Skip to content

Commit

Permalink
[feat]: ability to select custom datetime format
Browse files Browse the repository at this point in the history
  • Loading branch information
F0x1d committed Nov 3, 2023
1 parent 374b8f2 commit d762309
Show file tree
Hide file tree
Showing 41 changed files with 269 additions and 117 deletions.
4 changes: 2 additions & 2 deletions app/src/main/java/com/f0x1d/logfox/LogFoxApp.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ package com.f0x1d.logfox
import android.app.Application
import androidx.core.app.NotificationChannelCompat
import androidx.core.app.NotificationManagerCompat
import com.f0x1d.logfox.extensions.applyTheme
import com.f0x1d.logfox.extensions.notificationManagerCompat
import com.f0x1d.logfox.extensions.context.applyTheme
import com.f0x1d.logfox.extensions.context.notificationManagerCompat
import com.f0x1d.logfox.utils.preferences.AppPreferences
import com.google.android.material.color.DynamicColors
import dagger.hilt.android.HiltAndroidApp
Expand Down
11 changes: 0 additions & 11 deletions app/src/main/java/com/f0x1d/logfox/extensions/TimeExtensions.kt
Original file line number Diff line number Diff line change
@@ -1,16 +1,5 @@
package com.f0x1d.logfox.extensions

import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale

private val logDateFormat = SimpleDateFormat("dd.MM", Locale.US)
private val logTimeFormat = SimpleDateFormat("HH:mm:ss.SSS", Locale.US)
private val exportDateFormat = SimpleDateFormat("dd-MM_HH-mm-ss", Locale.US)
private val defaultDateFormat = SimpleDateFormat("dd.MM HH:mm:ss", Locale.US)

val Long.logsDateFormatted get() = logDateFormat.format(this)
val Long.logsTimeFormatted get() = logTimeFormat.format(this)
val Long.exportFormatted get() = exportDateFormat.format(this)
val Long.defaultFormatted get() = defaultDateFormat.format(this)
fun Long.toLocaleString() = Date(this).toLocaleString()
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,29 @@ package com.f0x1d.logfox.extensions
import android.content.Context
import android.net.Uri
import androidx.documentfile.provider.DocumentFile
import com.f0x1d.logfox.extensions.context.appPreferences
import com.f0x1d.logfox.extensions.logline.LogLine
import com.f0x1d.logfox.model.LogLine
import com.f0x1d.logfox.utils.preferences.AppPreferences
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOn

fun Uri?.readFileContentsAsFlow(context: Context, appPreferences: AppPreferences) = flow<List<LogLine>> {
fun Uri?.readFileContentsAsFlow(context: Context) = flow {
val uri = this@readFileContentsAsFlow

if (uri == null) {
emit(emptyList())
} else {
val logsDisplayLimit = appPreferences.logsDisplayLimit
val logsDisplayLimit = context.appPreferences.logsDisplayLimit

context.contentResolver.openInputStream(uri)?.use {
it.bufferedReader().useLines { lines ->
var id = -1L
val logLines = mutableListOf<LogLine>()

for (line in lines) {
val logLine = LogLine(id, line, context.packageManager) ?: LogLine(
val logLine = LogLine(id, line, context) ?: LogLine(
id = id,
content = line,
original = line
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.f0x1d.logfox.extensions.context

import android.content.Context
import com.f0x1d.logfox.utils.DateTimeFormatter
import com.f0x1d.logfox.utils.preferences.AppPreferences
import dagger.hilt.EntryPoint
import dagger.hilt.InstallIn
import dagger.hilt.android.EntryPointAccessors
import dagger.hilt.components.SingletonComponent
import io.github.inflationx.viewpump.ViewPump

val Context.appPreferences get() = extensionsEntryPoint.appPreferences()
val Context.dateTimeFormatter get() = extensionsEntryPoint.dateTimeFormatter()
val Context.viewPump get() = extensionsEntryPoint.viewPump()

private val Context.extensionsEntryPoint get() = EntryPointAccessors.fromApplication(
this,
ContextExtensionsEntryPoint::class.java
)

@EntryPoint
@InstallIn(SingletonComponent::class)
private interface ContextExtensionsEntryPoint {
fun appPreferences(): AppPreferences
fun dateTimeFormatter(): DateTimeFormatter
fun viewPump(): ViewPump
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.f0x1d.logfox.extensions
package com.f0x1d.logfox.extensions.context

import android.Manifest
import android.annotation.SuppressLint
Expand All @@ -16,6 +16,10 @@ import androidx.appcompat.app.AppCompatDelegate
import androidx.core.app.NotificationManagerCompat
import androidx.core.content.ContextCompat
import com.f0x1d.logfox.R
import com.f0x1d.logfox.extensions.asUri
import com.f0x1d.logfox.extensions.shouldRequestNotificationsPermission
import com.f0x1d.logfox.extensions.startForegroundServiceAvailable
import com.f0x1d.logfox.extensions.uiModeManagerAvailable
import com.f0x1d.logfox.repository.logging.LoggingRepository
import com.f0x1d.logfox.service.LoggingService
import com.f0x1d.logfox.utils.preferences.AppPreferences
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.f0x1d.logfox.extensions.logline

import android.content.pm.PackageManager
import android.content.Context
import androidx.collection.LruCache
import com.f0x1d.logfox.model.LogLevel
import com.f0x1d.logfox.model.LogLine
Expand All @@ -14,24 +14,26 @@ private val uidsCache = LruCache<String, String>(200)
fun LogLine(
id: Long,
line: String,
packageManager: PackageManager
context: Context
) = logRegex.find(line.trim())?.run {
val uid = groupValues[2].replace(" ", "")
val integerUid = uid.toIntOrNull() ?: UIDS.MAPPINGS[uid]

val packageName = uidsCache.get(uid) ?: integerUid?.let {
packageManager.getPackagesForUid(it)?.firstOrNull()?.also { packageName ->
val packageName = uidsCache[uid] ?: integerUid?.let {
context.packageManager.getPackagesForUid(it)?.firstOrNull()?.also { packageName ->
uidsCache.put(uid, packageName)
}
}

val time = groupValues[1].replace(" ", "").run {
indexOf(".").let {
substring(0, it).toLong() * 1000 + substring(it + 1).toLong()
}
}

LogLine(
id,
groupValues[1].replace(" ", "").run {
indexOf(".").let {
substring(0, it).toLong() * 1000 + substring(it + 1).toLong()
}
},
time,
uid,
groupValues[3].replace(" ", ""),
groupValues[4].replace(" ", ""),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ import com.f0x1d.logfox.LogFoxApp
import com.f0x1d.logfox.R
import com.f0x1d.logfox.database.entity.AppCrash
import com.f0x1d.logfox.extensions.*
import com.f0x1d.logfox.extensions.context.doIfPermitted
import com.f0x1d.logfox.extensions.context.notificationManager
import com.f0x1d.logfox.extensions.context.notificationManagerCompat
import com.f0x1d.logfox.receiver.CopyReceiver

@SuppressLint("MissingPermission")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import androidx.core.app.NotificationCompat
import com.f0x1d.logfox.LogFoxApp
import com.f0x1d.logfox.R
import com.f0x1d.logfox.extensions.*
import com.f0x1d.logfox.extensions.context.doIfPermitted
import com.f0x1d.logfox.extensions.context.notificationManagerCompat
import com.f0x1d.logfox.receiver.RecordingReceiver

private const val RECORDING_NOTIFICATIONS_TAG = "recording"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,6 @@ inline fun <reified T> Preference.observeAndUpdateSummary(appPreferences: AppPre

inline fun <reified T> Preference.observeAndUpdateSummary(appPreferences: AppPreferences, observer: LifecycleOwner, defValue: T, crossinline block: (T) -> Unit) {
appPreferences.asLiveData(key, defValue).observe(observer) {
block(it)
block(it ?: return@observe)
}
}
7 changes: 1 addition & 6 deletions app/src/main/java/com/f0x1d/logfox/model/LogLine.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ package com.f0x1d.logfox.model
import androidx.annotation.ColorRes
import androidx.annotation.Keep
import com.f0x1d.logfox.R
import com.f0x1d.logfox.extensions.logsDateFormatted
import com.f0x1d.logfox.extensions.logsTimeFormatted

data class LogLine(
val id: Long,
Expand All @@ -16,10 +14,7 @@ data class LogLine(
val level: LogLevel = LogLevel.INFO,
val tag: String = "",
val content: String,
val original: String,

val logsDateFormatted: String = dateAndTime.logsDateFormatted,
val logsTimeFormatted: String = dateAndTime.logsTimeFormatted
val original: String
)

@Keep
Expand Down
4 changes: 2 additions & 2 deletions app/src/main/java/com/f0x1d/logfox/receiver/BootReceiver.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import com.f0x1d.logfox.R
import com.f0x1d.logfox.extensions.startLoggingAndServiceIfCan
import com.f0x1d.logfox.extensions.toast
import com.f0x1d.logfox.extensions.context.startLoggingAndServiceIfCan
import com.f0x1d.logfox.extensions.context.toast
import com.f0x1d.logfox.repository.logging.LoggingRepository
import com.f0x1d.logfox.utils.preferences.AppPreferences
import com.f0x1d.logfox.utils.terminal.ShizukuTerminal
Expand Down
6 changes: 3 additions & 3 deletions app/src/main/java/com/f0x1d/logfox/receiver/CopyReceiver.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import com.f0x1d.logfox.R
import com.f0x1d.logfox.extensions.copyText
import com.f0x1d.logfox.extensions.notificationManagerCompat
import com.f0x1d.logfox.extensions.toast
import com.f0x1d.logfox.extensions.context.copyText
import com.f0x1d.logfox.extensions.context.notificationManagerCompat
import com.f0x1d.logfox.extensions.context.toast

class CopyReceiver: BroadcastReceiver() {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ package com.f0x1d.logfox.repository.logging
import android.content.Context
import android.content.SharedPreferences
import com.f0x1d.logfox.R
import com.f0x1d.logfox.extensions.context.toast
import com.f0x1d.logfox.extensions.logline.LogLine
import com.f0x1d.logfox.extensions.toast
import com.f0x1d.logfox.extensions.updateList
import com.f0x1d.logfox.model.LogLine
import com.f0x1d.logfox.repository.base.BaseRepository
Expand Down Expand Up @@ -164,7 +164,7 @@ class LoggingRepository @Inject constructor(
for (line in it) {
if (!isActive) break

val logLine = LogLine(idsCounter++, line, packageManager) ?: continue
val logLine = LogLine(idsCounter++, line, context) ?: continue
if (!droppedFirst) {
droppedFirst = true
continue
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ import com.f0x1d.logfox.R
import com.f0x1d.logfox.database.AppDatabase
import com.f0x1d.logfox.database.entity.LogRecording
import com.f0x1d.logfox.database.entity.UserFilter
import com.f0x1d.logfox.extensions.exportFormatted
import com.f0x1d.logfox.extensions.logline.filterAndSearch
import com.f0x1d.logfox.extensions.notifications.cancelRecordingNotification
import com.f0x1d.logfox.extensions.notifications.sendRecordingNotification
import com.f0x1d.logfox.extensions.notifications.sendRecordingPausedNotification
import com.f0x1d.logfox.model.LogLine
import com.f0x1d.logfox.repository.logging.base.LoggingHelperItemsRepository
import com.f0x1d.logfox.repository.logging.readers.base.LogsReader
import com.f0x1d.logfox.utils.DateTimeFormatter
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
Expand All @@ -32,7 +32,8 @@ import javax.inject.Singleton
@Singleton
class RecordingsRepository @Inject constructor(
@ApplicationContext private val context: Context,
private val database: AppDatabase
private val database: AppDatabase,
private val dateTimeFormatter: DateTimeFormatter
): LoggingHelperItemsRepository<LogRecording>() {

val recordingStateFlow = MutableStateFlow(RecordingState.IDLE)
Expand Down Expand Up @@ -92,7 +93,10 @@ class RecordingsRepository @Inject constructor(

recordingTime = System.currentTimeMillis()
fileMutex.withLock {
recordingFile = File(recordingDir, "${recordingTime.exportFormatted}.log").apply {
recordingFile = File(
recordingDir,
"${dateTimeFormatter.formatForExport(recordingTime)}.log"
).apply {
createNewFile()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import com.f0x1d.logfox.LogFoxApp
import com.f0x1d.logfox.R
import com.f0x1d.logfox.extensions.EXIT_APP_INTENT_ID
import com.f0x1d.logfox.extensions.STOP_LOGGING_SERVICE_INTENT_ID
import com.f0x1d.logfox.extensions.activityManager
import com.f0x1d.logfox.extensions.context.activityManager
import com.f0x1d.logfox.extensions.makeOpenAppPendingIntent
import com.f0x1d.logfox.extensions.makeServicePendingIntent
import com.f0x1d.logfox.extensions.notifications.applyPrimaryColorIfNeeded
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ import androidx.transition.TransitionManager
import com.f0x1d.logfox.NavGraphDirections
import com.f0x1d.logfox.R
import com.f0x1d.logfox.databinding.ActivityMainBinding
import com.f0x1d.logfox.extensions.context.hasNotificationsPermission
import com.f0x1d.logfox.extensions.context.isHorizontalOrientation
import com.f0x1d.logfox.extensions.contrastedNavBarAvailable
import com.f0x1d.logfox.extensions.gesturesAvailable
import com.f0x1d.logfox.extensions.hasNotificationsPermission
import com.f0x1d.logfox.extensions.isHorizontalOrientation
import com.f0x1d.logfox.ui.activity.base.BaseViewModelActivity
import com.f0x1d.logfox.utils.event.Event
import com.f0x1d.logfox.viewmodel.MainViewModel
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,11 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.WindowCompat
import androidx.viewbinding.ViewBinding
import com.f0x1d.logfox.R
import com.f0x1d.logfox.extensions.context.viewPump
import com.f0x1d.logfox.extensions.contrastedNavBarAvailable
import com.f0x1d.logfox.extensions.gesturesAvailable
import com.f0x1d.logfox.extensions.views.snackbar
import dagger.hilt.EntryPoint
import dagger.hilt.InstallIn
import dagger.hilt.android.EntryPointAccessors
import dagger.hilt.components.SingletonComponent
import dev.chrisbanes.insetter.applyInsetter
import io.github.inflationx.viewpump.ViewPump
import io.github.inflationx.viewpump.ViewPumpContextWrapper

abstract class BaseActivity<T : ViewBinding>: AppCompatActivity() {
Expand Down Expand Up @@ -56,21 +52,10 @@ abstract class BaseActivity<T : ViewBinding>: AppCompatActivity() {
}

override fun attachBaseContext(newBase: Context) {
val viewPump = EntryPointAccessors.fromApplication(
newBase,
BaseActivityEntryPoint::class.java
).viewPump()

super.attachBaseContext(ViewPumpContextWrapper.wrap(newBase, viewPump))
super.attachBaseContext(ViewPumpContextWrapper.wrap(newBase, newBase.viewPump))
}

protected fun snackbar(text: String) = binding.root.snackbar(text)

protected fun snackbar(id: Int) = snackbar(getString(id))
}

@EntryPoint
@InstallIn(SingletonComponent::class)
interface BaseActivityEntryPoint {
fun viewPump(): ViewPump
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ import androidx.navigation.fragment.findNavController
import com.f0x1d.logfox.NavGraphDirections
import com.f0x1d.logfox.databinding.SheetRecordingBinding
import com.f0x1d.logfox.extensions.asUri
import com.f0x1d.logfox.extensions.exportFormatted
import com.f0x1d.logfox.extensions.shareFileIntent
import com.f0x1d.logfox.extensions.context.shareFileIntent
import com.f0x1d.logfox.extensions.toLocaleString
import com.f0x1d.logfox.extensions.views.replaceAccessibilityDelegateClassNameWithButton
import com.f0x1d.logfox.ui.dialog.base.BaseViewModelBottomSheet
Expand Down Expand Up @@ -58,15 +57,15 @@ class RecordingBottomSheet: BaseViewModelBottomSheet<RecordingViewModel, SheetRe
}
binding.exportLayout.replaceAccessibilityDelegateClassNameWithButton()
binding.exportLayout.setOnClickListener {
logExportLauncher.launch("${logRecording.dateAndTime.exportFormatted}.log")
logExportLauncher.launch("${viewModel.dateTimeFormatter.formatForExport(logRecording.dateAndTime)}.log")
}
binding.shareLayout.replaceAccessibilityDelegateClassNameWithButton()
binding.shareLayout.setOnClickListener {
requireContext().shareFileIntent(File(logRecording.file))
}
binding.zipLayout.replaceAccessibilityDelegateClassNameWithButton()
binding.zipLayout.setOnClickListener {
zipLogLauncher.launch("${logRecording.dateAndTime.exportFormatted}.zip")
zipLogLauncher.launch("${viewModel.dateTimeFormatter.formatForExport(logRecording.dateAndTime)}.log")
}
}

Expand Down
10 changes: 5 additions & 5 deletions app/src/main/java/com/f0x1d/logfox/ui/fragment/LogsFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ import androidx.recyclerview.widget.RecyclerView
import com.f0x1d.logfox.R
import com.f0x1d.logfox.adapter.LogsAdapter
import com.f0x1d.logfox.databinding.FragmentLogsBinding
import com.f0x1d.logfox.extensions.copyText
import com.f0x1d.logfox.extensions.isHorizontalOrientation
import com.f0x1d.logfox.extensions.sendKillApp
import com.f0x1d.logfox.extensions.sendStopService
import com.f0x1d.logfox.extensions.startLoggingService
import com.f0x1d.logfox.extensions.context.copyText
import com.f0x1d.logfox.extensions.context.isHorizontalOrientation
import com.f0x1d.logfox.extensions.context.sendKillApp
import com.f0x1d.logfox.extensions.context.sendStopService
import com.f0x1d.logfox.extensions.context.startLoggingService
import com.f0x1d.logfox.extensions.views.widgets.invalidateNavigationButton
import com.f0x1d.logfox.extensions.views.widgets.setClickListenerOn
import com.f0x1d.logfox.extensions.views.widgets.setupBackButtonForNavController
Expand Down
Loading

0 comments on commit d762309

Please sign in to comment.