Skip to content

Commit

Permalink
feat(settings): add troubleshooting page and app preferences import/e…
Browse files Browse the repository at this point in the history
…xport tool (#672)
  • Loading branch information
Ashinch committed Mar 28, 2024
1 parent d749107 commit 826819a
Show file tree
Hide file tree
Showing 15 changed files with 343 additions and 35 deletions.
Expand Up @@ -94,12 +94,5 @@ class AccountService @Inject constructor(
rssService.get().cancelSync()
context.dataStore.put(DataStoreKeys.CurrentAccountId, account.id!!)
context.dataStore.put(DataStoreKeys.CurrentAccountType, account.type.id)

// Restart
// context.packageManager.getLaunchIntentForPackage(context.packageName)?.let {
// it.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
// context.startActivity(it)
// android.os.Process.killProcess(android.os.Process.myPid())
// }
}
}
Expand Up @@ -152,7 +152,7 @@ fun CrashReportPage(
val startIndex = msg.indexOf(hyperLinkText)
val endIndex = startIndex + hyperLinkText.length
addUrlAnnotation(
UrlAnnotation("https://github.com/Ashinch/ReadYou/issues/new?assignees=&labels=bug&projects=&template=bug_report.md&title="),
UrlAnnotation(stringResource(R.string.issue_tracer_url)),
start = startIndex,
end = endIndex
)
Expand Down Expand Up @@ -226,4 +226,4 @@ fun CrashReportPage(

}
}
}
}
6 changes: 6 additions & 0 deletions app/src/main/java/me/ash/reader/ui/ext/ContextExt.kt
Expand Up @@ -183,3 +183,9 @@ fun Context.getCustomTabsPackages(): List<String> {
return@mapNotNull null
}.toList()
}

fun Context.getPreferencesFile(): File =
File(filesDir.absolutePath + File.separator +
"datastore" + File.separator +
"settings.preferences_pb"
)
4 changes: 2 additions & 2 deletions app/src/main/java/me/ash/reader/ui/ext/DataStoreExt.kt
Expand Up @@ -27,9 +27,9 @@ val Context.skipVersionNumber: String
val Context.isFirstLaunch: Boolean
get() = this.dataStore.get(DataStoreKeys.IsFirstLaunch) ?: true
val Context.currentAccountId: Int
get() = this.dataStore.get(DataStoreKeys.CurrentAccountId)!!
get() = this.dataStore.get(DataStoreKeys.CurrentAccountId) ?: 1
val Context.currentAccountType: Int
get() = this.dataStore.get(DataStoreKeys.CurrentAccountType)!!
get() = this.dataStore.get(DataStoreKeys.CurrentAccountType) ?: 1

val Context.initialPage: Int
get() = this.dataStore.get(DataStoreKeys.InitialPage) ?: 0
Expand Down
6 changes: 5 additions & 1 deletion app/src/main/java/me/ash/reader/ui/ext/FileEXT.kt
Expand Up @@ -35,4 +35,8 @@ fun File.mkDir() {
val newF = File("${dirArray[0]}$pathTemp")
if (!newF.exists()) newF.mkdir()
}
}
}

fun ByteArray.isProbableProtobuf(): Boolean =
if (size < 2) false
else get(0) == 0x0a.toByte() && get(1) == 0x16.toByte()
2 changes: 1 addition & 1 deletion app/src/main/java/me/ash/reader/ui/ext/StringExt.kt
Expand Up @@ -8,7 +8,7 @@ import java.security.MessageDigest
object MimeType {

const val ANY = "*/*"
const val FONT = "font/ttf" // Not supported yet
const val FONT = "font/ttf"
const val OPML = "text/x-opml" // Not supported yet
const val JSON = "application/json"
}
Expand Down
6 changes: 6 additions & 0 deletions app/src/main/java/me/ash/reader/ui/page/common/HomeEntry.kt
Expand Up @@ -52,6 +52,7 @@ import me.ash.reader.ui.page.settings.interaction.InteractionPage
import me.ash.reader.ui.page.settings.languages.LanguagesPage
import me.ash.reader.ui.page.settings.tips.LicenseListPage
import me.ash.reader.ui.page.settings.tips.TipsAndSupportPage
import me.ash.reader.ui.page.settings.troubleshooting.TroubleshootingPage
import me.ash.reader.ui.page.startup.StartupPage
import me.ash.reader.ui.theme.AppTheme

Expand Down Expand Up @@ -237,6 +238,11 @@ fun HomeEntry(
LanguagesPage(navController = navController)
}

// Troubleshooting
forwardAndBackwardComposable(route = RouteName.TROUBLESHOOTING) {
TroubleshootingPage(navController = navController)
}

// Tips & Support
forwardAndBackwardComposable(route = RouteName.TIPS_AND_SUPPORT) {
TipsAndSupportPage(navController)
Expand Down
3 changes: 3 additions & 0 deletions app/src/main/java/me/ash/reader/ui/page/common/RouteName.kt
Expand Up @@ -36,6 +36,9 @@ object RouteName {
// Languages
const val LANGUAGES = "languages"

// Troubleshooting
const val TROUBLESHOOTING = "troubleshooting"

// Tips & Support
const val TIPS_AND_SUPPORT = "tips_and_support"
const val LICENSE_LIST = "license_list"
Expand Down
Expand Up @@ -35,8 +35,10 @@ import me.ash.reader.ui.component.RenameDialog
import me.ash.reader.ui.component.base.ClipboardTextField
import me.ash.reader.ui.component.base.RYDialog
import me.ash.reader.ui.component.base.TextFieldDialog
import me.ash.reader.ui.ext.MimeType
import me.ash.reader.ui.ext.collectAsStateValue
import me.ash.reader.ui.ext.roundClick
import me.ash.reader.ui.ext.showToast
import me.ash.reader.ui.page.home.feeds.FeedOptionView

@OptIn(
Expand All @@ -51,12 +53,12 @@ fun SubscribeDialog(
val focusManager = LocalFocusManager.current
val subscribeUiState = subscribeViewModel.subscribeUiState.collectAsStateValue()
val groupsState = subscribeUiState.groups.collectAsState(initial = emptyList())
val launcher = rememberLauncherForActivityResult(ActivityResultContracts.GetContent()) {
val launcher = rememberLauncherForActivityResult(ActivityResultContracts.OpenDocument()) {
it?.let { uri ->
context.contentResolver.openInputStream(uri)?.let { inputStream ->
subscribeViewModel.importFromInputStream(inputStream)
}
}
} ?: context.showToast("Cannot open Input Stream with content resolver")
} ?: context.showToast("Cannot get activity result with launcher")
}

LaunchedEffect(subscribeUiState.visible) {
Expand Down Expand Up @@ -180,7 +182,7 @@ fun SubscribeDialog(
TextButton(
onClick = {
focusManager.clearFocus()
launcher.launch("*/*")
launcher.launch(arrayOf(MimeType.ANY))
subscribeViewModel.hideDrawer()
}
) {
Expand Down
@@ -1,6 +1,5 @@
package me.ash.reader.ui.page.home.feeds.subscribe

import android.util.Log
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.rometools.rome.feed.synd.SyndFeed
Expand Down Expand Up @@ -59,12 +58,8 @@ class SubscribeViewModel @Inject constructor(

fun importFromInputStream(inputStream: InputStream) {
applicationScope.launch {
try {
opmlService.saveToDatabase(inputStream)
rssService.get().doSync()
} catch (e: Exception) {
Log.e("FeedsViewModel", "importFromInputStream: ", e)
}
opmlService.saveToDatabase(inputStream)
rssService.get().doSync()
}
}

Expand Down
27 changes: 24 additions & 3 deletions app/src/main/java/me/ash/reader/ui/page/settings/SettingsPage.kt
@@ -1,10 +1,21 @@
package me.ash.reader.ui.page.settings

import androidx.compose.foundation.layout.*
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.navigationBars
import androidx.compose.foundation.layout.windowInsetsBottomHeight
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.*
import androidx.compose.material.icons.automirrored.rounded.ArrowBack
import androidx.compose.material.icons.outlined.AccountCircle
import androidx.compose.material.icons.outlined.BugReport
import androidx.compose.material.icons.outlined.Language
import androidx.compose.material.icons.outlined.Lightbulb
import androidx.compose.material.icons.outlined.Palette
import androidx.compose.material.icons.outlined.TipsAndUpdates
import androidx.compose.material.icons.outlined.TouchApp
import androidx.compose.material.icons.rounded.Close
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
Expand All @@ -17,7 +28,6 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.zIndex
import androidx.core.os.LocaleListCompat
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.navigation.NavHostController
import me.ash.reader.R
Expand Down Expand Up @@ -134,6 +144,17 @@ fun SettingsPage(
}
}
}
item {
SelectableSettingGroupItem(
title = stringResource(R.string.troubleshooting),
desc = stringResource(R.string.troubleshooting_desc),
icon = Icons.Outlined.BugReport,
) {
navController.navigate(RouteName.TROUBLESHOOTING) {
launchSingleTop = true
}
}
}
item {
SelectableSettingGroupItem(
title = stringResource(R.string.tips_and_support),
Expand Down
Expand Up @@ -19,9 +19,9 @@ import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.rounded.ArrowBack
import androidx.compose.material.icons.outlined.DeleteSweep
import androidx.compose.material.icons.outlined.PersonOff
import androidx.compose.material.icons.automirrored.rounded.ArrowBack
import androidx.compose.material.icons.rounded.Close
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
Expand Down Expand Up @@ -61,6 +61,7 @@ import me.ash.reader.ui.component.base.Subtitle
import me.ash.reader.ui.component.base.TextFieldDialog
import me.ash.reader.ui.component.base.Tips
import me.ash.reader.ui.ext.DateFormat
import me.ash.reader.ui.ext.MimeType
import me.ash.reader.ui.ext.collectAsStateValue
import me.ash.reader.ui.ext.getCurrentVersion
import me.ash.reader.ui.ext.showToast
Expand Down Expand Up @@ -103,14 +104,14 @@ fun AccountDetailsPage(
}

val launcher = rememberLauncherForActivityResult(
ActivityResultContracts.CreateDocument("*/*")
ActivityResultContracts.CreateDocument(MimeType.ANY)
) { result ->
viewModel.exportAsOPML(selectedAccount!!.id!!) { string ->
result?.let { uri ->
context.contentResolver.openOutputStream(uri)?.use { outputStream ->
outputStream.write(string.toByteArray())
}
}
} ?: context.showToast("Cannot open Input Stream with content resolver")
} ?: context.showToast("Cannot get activity result with launcher")
}
}

Expand Down Expand Up @@ -483,7 +484,7 @@ fun AccountDetailsPage(
TextButton(
onClick = {
exportOPMLModeDialogVisible = false
launcherOPMLFile(context, launcher)
subscriptionOPMLFileLauncher(context, launcher)
}
) {
Text(stringResource(R.string.export))
Expand All @@ -502,11 +503,11 @@ fun AccountDetailsPage(
)
}

private fun launcherOPMLFile(
private fun subscriptionOPMLFileLauncher(
context: Context,
launcher: ManagedActivityResultLauncher<String, Uri?>,
) {
launcher.launch("Read-You-" +
"${context.getCurrentVersion()}-export-" +
"${context.getCurrentVersion()}-subscription-" +
"${Date().toString(DateFormat.YYYY_MM_DD_DASH_HH_MM_SS_DASH)}.opml")
}

0 comments on commit 826819a

Please sign in to comment.