Skip to content

Commit bde4beb

Browse files
committed
[feature|optimize|doc] Support configure text field style; optimize crash info screen; update README
1 parent b753587 commit bde4beb

35 files changed

+332
-92
lines changed

README.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,6 @@
3838
</div>
3939

4040

41-
42-
4341
## 💡 Features
4442

4543
1. **Subscribe to RSS**, Update RSS, **Read** RSS

app/src/main/java/com/skyd/anivu/ext/PreferenceExt.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import androidx.datastore.preferences.core.Preferences
44
import com.skyd.anivu.model.preference.IgnoreUpdateVersionPreference
55
import com.skyd.anivu.model.preference.Settings
66
import com.skyd.anivu.model.preference.appearance.DarkModePreference
7+
import com.skyd.anivu.model.preference.appearance.TextFieldStylePreference
78
import com.skyd.anivu.model.preference.appearance.ThemePreference
89
import com.skyd.anivu.model.preference.appearance.feed.FeedGroupExpandPreference
910
import com.skyd.anivu.model.preference.behavior.article.ArticleSwipeLeftActionPreference
@@ -16,6 +17,7 @@ fun Preferences.toSettings(): Settings {
1617
theme = ThemePreference.fromPreferences(this),
1718
darkMode = DarkModePreference.fromPreferences(this),
1819
feedGroupExpand = FeedGroupExpandPreference.fromPreferences(this),
20+
textFieldStyle = TextFieldStylePreference.fromPreferences(this),
1921

2022
// Update
2123
ignoreUpdateVersion = IgnoreUpdateVersionPreference.fromPreferences(this),

app/src/main/java/com/skyd/anivu/model/preference/Settings.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import androidx.compose.ui.platform.LocalContext
99
import com.skyd.anivu.ext.dataStore
1010
import com.skyd.anivu.ext.toSettings
1111
import com.skyd.anivu.model.preference.appearance.DarkModePreference
12+
import com.skyd.anivu.model.preference.appearance.TextFieldStylePreference
1213
import com.skyd.anivu.model.preference.appearance.ThemePreference
1314
import com.skyd.anivu.model.preference.appearance.feed.FeedGroupExpandPreference
1415
import com.skyd.anivu.model.preference.behavior.article.ArticleSwipeLeftActionPreference
@@ -20,6 +21,7 @@ import com.skyd.anivu.ui.local.LocalDarkMode
2021
import com.skyd.anivu.ui.local.LocalDeduplicateTitleInDesc
2122
import com.skyd.anivu.ui.local.LocalFeedGroupExpand
2223
import com.skyd.anivu.ui.local.LocalIgnoreUpdateVersion
24+
import com.skyd.anivu.ui.local.LocalTextFieldStyle
2325
import com.skyd.anivu.ui.local.LocalTheme
2426
import kotlinx.coroutines.Dispatchers
2527
import kotlinx.coroutines.flow.map
@@ -29,6 +31,7 @@ data class Settings(
2931
val theme: String = ThemePreference.default,
3032
val darkMode: Int = DarkModePreference.default,
3133
val feedGroupExpand: Boolean = FeedGroupExpandPreference.default,
34+
val textFieldStyle: String = TextFieldStylePreference.default,
3235
// Update
3336
val ignoreUpdateVersion: Long = IgnoreUpdateVersionPreference.default,
3437
// Behavior
@@ -50,6 +53,7 @@ fun SettingsProvider(
5053
LocalTheme provides settings.theme,
5154
LocalDarkMode provides settings.darkMode,
5255
LocalFeedGroupExpand provides settings.feedGroupExpand,
56+
LocalTextFieldStyle provides settings.textFieldStyle,
5357
// Update
5458
LocalIgnoreUpdateVersion provides settings.ignoreUpdateVersion,
5559
// Behavior
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package com.skyd.anivu.model.preference.appearance
2+
3+
import android.content.Context
4+
import androidx.datastore.preferences.core.Preferences
5+
import androidx.datastore.preferences.core.stringPreferencesKey
6+
import com.skyd.anivu.R
7+
import com.skyd.anivu.base.BasePreference
8+
import com.skyd.anivu.ext.dataStore
9+
import com.skyd.anivu.ext.getOrDefault
10+
import com.skyd.anivu.ext.put
11+
import com.skyd.anivu.ui.component.AniVuTextFieldStyle
12+
import kotlinx.coroutines.CoroutineScope
13+
import kotlinx.coroutines.Dispatchers
14+
import kotlinx.coroutines.launch
15+
16+
object TextFieldStylePreference : BasePreference<String> {
17+
private const val TEXT_FIELD_STYLE = "textFieldStyle"
18+
19+
val values = AniVuTextFieldStyle.entries.map { it.value }
20+
21+
override val default = AniVuTextFieldStyle.Normal.value
22+
23+
val key = stringPreferencesKey(TEXT_FIELD_STYLE)
24+
25+
fun put(context: Context, scope: CoroutineScope, value: String) {
26+
scope.launch(Dispatchers.IO) {
27+
context.dataStore.put(key, value)
28+
}
29+
}
30+
31+
override fun fromPreferences(preferences: Preferences): String = preferences[key] ?: default
32+
33+
fun toDisplayName(
34+
context: Context,
35+
value: String = context.dataStore.getOrDefault(this),
36+
): String = when (value) {
37+
AniVuTextFieldStyle.Normal.value -> context.getString(R.string.normal_text_field_style)
38+
AniVuTextFieldStyle.Outlined.value -> context.getString(R.string.outlined_text_field_style)
39+
else -> context.getString(R.string.unknown)
40+
}
41+
}
Lines changed: 128 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,63 @@
11
package com.skyd.anivu.ui.activity
22

3-
import android.content.ClipData
4-
import android.content.ClipboardManager
53
import android.content.Context
64
import android.content.Intent
75
import android.net.Uri
86
import android.os.Build
97
import android.os.Bundle
10-
import android.os.Process
11-
import android.widget.TextView
8+
import androidx.activity.ComponentActivity
9+
import androidx.activity.compose.setContent
1210
import androidx.activity.enableEdgeToEdge
13-
import androidx.appcompat.app.AppCompatActivity
14-
import com.google.android.material.dialog.MaterialAlertDialogBuilder
11+
import androidx.compose.foundation.layout.Arrangement
12+
import androidx.compose.foundation.layout.Column
13+
import androidx.compose.foundation.layout.Row
14+
import androidx.compose.foundation.layout.Spacer
15+
import androidx.compose.foundation.layout.fillMaxWidth
16+
import androidx.compose.foundation.layout.height
17+
import androidx.compose.foundation.layout.padding
18+
import androidx.compose.foundation.layout.size
19+
import androidx.compose.foundation.layout.width
20+
import androidx.compose.foundation.rememberScrollState
21+
import androidx.compose.foundation.text.selection.SelectionContainer
22+
import androidx.compose.foundation.verticalScroll
23+
import androidx.compose.material.icons.Icons
24+
import androidx.compose.material.icons.filled.BugReport
25+
import androidx.compose.material3.Button
26+
import androidx.compose.material3.Icon
27+
import androidx.compose.material3.MaterialTheme
28+
import androidx.compose.material3.Scaffold
29+
import androidx.compose.material3.SnackbarHost
30+
import androidx.compose.material3.SnackbarHostState
31+
import androidx.compose.material3.Text
32+
import androidx.compose.material3.TextButton
33+
import androidx.compose.material3.windowsizeclass.calculateWindowSizeClass
34+
import androidx.compose.runtime.Composable
35+
import androidx.compose.runtime.CompositionLocalProvider
36+
import androidx.compose.runtime.remember
37+
import androidx.compose.runtime.rememberCoroutineScope
38+
import androidx.compose.ui.Modifier
39+
import androidx.compose.ui.platform.ClipboardManager
40+
import androidx.compose.ui.platform.LocalClipboardManager
41+
import androidx.compose.ui.platform.LocalContext
42+
import androidx.compose.ui.res.stringResource
43+
import androidx.compose.ui.text.AnnotatedString
44+
import androidx.compose.ui.unit.dp
1545
import com.skyd.anivu.R
1646
import com.skyd.anivu.config.Const.GITHUB_NEW_ISSUE_URL
1747
import com.skyd.anivu.ext.getAppVersionCode
1848
import com.skyd.anivu.ext.getAppVersionName
1949
import com.skyd.anivu.ext.openBrowser
20-
import com.skyd.anivu.ext.sp
21-
import com.skyd.anivu.ui.component.showToast
22-
import kotlin.system.exitProcess
50+
import com.skyd.anivu.ext.showSnackbar
51+
import com.skyd.anivu.model.preference.SettingsProvider
52+
import com.skyd.anivu.ui.local.LocalDarkMode
53+
import com.skyd.anivu.ui.local.LocalWindowSizeClass
54+
import com.skyd.anivu.ui.theme.AniVuTheme
2355

2456

2557
/**
2658
* CrashActivity, do not extends BaseActivity
2759
*/
28-
class CrashActivity : AppCompatActivity() {
60+
class CrashActivity : ComponentActivity() {
2961
companion object {
3062
const val CRASH_INFO = "crashInfo"
3163

@@ -37,23 +69,11 @@ class CrashActivity : AppCompatActivity() {
3769
}
3870
}
3971

40-
private fun copyToClipboard(crashInfo: String?) {
41-
val cm = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
42-
cm.setPrimaryClip(ClipData.newPlainText("Exception trace stack", crashInfo))
43-
}
44-
45-
private fun exitApp() {
46-
finish()
47-
Process.killProcess(Process.myPid())
48-
exitProcess(1)
49-
}
50-
5172
override fun onCreate(savedInstanceState: Bundle?) {
5273
enableEdgeToEdge()
5374
super.onCreate(savedInstanceState)
5475

5576
val crashInfo = intent.getStringExtra(CRASH_INFO)
56-
5777
val message = buildString {
5878
append("VersionName: ").append(getAppVersionName()).append("\n")
5979
append("VersionCode: ").append(getAppVersionCode()).append("\n")
@@ -64,31 +84,94 @@ class CrashActivity : AppCompatActivity() {
6484
append("Crash Info: \n")
6585
append(crashInfo)
6686
}
67-
MaterialAlertDialogBuilder(this)
68-
.setIcon(R.drawable.ic_error_24)
69-
.setTitle(getString(R.string.crashed))
70-
.setMessage(message)
71-
.setCancelable(false)
72-
.setPositiveButton(getString(R.string.submit_an_issue_on_github)) { _, _ ->
73-
copyToClipboard(message)
74-
Uri.parse(GITHUB_NEW_ISSUE_URL).openBrowser(this)
75-
exitApp()
76-
}
77-
.setNegativeButton(getString(R.string.close)) { _, _ ->
78-
exitApp()
79-
}
80-
.setNeutralButton(getString(android.R.string.copy)) { _, _ ->
81-
copyToClipboard(message)
82-
getString(R.string.copied).showToast()
83-
exitApp()
87+
88+
setContent {
89+
CompositionLocalProvider(
90+
LocalWindowSizeClass provides calculateWindowSizeClass(this)
91+
) {
92+
SettingsProvider {
93+
AniVuTheme(darkTheme = LocalDarkMode.current) {
94+
CrashScreen(
95+
message = message,
96+
onReport = {
97+
Uri.parse(GITHUB_NEW_ISSUE_URL).openBrowser(this)
98+
}
99+
)
100+
}
101+
}
84102
}
85-
.show()
86-
.apply {
87-
window?.decorView?.findViewById<TextView>(android.R.id.message)?.apply {
88-
setTextIsSelectable(true)
89-
textSize = 3.5f.sp
103+
}
104+
}
105+
}
106+
107+
@Composable
108+
private fun CrashScreen(
109+
message: String,
110+
onReport: () -> Unit,
111+
) {
112+
val snackbarHostState = remember { SnackbarHostState() }
113+
val context = LocalContext.current
114+
val scope = rememberCoroutineScope()
115+
val clipboardManager = LocalClipboardManager.current
116+
117+
Scaffold(
118+
snackbarHost = { SnackbarHost(hostState = snackbarHostState) },
119+
) {
120+
Column(
121+
modifier = Modifier
122+
.verticalScroll(rememberScrollState())
123+
.padding(it)
124+
.padding(20.dp)
125+
) {
126+
Spacer(modifier = Modifier.height(40.dp))
127+
Icon(
128+
modifier = Modifier.size(40.dp),
129+
imageVector = Icons.Default.BugReport,
130+
contentDescription = null,
131+
)
132+
133+
Spacer(modifier = Modifier.height(30.dp))
134+
Text(
135+
text = stringResource(id = R.string.crashed),
136+
style = MaterialTheme.typography.headlineLarge,
137+
)
138+
139+
Spacer(modifier = Modifier.height(30.dp))
140+
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.End) {
141+
TextButton(onClick = {
142+
copyToClipboard(message, clipboardManager)
143+
snackbarHostState.showSnackbar(
144+
scope = scope,
145+
message = context.getString(R.string.copied),
146+
)
147+
}) {
148+
Text(text = stringResource(id = R.string.crash_screen_copy_crash_log))
149+
}
150+
151+
Spacer(modifier = Modifier.width(12.dp))
152+
153+
Button(onClick = {
154+
copyToClipboard(message, clipboardManager)
155+
onReport()
156+
}) {
157+
Text(text = stringResource(id = R.string.submit_an_issue_on_github))
90158
}
91159
}
92-
setFinishOnTouchOutside(false)
160+
161+
Spacer(modifier = Modifier.height(20.dp))
162+
Text(
163+
text = stringResource(R.string.crash_screen_crash_log),
164+
style = MaterialTheme.typography.titleLarge,
165+
)
166+
167+
Spacer(modifier = Modifier.height(10.dp))
168+
SelectionContainer {
169+
Text(text = message, style = MaterialTheme.typography.bodyMedium)
170+
}
171+
}
93172
}
173+
}
174+
175+
private fun copyToClipboard(text: String, clipboardManager: ClipboardManager) {
176+
clipboardManager.setText(AnnotatedString(text))
94177
}

0 commit comments

Comments
 (0)