Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update v2.0.4 #149

Merged
merged 4 commits into from
Nov 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ android {
defaultConfig {
applicationId = logFoxPackageName

versionCode = 63
versionName = "2.0.3"
versionCode = 64
versionName = "2.0.4"
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import com.f0x1d.logfox.arch.presentation.ui.base.SimpleFragmentLifecycleOwner
import com.f0x1d.logfox.arch.presentation.ui.snackbar
import dev.chrisbanes.insetter.applyInsetter

abstract class BaseFragment<T : ViewBinding>: Fragment(), SimpleFragmentLifecycleOwner {
abstract class BaseFragment<T : ViewBinding> : Fragment(), SimpleFragmentLifecycleOwner {

private var mutableBinding: T? = null
protected val binding: T get() = mutableBinding!!
Expand Down
2 changes: 2 additions & 0 deletions core/database/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ android {
dependencies {
implementation(projects.core.arch)

compileOnly(libs.androidx.compose.runtime)

implementation(libs.androidx.room)
implementation(libs.androidx.room.runtime)
ksp(libs.androidx.room.compiler)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.f0x1d.logfox.database.entity

import androidx.compose.runtime.Immutable
import androidx.room.ColumnInfo
import androidx.room.Dao
import androidx.room.Delete
Expand All @@ -12,6 +13,7 @@ import com.f0x1d.logfox.model.Identifiable
import kotlinx.coroutines.flow.Flow
import java.io.File

@Immutable
@Entity
data class LogRecording(
@ColumnInfo(name = "title") val title: String,
Expand Down
2 changes: 1 addition & 1 deletion core/navigation/src/main/res/navigation/recordings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<fragment
android:id="@+id/recordingsFragment"
android:name="com.f0x1d.logfox.feature.recordings.list.presentation.ui.fragment.RecordingsFragment"
android:name="com.f0x1d.logfox.feature.recordings.list.presentation.ui.RecordingsFragment"
android:label="RecordingsFragment" />
<action
android:id="@+id/action_recordingsFragment_to_recordingBottomSheet"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package com.f0x1d.logfox.ui.compose.component.button

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.ProvideTextStyle
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import com.f0x1d.logfox.strings.Strings
import com.f0x1d.logfox.ui.Icons
import com.f0x1d.logfox.ui.compose.preview.DayNightPreview
import com.f0x1d.logfox.ui.compose.theme.LogFoxTheme

@Composable
fun VerticalButton(
icon: @Composable () -> Unit,
text: @Composable () -> Unit,
onClick: () -> Unit,
modifier: Modifier = Modifier,
enabled: Boolean = true,
shape: Shape = CardDefaults.shape,
) {
Card(
modifier = modifier,
onClick = onClick,
enabled = enabled,
shape = shape,
) {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(20.dp),
verticalArrangement = Arrangement.spacedBy(6.dp),
horizontalAlignment = Alignment.CenterHorizontally,
) {
icon()

ProvideTextStyle(
value = MaterialTheme.typography.bodyLarge.copy(
fontWeight = FontWeight.Medium,
),
) {
text()
}
}
}
}

@DayNightPreview
@Composable
private fun Preview() = LogFoxTheme {
VerticalButton(
icon = {
Icon(
painter = painterResource(Icons.ic_menu_overflow),
contentDescription = null,
)
},
text = {
Text(text = stringResource(Strings.root))
},
onClick = { },
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package com.f0x1d.logfox.ui.compose.component.placeholder

import androidx.annotation.DrawableRes
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.ProvideTextStyle
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import com.f0x1d.logfox.strings.Strings
import com.f0x1d.logfox.ui.Icons
import com.f0x1d.logfox.ui.compose.preview.DayNightPreview
import com.f0x1d.logfox.ui.compose.theme.LogFoxTheme

@Composable
fun ListPlaceholder(
@DrawableRes iconResId: Int,
text: @Composable () -> Unit,
modifier: Modifier = Modifier,
) {
Column(
modifier = modifier.padding(horizontal = 10.dp),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(16.dp),
) {
Box(
modifier = Modifier
.size(120.dp)
.clip(CircleShape)
.background(MaterialTheme.colorScheme.surfaceContainerHighest)
.padding(26.dp),
) {
Icon(
modifier = Modifier.fillMaxSize(),
painter = painterResource(iconResId),
contentDescription = null,
)
}

ProvideTextStyle(MaterialTheme.typography.bodyLarge) {
text()
}
}
}

@DayNightPreview
@Composable
private fun Preview() = LogFoxTheme {
ListPlaceholder(
iconResId = Icons.ic_recording,
text = {
Text(text = stringResource(Strings.no_crashes))
},
)
}
37 changes: 37 additions & 0 deletions core/ui/src/main/kotlin/com/f0x1d/logfox/ui/view/EditTextExt.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.f0x1d.logfox.ui.view

import android.text.Editable
import android.text.TextWatcher
import android.widget.EditText

class ExtendedTextWatcher(
val editText: EditText,
var enabled: Boolean = true,
private val doAfterTextChanged: (e: Editable?) -> Unit,
) : TextWatcher {

init {
editText.addTextChangedListener(this)
}

override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) = Unit

override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) = Unit

override fun afterTextChanged(e: Editable?) {
if (enabled) {
doAfterTextChanged(e)
}
}

fun setText(text: String?) {
enabled = false
editText.setText(text)
enabled = true
}
}

fun EditText.applyExtendedTextWatcher(doAfterTextChanged: (e: Editable?) -> Unit): ExtendedTextWatcher = ExtendedTextWatcher(
editText = this,
doAfterTextChanged = doAfterTextChanged,
)
9 changes: 9 additions & 0 deletions core/ui/src/main/res/drawable/ic_menu_overflow.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
android:width="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#000000"
android:pathData="M12,16A2,2 0 0,1 14,18A2,2 0 0,1 12,20A2,2 0 0,1 10,18A2,2 0 0,1 12,16M12,10A2,2 0 0,1 14,12A2,2 0 0,1 12,14A2,2 0 0,1 10,12A2,2 0 0,1 12,10M12,4A2,2 0 0,1 14,6A2,2 0 0,1 12,8A2,2 0 0,1 10,6A2,2 0 0,1 12,4Z" />
</vector>
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import com.f0x1d.logfox.model.logline.LogLine

data class LogsState(
val logs: List<LogLine> = emptyList(),
val logsChanged: Boolean = true,
val paused: Boolean = false,
val query: String? = null,
val filters: List<UserFilter> = emptyList(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ class LogsViewModel @Inject constructor(
@IODispatcher private val ioDispatcher: CoroutineDispatcher,
dateTimeFormatter: DateTimeFormatter,
application: Application,
): BaseViewModel<LogsState, LogsAction>(
) : BaseViewModel<LogsState, LogsAction>(
initialStateProvider = { LogsState() },
application = application,
), DateTimeFormatter by dateTimeFormatter {
Expand All @@ -58,9 +58,12 @@ class LogsViewModel @Inject constructor(
val logsExpanded get() = appPreferences.logsExpanded
val logsFormat get() = appPreferences.showLogValues

val selectedItemsContent get() = currentState.selectedItems.joinToString("\n") {
originalOf(it)
}
val selectedItemsContent get() = currentState
.selectedItems
.sortedBy { it.dateAndTime }
.joinToString("\n") {
originalOf(it)
}

init {
load()
Expand All @@ -71,7 +74,11 @@ class LogsViewModel @Inject constructor(
state
.map { it.selectedItems }
.distinctUntilChanged()
.onEach { selectedLogLinesDataSource.updateSelectedLines(it.toList()) }
.onEach { lines ->
selectedLogLinesDataSource.updateSelectedLines(
selectedLines = lines.sortedBy { it.dateAndTime },
)
}
.launchIn(this)

combine(
Expand Down Expand Up @@ -119,7 +126,7 @@ class LogsViewModel @Inject constructor(
logs = data.logs.filterAndSearch(
filters = data.filters,
query = data.query,
)
),
)
}.flowOn(
defaultDispatcher,
Expand All @@ -129,6 +136,7 @@ class LogsViewModel @Inject constructor(
logs = data.logs,
query = data.query,
filters = data.filters,
logsChanged = true,
)
}
}.launchIn(this)
Expand All @@ -143,7 +151,8 @@ class LogsViewModel @Inject constructor(
) else remove(
logLine
)
}
},
logsChanged = false,
)
}

Expand All @@ -154,6 +163,7 @@ class LogsViewModel @Inject constructor(
} else {
logs.toSet()
},
logsChanged = false,
)
}

Expand All @@ -171,9 +181,9 @@ class LogsViewModel @Inject constructor(
}
}

fun switchState() = reduce { copy(paused = paused.not()) }
fun pause() = reduce { copy(paused = true) }
fun resume() = reduce { copy(paused = false) }
fun switchState() = reduce { copy(paused = paused.not(), logsChanged = false) }
fun pause() = reduce { copy(paused = true, logsChanged = false) }
fun resume() = reduce { copy(paused = false, logsChanged = false) }

fun originalOf(logLine: LogLine): String = appPreferences.originalOf(
logLine = logLine,
Expand All @@ -182,7 +192,10 @@ class LogsViewModel @Inject constructor(
)

fun clearSelection() = reduce {
copy(selectedItems = emptySet())
copy(
selectedItems = emptySet(),
logsChanged = false,
)
}

private data class LogsData(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,9 @@ class LogsFragment : BaseFragment<FragmentLogsBinding>() {
processSelectedItems(selectedItems = state.selectedItems)
processPaused(paused = state.paused)

updateLogsList(items = state.logs)
if (state.logsChanged) {
updateLogsList(items = state.logs)
}
}

requireActivity().onBackPressedDispatcher.apply {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class RecordingDetailsViewModel @Inject constructor(
application = application,
), DateTimeFormatter by dateTimeFormatter {
var currentTitle: String? = null
private set

private val titleUpdateMutex = Mutex()

Expand Down Expand Up @@ -83,6 +84,8 @@ class RecordingDetailsViewModel @Inject constructor(

fun updateTitle(title: String) = launchCatching {
titleUpdateMutex.withLock {
currentTitle = title

currentState.recording?.let {
recordingsRepository.updateTitle(it, title)
}
Expand Down
Loading
Loading