mirror of
https://github.com/fcitx5-android/fcitx5-android.git
synced 2026-08-02 04:44:35 +08:00
Remove misused kotlinx.coroutines.NonCancellable
This commit is contained in:
parent
306fdaef77
commit
e605129e68
@ -13,7 +13,6 @@ import android.view.inputmethod.InputMethodManager
|
||||
import android.widget.EditText
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.MainScope
|
||||
import kotlinx.coroutines.NonCancellable
|
||||
import kotlinx.coroutines.cancel
|
||||
import kotlinx.coroutines.launch
|
||||
import org.fcitx.fcitx5.android.data.clipboard.ClipboardManager
|
||||
@ -47,7 +46,7 @@ class ClipboardEditActivity : Activity() {
|
||||
|
||||
private fun finishEditing(copy: Boolean = false) {
|
||||
val str = editText.str
|
||||
scope.launch(NonCancellable) {
|
||||
scope.launch {
|
||||
ClipboardManager.updateText(entryId, str)
|
||||
if (copy) {
|
||||
clipboardManager.setPrimaryClip(ClipData.newPlainText("", str))
|
||||
|
||||
@ -42,13 +42,22 @@ class DeveloperFragment : PaddingPreferenceFragment() {
|
||||
return@registerForActivityResult
|
||||
}
|
||||
val ctx = requireContext()
|
||||
lifecycleScope.launch(NonCancellable + Dispatchers.IO) {
|
||||
runCatching {
|
||||
ctx.contentResolver.openOutputStream(uri)!!.use { o ->
|
||||
hprofFile.inputStream().use { i -> i.copyTo(o) }
|
||||
lifecycleScope.launch {
|
||||
try {
|
||||
withContext(Dispatchers.IO) {
|
||||
ctx.contentResolver.openOutputStream(uri)!!.use { o ->
|
||||
hprofFile.inputStream().use { i -> i.copyTo(o) }
|
||||
}
|
||||
}
|
||||
}.let { ctx.toast(it) }
|
||||
hprofFile.delete()
|
||||
} catch (e: Exception) {
|
||||
ctx.toast(e)
|
||||
} finally {
|
||||
withContext(NonCancellable) {
|
||||
withContext(Dispatchers.IO) {
|
||||
hprofFile.delete()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -87,12 +96,8 @@ class DeveloperFragment : PaddingPreferenceFragment() {
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
.setPositiveButton(android.R.string.ok) { _, _ ->
|
||||
lifecycleScope.launch {
|
||||
withContext(NonCancellable + Dispatchers.IO) {
|
||||
FcitxDaemon.restartFcitx()
|
||||
withContext(Dispatchers.Main) {
|
||||
context.toast(R.string.done)
|
||||
}
|
||||
}
|
||||
FcitxDaemon.restartFcitx()
|
||||
context.toast(R.string.done)
|
||||
}
|
||||
}
|
||||
.show()
|
||||
@ -102,11 +107,11 @@ class DeveloperFragment : PaddingPreferenceFragment() {
|
||||
.setTitle(R.string.delete_and_sync_data)
|
||||
.setMessage(R.string.delete_and_sync_data_message)
|
||||
.setPositiveButton(android.R.string.ok) { _, _ ->
|
||||
lifecycleScope.launch(NonCancellable + Dispatchers.IO) {
|
||||
DataManager.deleteAndSync()
|
||||
withContext(Dispatchers.Main) {
|
||||
context.toast(R.string.synced)
|
||||
lifecycleScope.launch {
|
||||
withContext(Dispatchers.IO) {
|
||||
DataManager.deleteAndSync()
|
||||
}
|
||||
context.toast(R.string.synced)
|
||||
}
|
||||
}
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
@ -117,11 +122,11 @@ class DeveloperFragment : PaddingPreferenceFragment() {
|
||||
.setTitle(R.string.clear_clb_db)
|
||||
.setMessage(R.string.clear_clp_db_confirm)
|
||||
.setPositiveButton(android.R.string.ok) { _, _ ->
|
||||
lifecycleScope.launch(NonCancellable + Dispatchers.IO) {
|
||||
ClipboardManager.nukeTable()
|
||||
withContext(Dispatchers.Main) {
|
||||
context.toast(R.string.done)
|
||||
lifecycleScope.launch {
|
||||
withContext(Dispatchers.IO) {
|
||||
ClipboardManager.nukeTable()
|
||||
}
|
||||
context.toast(R.string.done)
|
||||
}
|
||||
}
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
|
||||
@ -17,8 +17,8 @@ import androidx.core.view.WindowInsetsCompat
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.NonCancellable
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.fcitx.fcitx5.android.FcitxApplication
|
||||
import org.fcitx.fcitx5.android.R
|
||||
import org.fcitx.fcitx5.android.databinding.ActivityLogBinding
|
||||
@ -41,12 +41,14 @@ class LogActivity : AppCompatActivity() {
|
||||
private fun registerLauncher() {
|
||||
launcher = registerForActivityResult(CreateDocument("text/plain")) { uri ->
|
||||
if (uri == null) return@registerForActivityResult
|
||||
lifecycleScope.launch(NonCancellable + Dispatchers.IO) {
|
||||
lifecycleScope.launch {
|
||||
runCatching {
|
||||
contentResolver.openOutputStream(uri)!!.use { stream ->
|
||||
stream.bufferedWriter().use { writer ->
|
||||
writer.write(DeviceInfo.get(this@LogActivity))
|
||||
writer.write(logView.currentLog)
|
||||
withContext(Dispatchers.IO) {
|
||||
contentResolver.openOutputStream(uri)!!.use { stream ->
|
||||
stream.bufferedWriter().use { writer ->
|
||||
writer.write(DeviceInfo.get(this@LogActivity))
|
||||
writer.write(logView.currentLog)
|
||||
}
|
||||
}
|
||||
}
|
||||
}.let { toast(it) }
|
||||
|
||||
@ -16,8 +16,8 @@ import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.NonCancellable
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.fcitx.fcitx5.android.R
|
||||
import org.fcitx.fcitx5.android.core.reloadPinyinCustomPhrase
|
||||
import org.fcitx.fcitx5.android.data.pinyin.CustomPhraseManager
|
||||
@ -193,8 +193,10 @@ class PinyinCustomPhraseFragment : Fragment(), OnItemChangedListener<PinyinCusto
|
||||
private fun saveConfig() {
|
||||
if (!dustman.dirty) return
|
||||
resetDustman()
|
||||
lifecycleScope.launch(NonCancellable + Dispatchers.IO) {
|
||||
CustomPhraseManager.save(ui.entries.toTypedArray())
|
||||
lifecycleScope.launch {
|
||||
withContext(Dispatchers.IO) {
|
||||
CustomPhraseManager.save(ui.entries.toTypedArray())
|
||||
}
|
||||
viewModel.fcitx.runOnReady {
|
||||
reloadPinyinCustomPhrase()
|
||||
}
|
||||
|
||||
@ -19,7 +19,6 @@ import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.NonCancellable
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.fcitx.fcitx5.android.R
|
||||
@ -132,7 +131,7 @@ class PinyinDictionaryFragment : Fragment(), OnItemChangedListener<PinyinDiction
|
||||
val ctx = requireContext()
|
||||
val cr = ctx.contentResolver
|
||||
val nm = ctx.notificationManager
|
||||
lifecycleScope.launch(NonCancellable + Dispatchers.IO) {
|
||||
lifecycleScope.launch {
|
||||
val id = IMPORT_ID++
|
||||
val fileName = cr.queryFileName(uri) ?: return@launch
|
||||
if (PinyinDictionary.Type.fromFileName(fileName) == null) {
|
||||
@ -153,12 +152,11 @@ class PinyinDictionaryFragment : Fragment(), OnItemChangedListener<PinyinDiction
|
||||
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
||||
.build().let { nm.notify(id, it) }
|
||||
try {
|
||||
val inputStream = cr.openInputStream(uri)!!
|
||||
val imported = PinyinDictManager.importFromInputStream(inputStream, fileName)
|
||||
.getOrThrow()
|
||||
withContext(Dispatchers.Main) {
|
||||
ui.addItem(item = imported)
|
||||
val imported = withContext(Dispatchers.IO) {
|
||||
val inputStream = cr.openInputStream(uri)!!
|
||||
PinyinDictManager.importFromInputStream(inputStream, fileName).getOrThrow()
|
||||
}
|
||||
ui.addItem(item = imported)
|
||||
} catch (e: Exception) {
|
||||
ctx.importErrorDialog(e)
|
||||
}
|
||||
@ -173,7 +171,7 @@ class PinyinDictionaryFragment : Fragment(), OnItemChangedListener<PinyinDiction
|
||||
// right before the Fragment detached from Activity, and at the time reload completes,
|
||||
// Fragment is no longer attached to a Context, thus unable to cancel the notification.
|
||||
val nm = requireContext().notificationManager
|
||||
lifecycleScope.launch(NonCancellable + Dispatchers.IO) {
|
||||
lifecycleScope.launch {
|
||||
if (busy.compareAndSet(false, true)) {
|
||||
val id = RELOAD_ID++
|
||||
NotificationCompat.Builder(requireContext(), CHANNEL_ID)
|
||||
|
||||
@ -10,7 +10,6 @@ import android.view.View
|
||||
import android.view.inputmethod.EditorInfo
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.NonCancellable
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.fcitx.fcitx5.android.R
|
||||
@ -147,14 +146,15 @@ class QuickPhraseEditFragment : ProgressFragment(), OnItemChangedListener<QuickP
|
||||
private fun saveConfig() {
|
||||
if (!dustman.dirty) return
|
||||
resetDustman()
|
||||
lifecycleScope.launch(NonCancellable + Dispatchers.IO) {
|
||||
quickPhrase.saveData(QuickPhraseData(ui.entries))
|
||||
launch(Dispatchers.Main) {
|
||||
// tell parent that we need to reload
|
||||
parentFragmentManager.setFragmentResult(
|
||||
RESULT,
|
||||
Bundle().apply { putParcelable(RESULT, quickPhrase) })
|
||||
lifecycleScope.launch {
|
||||
withContext(Dispatchers.IO) {
|
||||
quickPhrase.saveData(QuickPhraseData(ui.entries))
|
||||
}
|
||||
// tell parent that we need to reload
|
||||
parentFragmentManager.setFragmentResult(
|
||||
RESULT,
|
||||
Bundle().apply { putParcelable(RESULT, quickPhrase) }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -21,7 +21,6 @@ import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.NonCancellable
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.fcitx.fcitx5.android.R
|
||||
@ -222,7 +221,7 @@ class QuickPhraseListFragment : Fragment(), OnItemChangedListener<QuickPhrase> {
|
||||
val ctx = requireContext()
|
||||
val cr = ctx.contentResolver
|
||||
val nm = ctx.notificationManager
|
||||
lifecycleScope.launch(NonCancellable + Dispatchers.IO) {
|
||||
lifecycleScope.launch {
|
||||
val id = IMPORT_ID++
|
||||
val fileName = cr.queryFileName(uri) ?: return@launch
|
||||
val extName = fileName.substringAfterLast('.')
|
||||
@ -244,12 +243,11 @@ class QuickPhraseListFragment : Fragment(), OnItemChangedListener<QuickPhrase> {
|
||||
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
||||
.build().let { nm.notify(id, it) }
|
||||
try {
|
||||
val inputStream = cr.openInputStream(uri)!!
|
||||
val imported = QuickPhraseManager.importFromInputStream(inputStream, fileName)
|
||||
.getOrThrow()
|
||||
withContext(Dispatchers.Main) {
|
||||
ui.addItem(item = imported)
|
||||
val imported = withContext(Dispatchers.IO) {
|
||||
val inputStream = cr.openInputStream(uri)!!
|
||||
QuickPhraseManager.importFromInputStream(inputStream, fileName).getOrThrow()
|
||||
}
|
||||
ui.addItem(item = imported)
|
||||
} catch (e: Exception) {
|
||||
ctx.importErrorDialog(e)
|
||||
}
|
||||
@ -263,7 +261,7 @@ class QuickPhraseListFragment : Fragment(), OnItemChangedListener<QuickPhrase> {
|
||||
// save the reference to NotificationManager, in case we need to cancel notification
|
||||
// after Fragment detached
|
||||
val nm = requireContext().notificationManager
|
||||
lifecycleScope.launch(NonCancellable + Dispatchers.IO) {
|
||||
lifecycleScope.launch {
|
||||
if (busy.compareAndSet(false, true)) {
|
||||
val id = RELOAD_ID++
|
||||
NotificationCompat.Builder(requireContext(), CHANNEL_ID)
|
||||
|
||||
@ -20,7 +20,6 @@ import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.NonCancellable
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.fcitx.fcitx5.android.R
|
||||
@ -211,7 +210,7 @@ class TableInputMethodFragment : Fragment(), OnItemChangedListener<TableBasedInp
|
||||
val ctx = requireContext()
|
||||
val cr = ctx.contentResolver
|
||||
val nm = ctx.notificationManager
|
||||
lifecycleScope.launch(NonCancellable + Dispatchers.IO) {
|
||||
lifecycleScope.launch {
|
||||
val importId = IMPORT_ID++
|
||||
val fileName = cr.queryFileName(uri) ?: return@launch
|
||||
if (!fileName.endsWith(".zip")) {
|
||||
@ -227,11 +226,11 @@ class TableInputMethodFragment : Fragment(), OnItemChangedListener<TableBasedInp
|
||||
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
||||
.build().let { nm.notify(importId, it) }
|
||||
try {
|
||||
val inputStream = cr.openInputStream(uri)!!
|
||||
val imported = TableManager.importFromZip(inputStream).getOrThrow()
|
||||
withContext(Dispatchers.Main) {
|
||||
ui.addItem(item = imported)
|
||||
val imported = withContext(Dispatchers.IO) {
|
||||
val inputStream = cr.openInputStream(uri)!!
|
||||
TableManager.importFromZip(inputStream).getOrThrow()
|
||||
}
|
||||
ui.addItem(item = imported)
|
||||
} catch (e: Exception) {
|
||||
ctx.importErrorDialog(e)
|
||||
}
|
||||
@ -279,7 +278,7 @@ class TableInputMethodFragment : Fragment(), OnItemChangedListener<TableBasedInp
|
||||
}
|
||||
return
|
||||
}
|
||||
lifecycleScope.launch(NonCancellable + Dispatchers.IO) {
|
||||
lifecycleScope.launch {
|
||||
val importId = IMPORT_ID++
|
||||
val confName = cr.queryFileName(confUri) ?: return@launch
|
||||
val dictName = cr.queryFileName(dictUri) ?: return@launch
|
||||
@ -292,25 +291,21 @@ class TableInputMethodFragment : Fragment(), OnItemChangedListener<TableBasedInp
|
||||
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
||||
.build().let { nm.notify(importId, it) }
|
||||
try {
|
||||
val confStream = cr.openInputStream(confUri)!!
|
||||
val dictStream = cr.openInputStream(dictUri)!!
|
||||
withContext(Dispatchers.Main) {
|
||||
updateFilesSelectionDialogButton(importing = true)
|
||||
}
|
||||
val imported =
|
||||
updateFilesSelectionDialogButton(importing = true)
|
||||
val imported = withContext(Dispatchers.IO) {
|
||||
val confStream = cr.openInputStream(confUri)!!
|
||||
val dictStream = cr.openInputStream(dictUri)!!
|
||||
TableManager.importFromConfAndDict(confName, confStream, dictName, dictStream)
|
||||
.getOrThrow()
|
||||
withContext(Dispatchers.Main) {
|
||||
dismissFilesSelectionDialog()
|
||||
ui.addItem(item = imported)
|
||||
}
|
||||
dismissFilesSelectionDialog()
|
||||
ui.addItem(item = imported)
|
||||
} catch (e: Exception) {
|
||||
ctx.importErrorDialog(e)
|
||||
}
|
||||
nm.cancel(importId)
|
||||
withContext(Dispatchers.Main) {
|
||||
} finally {
|
||||
updateFilesSelectionDialogButton(importing = false)
|
||||
}
|
||||
nm.cancel(importId)
|
||||
}
|
||||
}
|
||||
|
||||
@ -320,7 +315,7 @@ class TableInputMethodFragment : Fragment(), OnItemChangedListener<TableBasedInp
|
||||
val nm = ctx.notificationManager
|
||||
val im = tableToReplace ?: return
|
||||
tableToReplace = null
|
||||
lifecycleScope.launch(NonCancellable + Dispatchers.IO) {
|
||||
lifecycleScope.launch {
|
||||
val importId = IMPORT_ID++
|
||||
val dictName = cr.queryFileName(uri) ?: return@launch
|
||||
if (Dictionary.Type.fromFileName(dictName) == null) {
|
||||
@ -336,11 +331,12 @@ class TableInputMethodFragment : Fragment(), OnItemChangedListener<TableBasedInp
|
||||
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
||||
.build().let { nm.notify(importId, it) }
|
||||
try {
|
||||
val dictStream = cr.openInputStream(uri)!!
|
||||
im.table = TableManager.replaceTableDict(im, dictName, dictStream).getOrThrow()
|
||||
withContext(Dispatchers.Main) {
|
||||
ui.updateItem(ui.indexItem(im), im)
|
||||
val imported = withContext(Dispatchers.IO) {
|
||||
val dictStream = cr.openInputStream(uri)!!
|
||||
TableManager.replaceTableDict(im, dictName, dictStream).getOrThrow()
|
||||
}
|
||||
im.table = imported
|
||||
ui.updateItem(ui.indexItem(im), im)
|
||||
dustman.forceDirty()
|
||||
} catch (e: Exception) {
|
||||
ctx.importErrorDialog(e)
|
||||
|
||||
@ -13,7 +13,6 @@ import androidx.fragment.app.activityViewModels
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.preference.PreferenceScreen
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.NonCancellable
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
@ -52,31 +51,30 @@ class AdvancedSettingsFragment : ManagedPreferenceFragment(AppPrefs.getInstance(
|
||||
val ctx = requireContext()
|
||||
val cr = ctx.contentResolver
|
||||
lifecycleScope.withLoadingDialog(ctx) {
|
||||
withContext(NonCancellable + Dispatchers.IO) {
|
||||
val name = cr.queryFileName(uri) ?: return@withContext
|
||||
if (!name.endsWith(".zip")) {
|
||||
ctx.importErrorDialog(R.string.exception_user_data_filename, name)
|
||||
return@withContext
|
||||
}
|
||||
try {
|
||||
// stop fcitx before overwriting files
|
||||
FcitxDaemon.stopFcitx()
|
||||
val name = cr.queryFileName(uri) ?: return@withLoadingDialog
|
||||
if (!name.endsWith(".zip")) {
|
||||
ctx.importErrorDialog(R.string.exception_user_data_filename, name)
|
||||
return@withLoadingDialog
|
||||
}
|
||||
try {
|
||||
// stop fcitx before overwriting files
|
||||
FcitxDaemon.stopFcitx()
|
||||
val metadata = withContext(Dispatchers.IO) {
|
||||
val inputStream = cr.openInputStream(uri)!!
|
||||
val metadata = UserDataManager.import(inputStream).getOrThrow()
|
||||
lifecycleScope.launch(NonCancellable + Dispatchers.Main) {
|
||||
delay(400L)
|
||||
AppUtil.exit()
|
||||
}
|
||||
withContext(Dispatchers.Main) {
|
||||
AppUtil.showRestartNotification(ctx)
|
||||
val exportTime = formatDateTime(metadata.exportTime)
|
||||
ctx.toast(getString(R.string.user_data_imported, exportTime))
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
// re-start fcitx in case importing failed
|
||||
FcitxDaemon.startFcitx()
|
||||
ctx.importErrorDialog(e)
|
||||
UserDataManager.import(inputStream).getOrThrow()
|
||||
}
|
||||
AppUtil.showRestartNotification(ctx)
|
||||
val exportTime = formatDateTime(metadata.exportTime)
|
||||
ctx.toast(getString(R.string.user_data_imported, exportTime))
|
||||
// delay exit to ensure Notification and Toast has been created
|
||||
lifecycleScope.launch {
|
||||
delay(400L)
|
||||
AppUtil.exit()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
// restart fcitx in case importing failed
|
||||
FcitxDaemon.startFcitx()
|
||||
ctx.importErrorDialog(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -84,17 +82,15 @@ class AdvancedSettingsFragment : ManagedPreferenceFragment(AppPrefs.getInstance(
|
||||
registerForActivityResult(ActivityResultContracts.CreateDocument("application/zip")) { uri ->
|
||||
if (uri == null) return@registerForActivityResult
|
||||
val ctx = requireContext()
|
||||
lifecycleScope.withLoadingDialog(requireContext()) {
|
||||
withContext(NonCancellable + Dispatchers.IO) {
|
||||
try {
|
||||
lifecycleScope.withLoadingDialog(ctx) {
|
||||
try {
|
||||
withContext(Dispatchers.IO) {
|
||||
val outputStream = ctx.contentResolver.openOutputStream(uri)!!
|
||||
UserDataManager.export(outputStream, exportTimestamp).getOrThrow()
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
withContext(Dispatchers.Main) {
|
||||
ctx.toast(e)
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
ctx.toast(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -120,11 +116,9 @@ class AdvancedSettingsFragment : ManagedPreferenceFragment(AppPrefs.getInstance(
|
||||
}) else null
|
||||
)
|
||||
screen.addPreference(R.string.export_user_data) {
|
||||
lifecycleScope.launch {
|
||||
lifecycleScope.withLoadingDialog(ctx) {
|
||||
viewModel.fcitx.runOnReady {
|
||||
save()
|
||||
}
|
||||
lifecycleScope.withLoadingDialog(ctx) {
|
||||
viewModel.fcitx.runOnReady {
|
||||
save()
|
||||
}
|
||||
exportTimestamp = System.currentTimeMillis()
|
||||
exportLauncher.launch("fcitx5-android_${iso8601UTCDateTime(exportTimestamp)}.zip")
|
||||
|
||||
@ -15,7 +15,6 @@ import androidx.appcompat.app.AlertDialog
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.NonCancellable
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.fcitx.fcitx5.android.R
|
||||
@ -83,31 +82,28 @@ class ThemeListFragment : Fragment() {
|
||||
val ctx = requireContext()
|
||||
val cr = ctx.contentResolver
|
||||
lifecycleScope.withLoadingDialog(ctx) {
|
||||
withContext(NonCancellable + Dispatchers.IO) {
|
||||
val name = cr.queryFileName(uri) ?: return@withContext
|
||||
val ext = name.substringAfterLast('.')
|
||||
if (ext != "zip") {
|
||||
ctx.importErrorDialog(R.string.exception_theme_filename, ext)
|
||||
return@withContext
|
||||
}
|
||||
try {
|
||||
val name = cr.queryFileName(uri) ?: return@withLoadingDialog
|
||||
val ext = name.substringAfterLast('.')
|
||||
if (ext != "zip") {
|
||||
ctx.importErrorDialog(R.string.exception_theme_filename, ext)
|
||||
return@withLoadingDialog
|
||||
}
|
||||
try {
|
||||
val (newCreated, theme, migrated) = withContext(Dispatchers.IO) {
|
||||
val inputStream = cr.openInputStream(uri)!!
|
||||
val (newCreated, theme, migrated) =
|
||||
ThemeFilesManager.importTheme(inputStream).getOrThrow()
|
||||
ThemeManager.refreshThemes()
|
||||
withContext(Dispatchers.Main) {
|
||||
if (newCreated) {
|
||||
themeListAdapter.prependTheme(theme)
|
||||
} else {
|
||||
themeListAdapter.replaceTheme(theme)
|
||||
}
|
||||
if (migrated) {
|
||||
ctx.toast(R.string.theme_migrated)
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
ctx.importErrorDialog(e)
|
||||
ThemeFilesManager.importTheme(inputStream).getOrThrow()
|
||||
}
|
||||
ThemeManager.refreshThemes()
|
||||
if (newCreated) {
|
||||
themeListAdapter.prependTheme(theme)
|
||||
} else {
|
||||
themeListAdapter.replaceTheme(theme)
|
||||
}
|
||||
if (migrated) {
|
||||
ctx.toast(R.string.theme_migrated)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
ctx.importErrorDialog(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -118,15 +114,13 @@ class ThemeListFragment : Fragment() {
|
||||
val exported = beingExported ?: return@registerForActivityResult
|
||||
beingExported = null
|
||||
lifecycleScope.withLoadingDialog(requireContext()) {
|
||||
withContext(NonCancellable + Dispatchers.IO) {
|
||||
try {
|
||||
try {
|
||||
withContext(Dispatchers.IO) {
|
||||
val outputStream = ctx.contentResolver.openOutputStream(uri)!!
|
||||
ThemeFilesManager.exportTheme(exported, outputStream).getOrThrow()
|
||||
} catch (e: Exception) {
|
||||
withContext(Dispatchers.Main) {
|
||||
ctx.toast(e)
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
ctx.toast(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user