feat: add install options screen (#70)

This commit is contained in:
rushii 2024-02-09 18:28:32 -08:00 • committed by GitHub
parent cd517b8b24
commit 9d6cdf24da
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
64 changed files with 771 additions and 625 deletions

View file

@ -10,6 +10,7 @@ import com.aliucord.manager.network.service.*
import com.aliucord.manager.ui.screens.about.AboutModel
import com.aliucord.manager.ui.screens.home.HomeModel
import com.aliucord.manager.ui.screens.install.InstallModel
import com.aliucord.manager.ui.screens.installopts.InstallOptionsModel
import com.aliucord.manager.ui.screens.plugins.PluginsModel
import com.aliucord.manager.ui.screens.settings.SettingsModel
import com.aliucord.manager.ui.widgets.updater.UpdaterViewModel
@ -54,6 +55,7 @@ class ManagerApplication : Application() {
factoryOf(::AboutModel)
factoryOf(::InstallModel)
factoryOf(::SettingsModel)
factoryOf(::InstallOptionsModel)
viewModelOf(::UpdaterViewModel)
})

View file

@ -1,21 +1,21 @@
package com.aliucord.manager.installer.steps
import com.aliucord.manager.installer.steps.base.Step
import com.aliucord.manager.installer.steps.download.*
import com.aliucord.manager.installer.steps.install.*
import com.aliucord.manager.installer.steps.patch.*
import com.aliucord.manager.installer.steps.prepare.DowngradeCheckStep
import com.aliucord.manager.installer.steps.prepare.FetchInfoStep
import com.aliucord.manager.ui.screens.installopts.InstallOptions
import kotlinx.collections.immutable.persistentListOf
/**
* Used for installing the old Kotlin Discord app.
*/
class KotlinInstallRunner : StepRunner() {
override val steps = persistentListOf<Step>(
class KotlinInstallRunner(options: InstallOptions) : StepRunner() {
override val steps = persistentListOf(
// Prepare
FetchInfoStep(),
DowngradeCheckStep(),
DowngradeCheckStep(options),
// Download
DownloadDiscordStep(),
@ -25,8 +25,8 @@ class KotlinInstallRunner : StepRunner() {
// Patch
CopyDependenciesStep(),
ReplaceIconStep(),
PatchManifestStep(),
ReplaceIconStep(options),
PatchManifestStep(options),
AddInjectorStep(),
AddAliuhookStep(),

View file

@ -5,18 +5,14 @@ import com.aliucord.manager.installer.steps.StepGroup
import com.aliucord.manager.installer.steps.StepRunner
import com.aliucord.manager.installer.steps.base.Step
import com.aliucord.manager.installer.util.ManifestPatcher
import com.aliucord.manager.manager.PreferencesManager
import com.aliucord.manager.ui.screens.installopts.InstallOptions
import com.github.diamondminer88.zip.ZipReader
import com.github.diamondminer88.zip.ZipWriter
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
/**
* Patch the APK's AndroidManifest.xml
*/
class PatchManifestStep : Step(), KoinComponent {
private val prefs: PreferencesManager by inject()
class PatchManifestStep(private val options: InstallOptions) : Step() {
override val group = StepGroup.Patch
override val localizedName = R.string.install_step_patch_manifests
@ -29,9 +25,9 @@ class PatchManifestStep : Step(), KoinComponent {
val patchedManifest = ManifestPatcher.patchManifest(
manifestBytes = manifest,
packageName = prefs.packageName,
appName = prefs.appName,
debuggable = prefs.debuggable,
packageName = options.packageName,
appName = options.appName,
debuggable = options.debuggable,
)
ZipWriter(apk, /* append = */ true).use {

View file

@ -7,7 +7,7 @@ import com.aliucord.manager.installer.steps.StepGroup
import com.aliucord.manager.installer.steps.StepRunner
import com.aliucord.manager.installer.steps.base.Step
import com.aliucord.manager.installer.steps.base.StepState
import com.aliucord.manager.manager.PreferencesManager
import com.aliucord.manager.ui.screens.installopts.InstallOptions
import com.github.diamondminer88.zip.ZipWriter
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
@ -17,15 +17,14 @@ import java.io.InputStream
* Replace icons
*/
@Stable
class ReplaceIconStep : Step(), KoinComponent {
class ReplaceIconStep(private val options: InstallOptions) : Step(), KoinComponent {
private val context: Context by inject()
private val prefs: PreferencesManager by inject()
override val group = StepGroup.Patch
override val localizedName = R.string.setting_replace_icon
override val localizedName = R.string.install_step_patch_icon
override suspend fun execute(container: StepRunner) {
if (!prefs.replaceIcon) {
if (!options.replaceIcon) {
state = StepState.Skipped
return
}

View file

@ -7,7 +7,7 @@ import com.aliucord.manager.installer.steps.StepRunner
import com.aliucord.manager.installer.steps.base.Step
import com.aliucord.manager.installer.steps.base.StepState
import com.aliucord.manager.installer.util.uninstallApk
import com.aliucord.manager.manager.PreferencesManager
import com.aliucord.manager.ui.screens.installopts.InstallOptions
import com.aliucord.manager.util.getPackageVersion
import com.aliucord.manager.util.showToast
import kotlinx.coroutines.Dispatchers
@ -19,16 +19,15 @@ import org.koin.core.component.inject
* Prompt the user to uninstall a previous version of Aliucord if it has a larger version code.
* (Prevent conflicts from downgrading)
*/
class DowngradeCheckStep : Step(), KoinComponent {
class DowngradeCheckStep(private val options: InstallOptions) : Step(), KoinComponent {
private val context: Context by inject()
private val prefs: PreferencesManager by inject()
override val group = StepGroup.Prepare
override val localizedName = R.string.install_step_downgrade_check
override suspend fun execute(container: StepRunner) {
val (_, currentVersion) = try {
context.getPackageVersion(prefs.packageName)
context.getPackageVersion(options.packageName)
}
// Package is not installed
catch (_: Throwable) {
@ -42,7 +41,7 @@ class DowngradeCheckStep : Step(), KoinComponent {
?: throw IllegalArgumentException("Invalid fetched Aliucord target Discord version")
if (currentVersion > targetVersion) {
context.uninstallApk(prefs.packageName)
context.uninstallApk(options.packageName)
withContext(Dispatchers.Main) {
context.showToast(R.string.installer_uninstall_new)

View file

@ -7,13 +7,7 @@ import com.aliucord.manager.ui.components.Theme
class PreferencesManager(preferences: SharedPreferences) : BasePreferenceManager(preferences) {
var theme by enumPreference("theme", Theme.SYSTEM)
var dynamicColor by booleanPreference("dynamic_color", true)
var replaceIcon by booleanPreference("replace_icon", true)
var devMode by booleanPreference("dev_mode", false)
var installer by enumPreference("installer", InstallerSetting.PM)
var debuggable by booleanPreference("debuggable", false)
var appName by stringPreference("app_name", "Aliucord")
var packageName by stringPreference("package_name", "com.aliucord")
var version by stringPreference("version", "146108")
var hermesReplaceLibCpp by booleanPreference("hermes_replace_libcpp", false)
var keepPatchedApks by booleanPreference("keep_patched_apks", false)
}

View file

@ -0,0 +1,36 @@
package com.aliucord.manager.ui.components
import androidx.compose.animation.*
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.withStyle
import com.aliucord.manager.R
import com.aliucord.manager.ui.util.DiscordVersion
@Composable
fun AnimatedVersionDisplay(
version: DiscordVersion,
modifier: Modifier = Modifier,
) {
AnimatedVisibility(
enter = fadeIn() + slideInVertically { it * -2 },
exit = fadeOut() + slideOutVertically { it * -2 },
visible = version !is DiscordVersion.None,
modifier = modifier,
) {
VersionDisplay(
version = version,
prefix = {
withStyle(SpanStyle(fontWeight = FontWeight.Bold)) {
append(stringResource(R.string.version_supported))
append(" ")
}
},
modifier = Modifier.alpha(.5f),
)
}
}

View file

@ -0,0 +1,28 @@
package com.aliucord.manager.ui.components
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.material3.*
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import com.aliucord.manager.R
import com.aliucord.manager.ui.util.mirrorVertically
@Composable
fun ResetToDefaultButton(
enabled: Boolean,
onClick: () -> Unit,
modifier: Modifier = Modifier,
) {
AnimatedVisibility(visible = enabled, modifier = modifier) {
IconButton(onClick = onClick) {
Icon(
painter = painterResource(R.drawable.ic_refresh),
tint = MaterialTheme.colorScheme.secondary,
contentDescription = stringResource(R.string.action_reset_default),
modifier = Modifier.mirrorVertically(),
)
}
}
}

View file

@ -0,0 +1,33 @@
package com.aliucord.manager.ui.components
import androidx.compose.foundation.layout.*
import androidx.compose.material3.*
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
@Composable
fun TextDivider(
text: String,
modifier: Modifier = Modifier,
) {
Row(
horizontalArrangement = Arrangement.spacedBy(6.dp, Alignment.CenterHorizontally),
verticalAlignment = Alignment.CenterVertically,
modifier = modifier
.fillMaxWidth(),
) {
HorizontalDivider(Modifier.weight(1f))
Text(
text = text,
style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.outline,
fontWeight = FontWeight.SemiBold,
)
HorizontalDivider(Modifier.weight(1f))
}
}

View file

@ -1,4 +1,4 @@
package com.aliucord.manager.ui.screens.home.components
package com.aliucord.manager.ui.components
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text

View file

@ -1,109 +0,0 @@
/*
* Copyright (c) 2022 Juby210 & zt
* Licensed under the Open Software License version 3.0
*/
package com.aliucord.manager.ui.components.dialogs
import androidx.compose.runtime.Composable
import androidx.compose.runtime.SideEffect
@Composable
fun InstallerDialog(
onDismiss: () -> Unit,
onConfirm: () -> Unit,
) {
SideEffect(onConfirm)
// TODO: local install option
// TODO: mobile data warning
// Dialog(
// onDismissRequest = onDismiss,
// ) {
// Surface(
// color = AlertDialogDefaults.containerColor,
// tonalElevation = AlertDialogDefaults.TonalElevation,
// shape = AlertDialogDefaults.shape,
// ) {
// Column(
// modifier = Modifier
// .sizeIn(minWidth = 380.dp)
// .padding(24.dp)
// ) {
// // Icon
// Box(
// Modifier
// .align(Alignment.CenterHorizontally)
// .padding(bottom = 16.dp)
// ) {
// Icon(
// imageVector = Icons.Default.Check, // TODO: move away from icon lib
// tint = AlertDialogDefaults.iconContentColor,
// contentDescription = null
// )
// }
//
// // Title
// Box(
// modifier = Modifier
// .align(Alignment.CenterHorizontally)
// .padding(bottom = 30.dp)
// ) {
// Text(
// stringResource(R.string.selector_discord_type),
// color = AlertDialogDefaults.titleContentColor,
// style = MaterialTheme.typography.headlineSmall
// )
// }
//
// // Body
// Box(
// modifier = Modifier
// .padding(bottom = 30.dp)
// ) {
// Text(
// stringResource(R.string.selector_discord_type_body),
// textAlign = TextAlign.Center,
// color = AlertDialogDefaults.textContentColor,
// style = MaterialTheme.typography.bodyMedium
// )
// }
//
// Buttons
// Column(
// verticalArrangement = Arrangement.spacedBy(4.dp),
// modifier = Modifier.clip(MaterialTheme.shapes.large)
// ) {
// ProvideTextStyle(MaterialTheme.typography.labelMedium) {
// Button(
// shape = MaterialTheme.shapes.extraSmall,
// enabled = BuildConfig.RN_ENABLED,
// onClick = {
// discordType = DiscordType.REACT_NATIVE
// triggerConfirm()
// },
// modifier = Modifier
// .fillMaxWidth()
// .height(50.dp)
// ) {
// Text(stringResource(R.string.selector_discord_type_kotlin))
// }
// Button(
// shape = MaterialTheme.shapes.extraSmall,
// onClick = {
// discordType = DiscordType.KOTLIN
// triggerConfirm()
// },
// modifier = Modifier
// .fillMaxWidth()
// .height(50.dp)
// ) {
// Text(stringResource(R.string.selector_discord_type_old))
// }
// }
// }
// }
// }
// }
}

View file

@ -7,7 +7,6 @@ import android.net.ConnectivityManager
import android.provider.Settings
import android.telephony.TelephonyManager
import android.util.Log
import android.widget.Toast
import androidx.compose.runtime.*
import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.graphics.painter.BitmapPainter
@ -59,10 +58,6 @@ class HomeModel(
application.startActivity(launchIntent)
}
fun showMultiInstallToast() {
Toast.makeText(application, "Multi-install support is coming soon!", Toast.LENGTH_SHORT).show()
}
/**
* Check whether the device is connected on a metered WIFI connection or through any type of mobile data,
* to avoid unknowingly downloading a lot of stuff through a potentially metered network.

View file

@ -14,23 +14,17 @@ import androidx.compose.material3.Scaffold
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.LifecycleResumeEffect
import cafe.adriel.voyager.core.screen.Screen
import cafe.adriel.voyager.koin.getScreenModel
import cafe.adriel.voyager.navigator.LocalNavigator
import cafe.adriel.voyager.navigator.currentOrThrow
import com.aliucord.manager.R
import com.aliucord.manager.ui.components.AnimatedVersionDisplay
import com.aliucord.manager.ui.components.ProjectHeader
import com.aliucord.manager.ui.components.dialogs.InstallerDialog
import com.aliucord.manager.ui.components.dialogs.NetworkWarningDialog
import com.aliucord.manager.ui.screens.home.components.*
import com.aliucord.manager.ui.screens.install.InstallScreen
import com.aliucord.manager.ui.screens.installopts.InstallOptionsScreen
import com.aliucord.manager.ui.screens.plugins.PluginsScreen
import com.aliucord.manager.ui.util.DiscordVersion
import com.aliucord.manager.ui.util.paddings.PaddingValuesSides
@ -52,16 +46,12 @@ class HomeScreen : Screen {
}
var showNetworkWarningDialog by remember { mutableStateOf(false) }
var showInstallerDialog by remember { mutableStateOf(false) }
val onClickInstall: () -> Unit = remember {
{
if ((model.installations as? InstallsState.Fetched)?.data?.isNotEmpty() == true) {
model.showMultiInstallToast()
} else if (model.isNetworkDangerous()) {
if (model.isNetworkDangerous()) {
showNetworkWarningDialog = true
} else {
showInstallerDialog = true
navigator.push(InstallOptionsScreen(model.supportedVersion))
}
}
}
@ -70,7 +60,7 @@ class HomeScreen : Screen {
NetworkWarningDialog(
onConfirm = {
showNetworkWarningDialog = false
showInstallerDialog = true
navigator.push(InstallOptionsScreen(model.supportedVersion))
},
onDismiss = {
showNetworkWarningDialog = false
@ -78,16 +68,6 @@ class HomeScreen : Screen {
)
}
if (showInstallerDialog) {
InstallerDialog(
onDismiss = { showInstallerDialog = false },
onConfirm = {
showInstallerDialog = false
navigator.push(InstallScreen())
}
)
}
Scaffold(
topBar = { HomeAppBar() },
) { paddingValues ->
@ -115,24 +95,10 @@ class HomeScreen : Screen {
}
item(key = "SUPPORTED_VERSION") {
AnimatedVisibility(
enter = fadeIn() + slideInVertically { it * -2 },
exit = fadeOut() + slideOutVertically { it * -2 },
visible = model.supportedVersion !is DiscordVersion.None,
) {
VersionDisplay(
version = model.supportedVersion,
prefix = {
withStyle(SpanStyle(fontWeight = FontWeight.Bold)) {
append(stringResource(R.string.version_supported))
append(" ")
}
},
modifier = Modifier
.alpha(.5f)
.padding(bottom = 22.dp),
)
}
AnimatedVersionDisplay(
version = model.supportedVersion,
modifier = Modifier.padding(bottom = 22.dp),
)
}
val installations = (model.installations as? InstallsState.Fetched)?.data
@ -146,7 +112,7 @@ class HomeScreen : Screen {
) {
InstalledItemCard(
data = it,
onUpdate = { showInstallerDialog = true }, // TODO: prefilled install options screen
onUpdate = ::TODO, // TODO: prefilled install options screen
onOpenApp = { model.launchApp(it.packageName) },
onOpenInfo = { model.openAppInfo(it.packageName) },
onOpenPlugins = { navigator.push(PluginsScreen()) }, // TODO: install-specific plugins

View file

@ -17,6 +17,7 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import com.aliucord.manager.R
import com.aliucord.manager.ui.components.SegmentedButton
import com.aliucord.manager.ui.components.VersionDisplay
import com.aliucord.manager.ui.screens.home.InstallData
@Composable

View file

@ -15,6 +15,7 @@ import com.aliucord.manager.installer.steps.base.Step
import com.aliucord.manager.installer.steps.base.StepState
import com.aliucord.manager.installer.steps.install.InstallStep
import com.aliucord.manager.manager.PathManager
import com.aliucord.manager.ui.screens.installopts.InstallOptions
import com.aliucord.manager.ui.util.toUnsafeImmutable
import com.aliucord.manager.util.*
import kotlinx.collections.immutable.ImmutableList
@ -26,6 +27,7 @@ import java.util.Date
class InstallModel(
private val application: Application,
private val paths: PathManager,
private val options: InstallOptions,
) : StateScreenModel<InstallScreenState>(InstallScreenState.Pending) {
private lateinit var startTime: Date
private var installJob: Job? = null
@ -69,7 +71,7 @@ class InstallModel(
mutableState.value = InstallScreenState.Working
val newInstallJob = screenModelScope.launch {
val runner = KotlinInstallRunner()
val runner = KotlinInstallRunner(options)
installSteps = runner.steps.groupBy { it.group }
.mapValues { it.value.toUnsafeImmutable() }

View file

@ -28,14 +28,16 @@ import com.aliucord.manager.installer.steps.StepGroup
import com.aliucord.manager.ui.components.back
import com.aliucord.manager.ui.components.dialogs.InstallerAbortDialog
import com.aliucord.manager.ui.screens.install.components.StepGroupCard
import com.aliucord.manager.ui.screens.installopts.InstallOptions
import org.koin.core.parameter.parametersOf
class InstallScreen : Screen {
class InstallScreen(private val data: InstallOptions) : Screen {
override val key = "Install"
@Composable
override fun Content() {
val navigator = LocalNavigator.currentOrThrow
val model = getScreenModel<InstallModel>()
val model = getScreenModel<InstallModel> { parametersOf(data) }
val state = model.state.collectAsState()
LaunchedEffect(state.value) {

View file

@ -0,0 +1,11 @@
package com.aliucord.manager.ui.screens.installopts
import androidx.compose.runtime.Immutable
@Immutable
data class InstallOptions(
val appName: String,
val packageName: String,
val debuggable: Boolean,
val replaceIcon: Boolean,
)

View file

@ -0,0 +1,128 @@
package com.aliucord.manager.ui.screens.installopts
import android.content.Context
import android.content.pm.PackageManager.NameNotFoundException
import androidx.compose.runtime.*
import cafe.adriel.voyager.core.model.ScreenModel
import cafe.adriel.voyager.core.model.screenModelScope
import com.aliucord.manager.manager.PreferencesManager
import com.aliucord.manager.util.debounce
import kotlinx.coroutines.launch
class InstallOptionsModel(
private val context: Context,
private val prefs: PreferencesManager,
) : ScreenModel {
// ---------- Package name state ----------
var packageName by mutableStateOf("com.aliucord")
private set
var packageNameState by mutableStateOf(PackageNameState.Ok)
private set
val packageNameIsDefault by derivedStateOf {
packageName == "com.aliucord"
}
fun changePackageName(newPackageName: String) {
packageName = newPackageName
fetchPkgNameStateDebounced()
}
fun resetPackageName() {
changePackageName("com.aliucord")
}
// ---------- App name state ----------
var appName by mutableStateOf("Aliucord")
private set
var appNameIsError by mutableStateOf(false)
private set
val appNameIsDefault by derivedStateOf {
appName == "Aliucord"
}
fun changeAppName(newAppName: String) {
appName = newAppName
appNameIsError = newAppName.length !in (1..150)
}
fun resetAppName() {
appName = "Aliucord"
}
// ---------- Icon patching state ----------
var replaceIcon by mutableStateOf(true)
private set
fun changeReplaceIcon(value: Boolean) {
replaceIcon = value
}
// ---------- Debuggable state ----------
var debuggable by mutableStateOf(false)
private set
fun changeDebuggable(value: Boolean) {
debuggable = value
}
// ---------- Config generation ----------
val isConfigValid by derivedStateOf {
val invalidChecks = arrayOf(
packageNameState == PackageNameState.Invalid,
appNameIsError,
)
invalidChecks.none { it }
}
fun generateConfig(): InstallOptions {
if (!isConfigValid) error("invalid config state")
return InstallOptions(
appName = appName,
packageName = packageName,
debuggable = debuggable,
replaceIcon = replaceIcon, // TODO: advanced icon patchers
)
}
// ---------- Other ----------
val isDevMode: Boolean
get() = prefs.devMode
// A throttled variant of fetchPkgNameState()
private val fetchPkgNameStateDebounced: () -> Unit =
screenModelScope.debounce(100L, function = ::fetchPkgNameState)
private fun fetchPkgNameState() {
if (packageName.length !in (3..150) || !PACKAGE_REGEX.matches(this.packageName)) {
packageNameState = PackageNameState.Invalid
} else {
try {
context.packageManager.getPackageInfo(packageName, 0)
packageNameState = PackageNameState.Taken
} catch (_: NameNotFoundException) {
packageNameState = PackageNameState.Ok
}
}
}
init {
screenModelScope.launch { fetchPkgNameState() }
}
companion object {
private val PACKAGE_REGEX = """^[a-z]\w*(\.[a-z]\w*)+$"""
.toRegex(RegexOption.IGNORE_CASE)
}
}
enum class PackageNameState {
Ok,
Invalid,
Taken,
}

View file

@ -0,0 +1,135 @@
package com.aliucord.manager.ui.screens.installopts
import androidx.compose.foundation.layout.*
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import cafe.adriel.voyager.core.screen.Screen
import cafe.adriel.voyager.koin.getScreenModel
import cafe.adriel.voyager.navigator.LocalNavigator
import cafe.adriel.voyager.navigator.currentOrThrow
import com.aliucord.manager.R
import com.aliucord.manager.ui.components.AnimatedVersionDisplay
import com.aliucord.manager.ui.components.TextDivider
import com.aliucord.manager.ui.screens.install.InstallScreen
import com.aliucord.manager.ui.screens.installopts.components.InstallOptionsAppBar
import com.aliucord.manager.ui.screens.installopts.components.PackageNameState
import com.aliucord.manager.ui.screens.installopts.components.options.SwitchInstallOption
import com.aliucord.manager.ui.screens.installopts.components.options.TextInstallOption
import com.aliucord.manager.ui.util.DiscordVersion
import com.aliucord.manager.ui.util.thenIf
class InstallOptionsScreen(
private val supportedVersion: DiscordVersion = DiscordVersion.None,
) : Screen {
override val key = "InstallOptions"
@Composable
override fun Content() {
val navigator = LocalNavigator.currentOrThrow
val model = getScreenModel<InstallOptionsModel>()
Scaffold(
topBar = { InstallOptionsAppBar() },
) { paddingValues ->
Column(
verticalArrangement = Arrangement.spacedBy(20.dp),
modifier = Modifier
.fillMaxSize()
.padding(paddingValues)
.padding(horizontal = 20.dp, vertical = 10.dp)
) {
Text(
text = stringResource(R.string.installopts_title),
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant,
textAlign = TextAlign.Center,
)
var animatedVersion by remember { mutableStateOf<DiscordVersion>(DiscordVersion.None) }
LaunchedEffect(Unit) {
animatedVersion = supportedVersion
}
AnimatedVersionDisplay(
version = animatedVersion,
modifier = Modifier
.align(Alignment.CenterHorizontally)
.offset(y = (-10).dp),
)
TextDivider(text = stringResource(R.string.installopts_divider_basic))
SwitchInstallOption(
icon = painterResource(R.drawable.ic_app_shortcut),
name = stringResource(R.string.installopts_icon_title),
description = stringResource(R.string.installopts_icon_desc),
value = model.replaceIcon,
onValueChange = model::changeReplaceIcon,
modifier = Modifier.padding(bottom = 8.dp)
)
TextInstallOption(
name = stringResource(R.string.installopts_appname_title),
description = stringResource(R.string.installopts_appname_desc),
value = model.appName,
valueIsError = model.appNameIsError,
valueIsDefault = model.appNameIsDefault,
onValueChange = model::changeAppName,
onValueReset = model::resetAppName
)
TextInstallOption(
name = stringResource(R.string.installopts_pkgname_title),
description = stringResource(R.string.installopts_pkgname_desc),
value = model.packageName,
valueIsError = model.packageNameState == PackageNameState.Invalid,
valueIsDefault = model.packageNameIsDefault,
onValueChange = model::changePackageName,
onValueReset = model::resetPackageName,
) {
PackageNameState(
state = model.packageNameState,
modifier = Modifier.padding(start = 4.dp),
)
}
TextDivider(
text = stringResource(R.string.installopts_divider_advanced),
modifier = Modifier.padding(top = 12.dp),
)
SwitchInstallOption(
icon = painterResource(R.drawable.ic_bug),
name = stringResource(R.string.installopts_debuggable_title),
description = stringResource(R.string.installopts_debuggable_desc),
value = model.debuggable,
onValueChange = model::changeDebuggable,
enabled = model.isDevMode,
modifier = Modifier
.thenIf(!model.isDevMode) { alpha(.6f) }
)
Spacer(Modifier.weight(1f))
FilledTonalButton(
enabled = model.isConfigValid,
onClick = { navigator replace InstallScreen(model.generateConfig()) },
colors = ButtonDefaults.filledTonalButtonColors(
contentColor = MaterialTheme.colorScheme.primary,
),
modifier = Modifier
.padding(bottom = 10.dp)
.align(Alignment.End),
) {
Text(stringResource(R.string.action_install))
}
}
}
}
}

View file

@ -0,0 +1,29 @@
package com.aliucord.manager.ui.screens.installopts.components
import androidx.compose.material3.*
import androidx.compose.runtime.Composable
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import cafe.adriel.voyager.navigator.LocalNavigator
import cafe.adriel.voyager.navigator.currentOrThrow
import com.aliucord.manager.R
import com.aliucord.manager.ui.components.BackButton
import com.aliucord.manager.ui.screens.settings.SettingsScreen
@Composable
fun InstallOptionsAppBar() {
TopAppBar(
navigationIcon = { BackButton() },
title = { Text(stringResource(R.string.action_add_install)) },
actions = {
val navigator = LocalNavigator.currentOrThrow
IconButton(onClick = { navigator.push(SettingsScreen()) }) {
Icon(
painter = painterResource(R.drawable.ic_settings),
contentDescription = stringResource(R.string.navigation_settings)
)
}
}
)
}

View file

@ -0,0 +1,65 @@
package com.aliucord.manager.ui.screens.installopts.components
import androidx.compose.animation.Crossfade
import androidx.compose.foundation.layout.*
import androidx.compose.material3.*
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import com.aliucord.manager.R
import com.aliucord.manager.ui.screens.installopts.PackageNameState
@Composable
fun PackageNameState(
state: PackageNameState,
modifier: Modifier = Modifier,
) {
Crossfade(
targetState = state,
label = "PackageNameStateLabel CrossFade"
) { animatedState ->
val (label, icon, tint) = when (animatedState) {
PackageNameState.Invalid -> Triple(
R.string.installopts_pkgname_invalid,
R.drawable.ic_canceled,
MaterialTheme.colorScheme.error,
)
PackageNameState.Taken -> Triple(
R.string.installopts_pkgname_taken,
R.drawable.ic_warning,
Color(0xFFFFCC00),
)
PackageNameState.Ok -> Triple(
R.string.installopts_pkgname_ok,
R.drawable.ic_check_circle,
Color(0xFF59B463),
)
}
Row(
horizontalArrangement = Arrangement.spacedBy(4.dp),
verticalAlignment = Alignment.CenterVertically,
modifier = modifier,
) {
Icon(
painter = painterResource(icon),
contentDescription = null,
tint = tint,
modifier = Modifier.size(20.dp),
)
Text(
text = stringResource(label),
style = MaterialTheme.typography.bodySmall,
modifier = Modifier.alpha(.7f),
)
}
}
}

View file

@ -0,0 +1,39 @@
package com.aliucord.manager.ui.screens.installopts.components.options
import androidx.compose.foundation.layout.*
import androidx.compose.material3.MaterialTheme
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.alpha
import androidx.compose.ui.unit.dp
@Composable
fun InstallOption(
name: String,
description: String?,
modifier: Modifier = Modifier,
content: @Composable ColumnScope.() -> Unit,
) {
Column(
verticalArrangement = Arrangement.spacedBy(4.dp),
horizontalAlignment = Alignment.Start,
modifier = modifier,
) {
Text(
text = name,
style = MaterialTheme.typography.titleMedium,
)
if (description != null) {
Text(
text = description,
style = MaterialTheme.typography.bodySmall,
modifier = Modifier.alpha(.7f),
)
}
content()
}
}

View file

@ -0,0 +1,73 @@
package com.aliucord.manager.ui.screens.installopts.components.options
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.*
import androidx.compose.material3.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.unit.dp
@Composable
fun SwitchInstallOption(
icon: Painter,
name: String,
description: String,
value: Boolean,
onValueChange: (Boolean) -> Unit,
enabled: Boolean = true,
modifier: Modifier = Modifier,
) {
val interactionSource = remember(::MutableInteractionSource)
val onClick = remember(value) { { onValueChange(!value) } }
Row(
horizontalArrangement = Arrangement.spacedBy(12.dp),
verticalAlignment = Alignment.CenterVertically,
modifier = modifier
.fillMaxWidth()
.clickable(
onClick = onClick,
enabled = enabled,
interactionSource = interactionSource,
indication = null,
role = Role.Switch,
),
) {
Icon(
painter = icon,
contentDescription = null,
modifier = Modifier.size(26.dp),
)
Column(
verticalArrangement = Arrangement.spacedBy(2.dp),
modifier = Modifier.weight(1f)
) {
Text(
text = name,
style = MaterialTheme.typography.titleMedium,
)
Text(
text = description,
style = MaterialTheme.typography.bodySmall,
modifier = Modifier
.alpha(.7f)
)
}
Switch(
checked = value,
enabled = enabled,
onCheckedChange = onValueChange,
interactionSource = interactionSource,
modifier = Modifier.padding(start = 6.dp),
)
}
}

View file

@ -0,0 +1,53 @@
package com.aliucord.manager.ui.screens.installopts.components.options
import androidx.compose.foundation.layout.*
import androidx.compose.material3.*
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.aliucord.manager.ui.components.ResetToDefaultButton
@Composable
fun TextInstallOption(
name: String,
description: String,
value: String,
valueIsError: Boolean,
valueIsDefault: Boolean,
onValueChange: (String) -> Unit,
onValueReset: () -> Unit,
modifier: Modifier = Modifier,
extra: (@Composable ColumnScope.() -> Unit)? = null,
) {
InstallOption(
name = name,
description = description,
modifier = modifier,
) {
val containerColor = MaterialTheme.colorScheme
.surfaceColorAtElevation(LocalAbsoluteTonalElevation.current + .5.dp)
OutlinedTextField(
value = value,
onValueChange = onValueChange,
isError = valueIsError,
singleLine = true,
colors = OutlinedTextFieldDefaults.colors(
unfocusedContainerColor = containerColor,
focusedContainerColor = containerColor,
errorContainerColor = containerColor,
),
trailingIcon = {
ResetToDefaultButton(
enabled = !valueIsDefault,
onClick = onValueReset,
)
},
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 4.dp),
)
extra?.invoke(this)
}
}

View file

@ -3,27 +3,18 @@ package com.aliucord.manager.ui.screens.settings
import android.app.Application
import androidx.compose.runtime.*
import cafe.adriel.voyager.core.model.ScreenModel
import cafe.adriel.voyager.core.model.screenModelScope
import com.aliucord.manager.R
import com.aliucord.manager.manager.PreferencesManager
import com.aliucord.manager.ui.components.Theme
import com.aliucord.manager.util.showToast
import com.aliucord.manager.util.throttle
class SettingsModel(
private val application: Application,
val preferences: PreferencesManager,
) : ScreenModel {
private val checkPackageNameThrottled = throttle(50L, screenModelScope) {
packageNameError = !PACKAGE_REGEX.matches(preferences.packageName)
}
var showThemeDialog by mutableStateOf(false)
private set
var packageNameError by mutableStateOf(false)
private set
fun showThemeDialog() {
showThemeDialog = true
}
@ -32,41 +23,12 @@ class SettingsModel(
showThemeDialog = false
}
fun setPackageName(packageName: String) {
preferences.packageName = packageName
checkPackageNameThrottled()
}
fun setAppName(appName: String) {
if (appName.isNotBlank()) preferences.appName = appName
}
fun setTheme(theme: Theme) {
preferences.theme = theme
}
fun setVersion(version: String) {
if (version.isNotBlank()) preferences.version = version
}
fun clearCacheDir() {
application.externalCacheDir?.deleteRecursively()
application.showToast(R.string.action_cleared_cache)
}
init {
checkPackageNameThrottled()
}
override fun onDispose() {
if (!PACKAGE_REGEX.matches(preferences.packageName)) {
preferences.packageName = "com.aliucord"
application.showToast(R.string.settings_invalid_package_name)
}
}
companion object {
private val PACKAGE_REGEX = "^[a-z]\\w*(\\.[a-z]\\w*)+\$"
.toRegex(RegexOption.IGNORE_CASE)
}
}

View file

@ -5,7 +5,6 @@
package com.aliucord.manager.ui.screens.settings
import androidx.compose.animation.*
import androidx.compose.foundation.*
import androidx.compose.foundation.layout.*
import androidx.compose.material3.*
@ -76,22 +75,8 @@ class SettingsScreen : Screen {
SettingsHeader(stringResource(R.string.settings_advanced))
SettingsTextField(
label = stringResource(R.string.setting_app_name),
pref = preferences.appName,
onPrefChange = model::setAppName
)
Spacer(modifier = Modifier.height(4.dp))
SettingsSwitch(
label = stringResource(R.string.setting_replace_icon),
secondaryLabel = stringResource(R.string.setting_replace_icon_desc),
pref = preferences.replaceIcon,
icon = { Icon(painterResource(R.drawable.ic_app_shortcut), null) }
) {
preferences.replaceIcon = it
}
SettingsSwitch(
label = stringResource(R.string.setting_keep_patched_apks),
secondaryLabel = stringResource(R.string.setting_keep_patched_apks_desc),
@ -110,45 +95,6 @@ class SettingsScreen : Screen {
preferences.devMode = it
}
AnimatedVisibility(
visible = preferences.devMode,
enter = expandVertically(),
exit = shrinkVertically()
) {
Column(
verticalArrangement = Arrangement.spacedBy(6.dp)
) {
SettingsTextField(
label = stringResource(R.string.setting_package_name),
pref = preferences.packageName,
onPrefChange = model::setPackageName,
error = model.packageNameError
)
SettingsTextField(
label = stringResource(R.string.setting_target_version),
pref = preferences.version,
onPrefChange = model::setVersion
)
SettingsSwitch(
label = stringResource(R.string.setting_debuggable),
secondaryLabel = stringResource(R.string.setting_debuggable_desc),
pref = preferences.debuggable,
icon = { Icon(painterResource(R.drawable.ic_bug), null) },
onPrefChange = { preferences.debuggable = it },
)
SettingsSwitch(
label = stringResource(R.string.setting_hermes_replace_libcpp),
secondaryLabel = stringResource(R.string.setting_hermes_replace_libcpp_desc),
icon = { Icon(painterResource(R.drawable.ic_copy_file), null) },
pref = preferences.hermesReplaceLibCpp,
onPrefChange = { preferences.hermesReplaceLibCpp = it },
)
}
}
Button(
modifier = Modifier
.fillMaxWidth()

View file

@ -1,7 +1,12 @@
@file:Suppress("NOTHING_TO_INLINE")
package com.aliucord.manager.ui.util
import androidx.annotation.StringRes
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Stable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.scale
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.*
import kotlinx.collections.immutable.ImmutableList
@ -75,3 +80,7 @@ inline fun annotatingStringResource(
append(string.substring(lastIndex))
}
}
@Stable
inline fun Modifier.mirrorVertically(): Modifier =
scale(scaleX = -1f, scaleY = 1f)

View file

@ -0,0 +1,55 @@
package com.aliucord.manager.util
import kotlinx.coroutines.*
import java.util.concurrent.atomic.AtomicBoolean
/**
* Returns a function that when called any number of times, only executes [function] after
* [waitMs] has passed after the last call, using the last call's passed in param(s).
* This is for things like "throttling" search text input to reduce the amount of actual
* calls to only when the user stops typing for example.
*
* @param waitMs Milliseconds to wait for additional calls before executing [function]
* @param waitCompletion If true, then ignore any calls while [function] is executing instead of
* cancelling it and restarting the debouncing job.
* @param function The target function to debounce.
* @return Refer to the general description
*/
fun <P1, P2> CoroutineScope.debounce(
waitMs: Long,
waitCompletion: Boolean = false,
function: suspend (P1, P2) -> Unit,
): (P1, P2) -> Unit {
var job: Job? = null
val executing = AtomicBoolean(false)
return block@{ p1: P1, p2: P2 ->
if (waitCompletion && !executing.get()) {
return@block
} else if (job?.isActive == true) {
job?.cancel()
}
job = launch {
delay(waitMs)
try {
executing.set(true)
function(p1, p2)
} finally {
executing.set(false)
}
}
}
}
// Re-binding the same function but with different amount of params
// Yes this is ugly but there isn't really a better way to do this efficiently afaik
inline fun CoroutineScope.debounce(waitMs: Long, waitCompletion: Boolean = false, crossinline function: suspend () -> Unit) =
debounce<Any?, Any?>(waitMs, waitCompletion) { _, _ -> function() }
.let { { it(null, null) } }
inline fun <T> CoroutineScope.debounce(waitMs: Long, waitCompletion: Boolean = false, crossinline function: suspend (T) -> Unit) =
debounce<T, Any?>(waitMs, waitCompletion) { p1, _ -> function(p1) }
.let { { p1: T -> it(p1, null) } }

View file

@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="#FFFFFFFF"
android:pathData="M760,760L320,760q-33,0 -56.5,-23.5T240,680v-560q0,-33 23.5,-56.5T320,40h247q16,0 30.5,6t25.5,17l194,194q11,11 17,25.5t6,30.5v367q0,33 -23.5,56.5T760,760ZM760,320L560,120v140q0,25 17.5,42.5T620,320h140ZM160,920q-33,0 -56.5,-23.5T80,840v-520q0,-17 11.5,-28.5T120,280q17,0 28.5,11.5T160,320v520h400q17,0 28.5,11.5T600,880q0,17 -11.5,28.5T560,920L160,920Z" />
</vector>

View file

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="#FFFFFFFF"
android:pathData="M480,800q-134,0 -227,-93t-93,-227q0,-134 93,-227t227,-93q69,0 132,28.5T720,270v-70q0,-17 11.5,-28.5T760,160q17,0 28.5,11.5T800,200v200q0,17 -11.5,28.5T760,440L560,440q-17,0 -28.5,-11.5T520,400q0,-17 11.5,-28.5T560,360h128q-32,-56 -87.5,-88T480,240q-100,0 -170,70t-70,170q0,100 70,170t170,70q68,0 124.5,-34.5T692,593q8,-14 22.5,-19.5t29.5,-0.5q16,5 23,21t-1,30q-41,80 -117,128t-169,48Z" />
</vector>

View file

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="#FFFFFFFF"
android:pathData="M137.02,820q-10.17,0 -18.27,-4.97 -8.1,-4.97 -12.6,-13.1 -4.68,-8.08 -5.15,-17.5 -0.47,-9.42 5.09,-18.67l342.43,-591.51q5.55,-9.24 13.9,-13.66 8.35,-4.42 17.58,-4.42 9.23,0 17.58,4.42 8.35,4.42 13.9,13.66l342.43,591.51q5.55,9.24 5.09,18.67 -0.47,9.42 -5.15,17.5 -4.5,8.13 -12.6,13.1 -8.1,4.97 -18.27,4.97L137.02,820ZM178,760h604L480,240 178,760ZM480,712.31q13.73,0 23.02,-9.29 9.29,-9.29 9.29,-23.02 0,-13.73 -9.29,-23.02 -9.29,-9.29 -23.02,-9.29 -13.73,0 -23.02,9.29 -9.29,9.29 -9.29,23.02 0,13.73 9.29,23.02 9.29,9.29 23.02,9.29ZM480.01,607.69q12.76,0 21.37,-8.63 8.61,-8.63 8.61,-21.37v-140q0,-12.75 -8.63,-21.37 -8.63,-8.63 -21.38,-8.63 -12.76,0 -21.37,8.63 -8.61,8.62 -8.61,21.37v140q0,12.75 8.63,21.37 8.63,8.63 21.38,8.63ZM480,500Z" />
</vector>

View file

@ -35,19 +35,9 @@
<string name="settings_appearance">Appearance</string>
<string name="settings_developer_options">Developer options</string>
<string name="setting_clear_cache">Clear cache</string>
<string name="setting_replace_icon">Replace app icon</string>
<string name="setting_replace_icon_desc">Uses the Aliucord variant as opposed to Discord\'s own icon</string>
<string name="setting_debuggable">Debuggable</string>
<string name="setting_debuggable_desc">Enable debuggable flag</string>
<string name="setting_app_name">App Name</string>
<string name="setting_package_name">Package Name</string>
<string name="setting_target_version">Download Version</string>
<string name="setting_dynamic_color">Dynamic color</string>
<string name="setting_hermes_replace_libcpp">Replace libc++ (RN only)</string>
<string name="setting_hermes_replace_libcpp_desc">Downloads and uses libc++ from patched hermes</string>
<string name="setting_keep_patched_apks">Keep patched APKs</string>
<string name="setting_keep_patched_apks_desc">Don\'t delete patched APKs after installing (for installing manually)</string>
<string name="settings_invalid_package_name">Invalid package name, reset to com.aliucord</string>
<string name="theme_system">System</string>
<string name="theme_dark">Dark</string>
<string name="theme_light">Light</string>

View file

@ -35,19 +35,9 @@
<string name="settings_appearance">Appearance</string>
<string name="settings_developer_options">Developer options</string>
<string name="setting_clear_cache">Clear cache</string>
<string name="setting_replace_icon">Replace app icon</string>
<string name="setting_replace_icon_desc">Uses the Aliucord variant as opposed to Discord\'s own icon</string>
<string name="setting_debuggable">Debuggable</string>
<string name="setting_debuggable_desc">Enable debuggable flag</string>
<string name="setting_app_name">App Name</string>
<string name="setting_package_name">Package Name</string>
<string name="setting_target_version">Download Version</string>
<string name="setting_dynamic_color">Dynamic color</string>
<string name="setting_hermes_replace_libcpp">Replace libc++ (RN only)</string>
<string name="setting_hermes_replace_libcpp_desc">Downloads and uses libc++ from patched hermes</string>
<string name="setting_keep_patched_apks">Keep patched APKs</string>
<string name="setting_keep_patched_apks_desc">Don\'t delete patched APKs after installing (for installing manually)</string>
<string name="settings_invalid_package_name">Invalid package name, reset to com.aliucord</string>
<string name="theme_system">System</string>
<string name="theme_dark">Dark</string>
<string name="theme_light">Light</string>

View file

@ -35,19 +35,9 @@
<string name="settings_appearance">Appearance</string>
<string name="settings_developer_options">Developer options</string>
<string name="setting_clear_cache">Clear cache</string>
<string name="setting_replace_icon">Replace app icon</string>
<string name="setting_replace_icon_desc">Uses the Aliucord variant as opposed to Discord\'s own icon</string>
<string name="setting_debuggable">Debuggable</string>
<string name="setting_debuggable_desc">Enable debuggable flag</string>
<string name="setting_app_name">App Name</string>
<string name="setting_package_name">Package Name</string>
<string name="setting_target_version">Download Version</string>
<string name="setting_dynamic_color">Dynamic color</string>
<string name="setting_hermes_replace_libcpp">Replace libc++ (RN only)</string>
<string name="setting_hermes_replace_libcpp_desc">Downloads and uses libc++ from patched hermes</string>
<string name="setting_keep_patched_apks">Keep patched APKs</string>
<string name="setting_keep_patched_apks_desc">Don\'t delete patched APKs after installing (for installing manually)</string>
<string name="settings_invalid_package_name">Invalid package name, reset to com.aliucord</string>
<string name="theme_system">System</string>
<string name="theme_dark">Dark</string>
<string name="theme_light">Light</string>

View file

@ -35,19 +35,9 @@
<string name="settings_appearance">Appearance</string>
<string name="settings_developer_options">Developer options</string>
<string name="setting_clear_cache">Clear cache</string>
<string name="setting_replace_icon">Replace app icon</string>
<string name="setting_replace_icon_desc">Uses the Aliucord variant as opposed to Discord\'s own icon</string>
<string name="setting_debuggable">Debuggable</string>
<string name="setting_debuggable_desc">Enable debuggable flag</string>
<string name="setting_app_name">App Name</string>
<string name="setting_package_name">Package Name</string>
<string name="setting_target_version">Download Version</string>
<string name="setting_dynamic_color">Dynamic color</string>
<string name="setting_hermes_replace_libcpp">Replace libc++ (RN only)</string>
<string name="setting_hermes_replace_libcpp_desc">Downloads and uses libc++ from patched hermes</string>
<string name="setting_keep_patched_apks">Keep patched APKs</string>
<string name="setting_keep_patched_apks_desc">Don\'t delete patched APKs after installing (for installing manually)</string>
<string name="settings_invalid_package_name">Invalid package name, reset to com.aliucord</string>
<string name="theme_system">System</string>
<string name="theme_dark">Dark</string>
<string name="theme_light">Light</string>

View file

@ -35,19 +35,9 @@
<string name="settings_appearance">Appearance</string>
<string name="settings_developer_options">Developer options</string>
<string name="setting_clear_cache">Clear cache</string>
<string name="setting_replace_icon">Replace app icon</string>
<string name="setting_replace_icon_desc">Uses the Aliucord variant as opposed to Discord\'s own icon</string>
<string name="setting_debuggable">Debuggable</string>
<string name="setting_debuggable_desc">Enable debuggable flag</string>
<string name="setting_app_name">App Name</string>
<string name="setting_package_name">Package Name</string>
<string name="setting_target_version">Download Version</string>
<string name="setting_dynamic_color">Dynamic color</string>
<string name="setting_hermes_replace_libcpp">Replace libc++ (RN only)</string>
<string name="setting_hermes_replace_libcpp_desc">Downloads and uses libc++ from patched hermes</string>
<string name="setting_keep_patched_apks">Keep patched APKs</string>
<string name="setting_keep_patched_apks_desc">Don\'t delete patched APKs after installing (for installing manually)</string>
<string name="settings_invalid_package_name">Invalid package name, reset to com.aliucord</string>
<string name="theme_system">System</string>
<string name="theme_dark">Dark</string>
<string name="theme_light">Light</string>

View file

@ -35,19 +35,9 @@
<string name="settings_appearance">Appearance</string>
<string name="settings_developer_options">Developer options</string>
<string name="setting_clear_cache">Clear cache</string>
<string name="setting_replace_icon">Replace app icon</string>
<string name="setting_replace_icon_desc">Uses the Aliucord variant as opposed to Discord\'s own icon</string>
<string name="setting_debuggable">Debuggable</string>
<string name="setting_debuggable_desc">Enable debuggable flag</string>
<string name="setting_app_name">App Name</string>
<string name="setting_package_name">Package Name</string>
<string name="setting_target_version">Download Version</string>
<string name="setting_dynamic_color">Dynamic color</string>
<string name="setting_hermes_replace_libcpp">Replace libc++ (RN only)</string>
<string name="setting_hermes_replace_libcpp_desc">Downloads and uses libc++ from patched hermes</string>
<string name="setting_keep_patched_apks">Keep patched APKs</string>
<string name="setting_keep_patched_apks_desc">Don\'t delete patched APKs after installing (for installing manually)</string>
<string name="settings_invalid_package_name">Invalid package name, reset to com.aliucord</string>
<string name="theme_system">System</string>
<string name="theme_dark">Dark</string>
<string name="theme_light">Light</string>

View file

@ -35,19 +35,9 @@
<string name="settings_appearance">Εμφάνιση</string>
<string name="settings_developer_options">Επιλογές προγραμματιστών</string>
<string name="setting_clear_cache">Εκκαθάριση προσωρινής μνήμης</string>
<string name="setting_replace_icon">Αντικατάσταση εικονιδίου εφαρμογής</string>
<string name="setting_replace_icon_desc">Χρησιμοποιεί την παραλλαγή του Aliucord σε αντίθεση με το εικονίδιο του Discord</string>
<string name="setting_debuggable">Αποσφαλματώσιμο</string>
<string name="setting_debuggable_desc">Ενεργοποίηση επισήμανσης αποσφαλμάτωσης</string>
<string name="setting_app_name">Όνομα εφαρμογής</string>
<string name="setting_package_name">Όνομα Πακέτου</string>
<string name="setting_target_version">Λήψη έκδοσης</string>
<string name="setting_dynamic_color">Δυναμικό χρώμα</string>
<string name="setting_hermes_replace_libcpp">Replace libc++ (RN only)</string>
<string name="setting_hermes_replace_libcpp_desc">Downloads and uses libc++ from patched hermes</string>
<string name="setting_keep_patched_apks">Keep patched APKs</string>
<string name="setting_keep_patched_apks_desc">Don\'t delete patched APKs after installing (for installing manually)</string>
<string name="settings_invalid_package_name">Άκυρο όνομα πακέτου, επαναφορά σε com.aliucord</string>
<string name="theme_system">Σύστημα</string>
<string name="theme_dark">Σκοτεινό</string>
<string name="theme_light">Φωτεινό</string>

View file

@ -35,19 +35,9 @@
<string name="settings_appearance">Apariencia</string>
<string name="settings_developer_options">Opciones de Desarrollador</string>
<string name="setting_clear_cache">Limpiar caché</string>
<string name="setting_replace_icon">Reemplazar el icono de la app</string>
<string name="setting_replace_icon_desc">Usa la variante de Aliucord en vez de el icono de Discord</string>
<string name="setting_debuggable">Depurable</string>
<string name="setting_debuggable_desc">Activa el modo de Depuración</string>
<string name="setting_app_name">Nombre de la App</string>
<string name="setting_package_name">Nombre del Paquete</string>
<string name="setting_target_version">Versión a descargar (solo RN)</string>
<string name="setting_dynamic_color">Colores dinámicos</string>
<string name="setting_hermes_replace_libcpp">Reemplazar libc++ (solo RN)</string>
<string name="setting_hermes_replace_libcpp_desc">Descargar y usar libc++ de hermes parcheado</string>
<string name="setting_keep_patched_apks">Mantener APKs parcheados</string>
<string name="setting_keep_patched_apks_desc">No eliminar APKs parcheados después de la instalación (para instalar manualmente)</string>
<string name="settings_invalid_package_name">Nombre de paquete inválido, restableciendo a com.aliucord</string>
<string name="theme_system">Sistema</string>
<string name="theme_dark">Oscuro</string>
<string name="theme_light">Claro</string>

View file

@ -35,19 +35,9 @@
<string name="settings_appearance">Appearance</string>
<string name="settings_developer_options">Developer options</string>
<string name="setting_clear_cache">Clear cache</string>
<string name="setting_replace_icon">Replace app icon</string>
<string name="setting_replace_icon_desc">Uses the Aliucord variant as opposed to Discord\'s own icon</string>
<string name="setting_debuggable">Debuggable</string>
<string name="setting_debuggable_desc">Enable debuggable flag</string>
<string name="setting_app_name">App Name</string>
<string name="setting_package_name">Package Name</string>
<string name="setting_target_version">Download Version</string>
<string name="setting_dynamic_color">Dynamic color</string>
<string name="setting_hermes_replace_libcpp">Replace libc++ (RN only)</string>
<string name="setting_hermes_replace_libcpp_desc">Downloads and uses libc++ from patched hermes</string>
<string name="setting_keep_patched_apks">Keep patched APKs</string>
<string name="setting_keep_patched_apks_desc">Don\'t delete patched APKs after installing (for installing manually)</string>
<string name="settings_invalid_package_name">Invalid package name, reset to com.aliucord</string>
<string name="theme_system">System</string>
<string name="theme_dark">Dark</string>
<string name="theme_light">Light</string>

View file

@ -35,19 +35,9 @@
<string name="settings_appearance">Apparence</string>
<string name="settings_developer_options">Options de développeur</string>
<string name="setting_clear_cache">Vider le cache</string>
<string name="setting_replace_icon">Remplacer l\'icône de l\'application</string>
<string name="setting_replace_icon_desc">Utiliser le logo d\'Aliucord à la place de celui de Discord</string>
<string name="setting_debuggable">Debuggable</string>
<string name="setting_debuggable_desc">Activer le drapeau de débogage</string>
<string name="setting_app_name">Nom de l\'application</string>
<string name="setting_package_name">Nom du paquet</string>
<string name="setting_target_version">Download Version</string>
<string name="setting_dynamic_color">Couleurs dynamiques</string>
<string name="setting_hermes_replace_libcpp">Remplacer libc++ (RN seulement)</string>
<string name="setting_hermes_replace_libcpp_desc">Télécharger et utiliser libc++ à partir des hermes patchés</string>
<string name="setting_keep_patched_apks">Garder les APKs patchés</string>
<string name="setting_keep_patched_apks_desc">Ne pas supprimer les APKs patchés après l\'installation (pour les installer manuellement)</string>
<string name="settings_invalid_package_name">Nom de paquet invalide, réinitialiser à com.aliucord</string>
<string name="theme_system">Système</string>
<string name="theme_dark">Sombre</string>
<string name="theme_light">Clair</string>

View file

@ -35,19 +35,9 @@
<string name="settings_appearance">Appearance</string>
<string name="settings_developer_options">Developer options</string>
<string name="setting_clear_cache">Clear cache</string>
<string name="setting_replace_icon">Replace app icon</string>
<string name="setting_replace_icon_desc">Uses the Aliucord variant as opposed to Discord\'s own icon</string>
<string name="setting_debuggable">Debuggable</string>
<string name="setting_debuggable_desc">Enable debuggable flag</string>
<string name="setting_app_name">App Name</string>
<string name="setting_package_name">Package Name</string>
<string name="setting_target_version">Download Version</string>
<string name="setting_dynamic_color">Dynamic color</string>
<string name="setting_hermes_replace_libcpp">Replace libc++ (RN only)</string>
<string name="setting_hermes_replace_libcpp_desc">Downloads and uses libc++ from patched hermes</string>
<string name="setting_keep_patched_apks">Keep patched APKs</string>
<string name="setting_keep_patched_apks_desc">Don\'t delete patched APKs after installing (for installing manually)</string>
<string name="settings_invalid_package_name">Invalid package name, reset to com.aliucord</string>
<string name="theme_system">System</string>
<string name="theme_dark">Dark</string>
<string name="theme_light">Light</string>

View file

@ -35,19 +35,9 @@
<string name="settings_appearance">Appearance</string>
<string name="settings_developer_options">Developer options</string>
<string name="setting_clear_cache">Clear cache</string>
<string name="setting_replace_icon">Replace app icon</string>
<string name="setting_replace_icon_desc">Uses the Aliucord variant as opposed to Discord\'s own icon</string>
<string name="setting_debuggable">Debuggable</string>
<string name="setting_debuggable_desc">Enable debuggable flag</string>
<string name="setting_app_name">App Name</string>
<string name="setting_package_name">Package Name</string>
<string name="setting_target_version">Download Version</string>
<string name="setting_dynamic_color">Dynamic color</string>
<string name="setting_hermes_replace_libcpp">Replace libc++ (RN only)</string>
<string name="setting_hermes_replace_libcpp_desc">Downloads and uses libc++ from patched hermes</string>
<string name="setting_keep_patched_apks">Keep patched APKs</string>
<string name="setting_keep_patched_apks_desc">Don\'t delete patched APKs after installing (for installing manually)</string>
<string name="settings_invalid_package_name">Invalid package name, reset to com.aliucord</string>
<string name="theme_system">System</string>
<string name="theme_dark">Dark</string>
<string name="theme_light">Light</string>

View file

@ -35,19 +35,9 @@
<string name="settings_appearance">Tampilan</string>
<string name="settings_developer_options">Opsi Pengembang</string>
<string name="setting_clear_cache">Bersihkan cache</string>
<string name="setting_replace_icon">Ganti ikon aplikasi</string>
<string name="setting_replace_icon_desc">Menggunakan varian Aliucord daripada ikon Discord sendiri</string>
<string name="setting_debuggable">Dapat di-debug</string>
<string name="setting_debuggable_desc">Aktifkan flag debuggable</string>
<string name="setting_app_name">Nama Aplikasi</string>
<string name="setting_package_name">Nama Paket</string>
<string name="setting_target_version">Unduh Versi</string>
<string name="setting_dynamic_color">Warna dinamis</string>
<string name="setting_hermes_replace_libcpp">Gantikan libc++ (Untuk RN)</string>
<string name="setting_hermes_replace_libcpp_desc">Unduh dan pakai libc++ dari hermes yang ditambal</string>
<string name="setting_keep_patched_apks">Simpan APK yang ditambal</string>
<string name="setting_keep_patched_apks_desc">Jangan hapus APK yang sudah ditambal setelah memasang (untuk memasang secara manual)</string>
<string name="settings_invalid_package_name">Nama paket tidak valid, atur ulang ke com.aliucord</string>
<string name="theme_system">Sistem</string>
<string name="theme_dark">Gelap</string>
<string name="theme_light">Terang</string>

View file

@ -35,19 +35,9 @@
<string name="settings_appearance">Aspetto</string>
<string name="settings_developer_options">Opzioni sviluppatore</string>
<string name="setting_clear_cache">Pulisci cache</string>
<string name="setting_replace_icon">Replace app icon</string>
<string name="setting_replace_icon_desc">Uses the Aliucord variant as opposed to Discord\'s own icon</string>
<string name="setting_debuggable">Debuggabile</string>
<string name="setting_debuggable_desc">Enable debuggable flag</string>
<string name="setting_app_name">App Name</string>
<string name="setting_package_name">Package Name</string>
<string name="setting_target_version">Download Version</string>
<string name="setting_dynamic_color">Dynamic color</string>
<string name="setting_hermes_replace_libcpp">Replace libc++ (RN only)</string>
<string name="setting_hermes_replace_libcpp_desc">Downloads and uses libc++ from patched hermes</string>
<string name="setting_keep_patched_apks">Keep patched APKs</string>
<string name="setting_keep_patched_apks_desc">Don\'t delete patched APKs after installing (for installing manually)</string>
<string name="settings_invalid_package_name">Invalid package name, reset to com.aliucord</string>
<string name="theme_system">Sistema</string>
<string name="theme_dark">Scuro</string>
<string name="theme_light">Chiaro</string>

View file

@ -35,19 +35,9 @@
<string name="settings_appearance">Appearance</string>
<string name="settings_developer_options">Developer options</string>
<string name="setting_clear_cache">Clear cache</string>
<string name="setting_replace_icon">Replace app icon</string>
<string name="setting_replace_icon_desc">Uses the Aliucord variant as opposed to Discord\'s own icon</string>
<string name="setting_debuggable">Debuggable</string>
<string name="setting_debuggable_desc">Enable debuggable flag</string>
<string name="setting_app_name">App Name</string>
<string name="setting_package_name">Package Name</string>
<string name="setting_target_version">Download Version</string>
<string name="setting_dynamic_color">Dynamic color</string>
<string name="setting_hermes_replace_libcpp">Replace libc++ (RN only)</string>
<string name="setting_hermes_replace_libcpp_desc">Downloads and uses libc++ from patched hermes</string>
<string name="setting_keep_patched_apks">Keep patched APKs</string>
<string name="setting_keep_patched_apks_desc">Don\'t delete patched APKs after installing (for installing manually)</string>
<string name="settings_invalid_package_name">Invalid package name, reset to com.aliucord</string>
<string name="theme_system">System</string>
<string name="theme_dark">Dark</string>
<string name="theme_light">Light</string>

View file

@ -36,19 +36,9 @@
<string name="settings_appearance">外観</string>
<string name="settings_developer_options">開発者向けオプション</string>
<string name="setting_clear_cache">キャッシュを消去</string>
<string name="setting_replace_icon">アプリのアイコンを置き換える</string>
<string name="setting_replace_icon_desc">DiscordのアイコンではなくAliucordのものを使用します</string>
<string name="setting_debuggable">デバッグ</string>
<string name="setting_debuggable_desc">デバッグ可能フラグを有効にする</string>
<string name="setting_app_name">アプリ名</string>
<string name="setting_package_name">パッケージ名</string>
<string name="setting_target_version">ダウンロードバージョン</string>
<string name="setting_dynamic_color">ダイナミックカラー</string>
<string name="setting_hermes_replace_libcpp">libc++ を置き換え (RN のみ)</string>
<string name="setting_hermes_replace_libcpp_desc">パッチを適用したヘルメスから libc++ をダウンロードして使用します</string>
<string name="setting_keep_patched_apks">パッチを適用した APK を維持</string>
<string name="setting_keep_patched_apks_desc">インストール後にパッチ適用された APK を削除しないでください(手動でインストールする場合)</string>
<string name="settings_invalid_package_name">無効なパッケージ名です。com.aliucordにリセットしてください。</string>
<string name="theme_system">システム</string>
<string name="theme_dark">ダーク</string>
<string name="theme_light">ライト</string>

View file

@ -35,19 +35,9 @@
<string name="settings_appearance">Sırtqı kórinis</string>
<string name="settings_developer_options">Developer options</string>
<string name="setting_clear_cache">Clear cache</string>
<string name="setting_replace_icon">Replace app icon</string>
<string name="setting_replace_icon_desc">Uses the Aliucord variant as opposed to Discord\'s own icon</string>
<string name="setting_debuggable">Debuggable</string>
<string name="setting_debuggable_desc">Enable debuggable flag</string>
<string name="setting_app_name">Qosımsha ataması</string>
<string name="setting_package_name">Package Name</string>
<string name="setting_target_version">Download Version (RN only)</string>
<string name="setting_dynamic_color">Dynamic color</string>
<string name="setting_hermes_replace_libcpp">Replace libc++ (RN only)</string>
<string name="setting_hermes_replace_libcpp_desc">Downloads and uses libc++ from patched hermes</string>
<string name="setting_keep_patched_apks">Keep patched APKs</string>
<string name="setting_keep_patched_apks_desc">Don\'t delete patched APKs after installing (for installing manually)</string>
<string name="settings_invalid_package_name">Invalid package name, reset to com.aliucord</string>
<string name="theme_system">System</string>
<string name="theme_dark">Qarańǵı</string>
<string name="theme_light">Jaqtı</string>

View file

@ -35,19 +35,9 @@
<string name="settings_appearance">외관</string>
<string name="settings_developer_options">개발자 옵션</string>
<string name="setting_clear_cache">캐시 지우기</string>
<string name="setting_replace_icon">앱 아이콘 재배치</string>
<string name="setting_replace_icon_desc">Discord의 아이콘 대신 Aliucord의 아이콘을 사용해요</string>
<string name="setting_debuggable">디버그 가능</string>
<string name="setting_debuggable_desc">디버그 가능 플래그를 사용해요</string>
<string name="setting_app_name">앱 이름</string>
<string name="setting_package_name">패키지 이름</string>
<string name="setting_target_version">다운로드 버전</string>
<string name="setting_dynamic_color">동적 색상</string>
<string name="setting_hermes_replace_libcpp">libc++ 대체(RN 전용)</string>
<string name="setting_hermes_replace_libcpp_desc">패치한 Herms에서 libc++를 다운로드하고 사용해요</string>
<string name="setting_keep_patched_apks">패치된 APK 유지</string>
<string name="setting_keep_patched_apks_desc">설치 후 패치된 APK를 삭제하지 않아요 (수동 설치용)</string>
<string name="settings_invalid_package_name">잘못된 패키지 이름이에요. com.aliucord로 초기화할게요</string>
<string name="theme_system">시스템</string>
<string name="theme_dark">어두운 테마</string>
<string name="theme_light">밝은 테마</string>

View file

@ -35,19 +35,9 @@
<string name="settings_appearance">Appearance</string>
<string name="settings_developer_options">Developer options</string>
<string name="setting_clear_cache">Clear cache</string>
<string name="setting_replace_icon">Replace app icon</string>
<string name="setting_replace_icon_desc">Uses the Aliucord variant as opposed to Discord\'s own icon</string>
<string name="setting_debuggable">Debuggable</string>
<string name="setting_debuggable_desc">Enable debuggable flag</string>
<string name="setting_app_name">App Name</string>
<string name="setting_package_name">Package Name</string>
<string name="setting_target_version">Download Versie (Alleen RN)</string>
<string name="setting_dynamic_color">Dynamic color</string>
<string name="setting_hermes_replace_libcpp">Replace libc++ (RN only)</string>
<string name="setting_hermes_replace_libcpp_desc">Downloads and uses libc++ from patched hermes</string>
<string name="setting_keep_patched_apks">Keep patched APKs</string>
<string name="setting_keep_patched_apks_desc">Don\'t delete patched APKs after installing (for installing manually)</string>
<string name="settings_invalid_package_name">Invalid package name, reset to com.aliucord</string>
<string name="theme_system">System</string>
<string name="theme_dark">Dark</string>
<string name="theme_light">Light</string>

View file

@ -35,19 +35,9 @@
<string name="settings_appearance">Appearance</string>
<string name="settings_developer_options">Developer options</string>
<string name="setting_clear_cache">Clear cache</string>
<string name="setting_replace_icon">Replace app icon</string>
<string name="setting_replace_icon_desc">Uses the Aliucord variant as opposed to Discord\'s own icon</string>
<string name="setting_debuggable">Debuggable</string>
<string name="setting_debuggable_desc">Enable debuggable flag</string>
<string name="setting_app_name">App Name</string>
<string name="setting_package_name">Package Name</string>
<string name="setting_target_version">Download Version</string>
<string name="setting_dynamic_color">Dynamic color</string>
<string name="setting_hermes_replace_libcpp">Replace libc++ (RN only)</string>
<string name="setting_hermes_replace_libcpp_desc">Downloads and uses libc++ from patched hermes</string>
<string name="setting_keep_patched_apks">Keep patched APKs</string>
<string name="setting_keep_patched_apks_desc">Don\'t delete patched APKs after installing (for installing manually)</string>
<string name="settings_invalid_package_name">Invalid package name, reset to com.aliucord</string>
<string name="theme_system">System</string>
<string name="theme_dark">Dark</string>
<string name="theme_light">Light</string>

View file

@ -35,19 +35,9 @@
<string name="settings_appearance">Wygląd</string>
<string name="settings_developer_options">Opcje dla programistów</string>
<string name="setting_clear_cache">Wyczyść pamięć podręczną</string>
<string name="setting_replace_icon">Zastąp ikonę aplikacji</string>
<string name="setting_replace_icon_desc">Używa wariantu Aliucord w przeciwieństwie do ikony Discorda</string>
<string name="setting_debuggable">Debugowalny</string>
<string name="setting_debuggable_desc">Włącz flagę debugowania</string>
<string name="setting_app_name">Nazwa aplikacji</string>
<string name="setting_package_name">Nazwa pakietu</string>
<string name="setting_target_version">Wersja do pobrania</string>
<string name="setting_dynamic_color">Kolor dynamiczny</string>
<string name="setting_hermes_replace_libcpp">Zastąp libc++ (tylko RN)</string>
<string name="setting_hermes_replace_libcpp_desc">Downloads and uses libc++ from patched hermes</string>
<string name="setting_keep_patched_apks">Zachowaj zpatchowane APK</string>
<string name="setting_keep_patched_apks_desc">Nie usuwaj skasowanych APK po instalacji (dla instalacji ręcznej)</string>
<string name="settings_invalid_package_name">Nieprawidłowa nazwa pakietu, przywrócono do com.aliucord</string>
<string name="theme_system">System</string>
<string name="theme_dark">Ciemny</string>
<string name="theme_light">Jasny</string>

View file

@ -35,19 +35,9 @@
<string name="settings_appearance">Aparência</string>
<string name="settings_developer_options">Opções de desenvolvedor</string>
<string name="setting_clear_cache">Limpar cache</string>
<string name="setting_replace_icon">Mudar ícone do aplicativo</string>
<string name="setting_replace_icon_desc">Usa a logo do Aliucord ao invés do próprio ícone do Discord</string>
<string name="setting_debuggable">Depurável</string>
<string name="setting_debuggable_desc">Habilitar sinal de depurável</string>
<string name="setting_app_name">Nome do App</string>
<string name="setting_package_name">Nome do pacote</string>
<string name="setting_target_version">Versão para download</string>
<string name="setting_dynamic_color">Cor dinâmica</string>
<string name="setting_hermes_replace_libcpp">Substituir libc++ (apenas RN)</string>
<string name="setting_hermes_replace_libcpp_desc">Baixa e usa libc++ do pacote hermes</string>
<string name="setting_keep_patched_apks">Manter APKs patched</string>
<string name="setting_keep_patched_apks_desc">Não excluir APKs patched após a instalação (para instalação manualmente)</string>
<string name="settings_invalid_package_name">Nome do pacote inválido, resetar para com.aliucord</string>
<string name="theme_system">Sistema</string>
<string name="theme_dark">Escuro</string>
<string name="theme_light">Claro</string>

View file

@ -35,19 +35,9 @@
<string name="settings_appearance">Aparência</string>
<string name="settings_developer_options">Opções de programador</string>
<string name="setting_clear_cache">Limpar cache</string>
<string name="setting_replace_icon">Substituir ícone da aplicação </string>
<string name="setting_replace_icon_desc">Uses the Aliucord variant as opposed to Discord\'s own icon</string>
<string name="setting_debuggable">Debuggable</string>
<string name="setting_debuggable_desc">Enable debuggable flag</string>
<string name="setting_app_name">Nome da aplicação</string>
<string name="setting_package_name">Package Name</string>
<string name="setting_target_version">Download Version</string>
<string name="setting_dynamic_color">Cor dinâmica</string>
<string name="setting_hermes_replace_libcpp">Replace libc++ (RN only)</string>
<string name="setting_hermes_replace_libcpp_desc">Downloads and uses libc++ from patched hermes</string>
<string name="setting_keep_patched_apks">Keep patched APKs</string>
<string name="setting_keep_patched_apks_desc">Não apague APKs modificados após a sua instalação (para instalação manualmente)</string>
<string name="settings_invalid_package_name">Invalid package name, reset to com.aliucord</string>
<string name="theme_system">Sistema</string>
<string name="theme_dark">Escuro</string>
<string name="theme_light">Claro</string>

View file

@ -35,19 +35,9 @@
<string name="settings_appearance">Appearance</string>
<string name="settings_developer_options">Developer options</string>
<string name="setting_clear_cache">Clear cache</string>
<string name="setting_replace_icon">Replace app icon</string>
<string name="setting_replace_icon_desc">Uses the Aliucord variant as opposed to Discord\'s own icon</string>
<string name="setting_debuggable">Debuggable</string>
<string name="setting_debuggable_desc">Enable debuggable flag</string>
<string name="setting_app_name">App Name</string>
<string name="setting_package_name">Package Name</string>
<string name="setting_target_version">Download Version</string>
<string name="setting_dynamic_color">Dynamic color</string>
<string name="setting_hermes_replace_libcpp">Replace libc++ (RN only)</string>
<string name="setting_hermes_replace_libcpp_desc">Downloads and uses libc++ from patched hermes</string>
<string name="setting_keep_patched_apks">Keep patched APKs</string>
<string name="setting_keep_patched_apks_desc">Don\'t delete patched APKs after installing (for installing manually)</string>
<string name="settings_invalid_package_name">Invalid package name, reset to com.aliucord</string>
<string name="theme_system">System</string>
<string name="theme_dark">Dark</string>
<string name="theme_light">Light</string>

View file

@ -35,19 +35,9 @@
<string name="settings_appearance">Внешний вид</string>
<string name="settings_developer_options">Настройки для разработчиков</string>
<string name="setting_clear_cache">Очистить кеш</string>
<string name="setting_replace_icon">Заменить иконку приложения</string>
<string name="setting_replace_icon_desc">Использовать вариант Aliucord вместо Discord</string>
<string name="setting_debuggable">Отладка</string>
<string name="setting_debuggable_desc">Включение флага для откладки</string>
<string name="setting_app_name">Название приложения</string>
<string name="setting_package_name">Название пакета</string>
<string name="setting_target_version">Загружаемая версия</string>
<string name="setting_dynamic_color">Динамические цвета</string>
<string name="setting_hermes_replace_libcpp">Заменить libc++ (только RN)</string>
<string name="setting_hermes_replace_libcpp_desc">Скачивает и использует libc++ из пропатченного hermes</string>
<string name="setting_keep_patched_apks">Сохранять пропатченные пакеты</string>
<string name="setting_keep_patched_apks_desc">Не удалять пропатченные пакеты после установки (для ручной установки)</string>
<string name="settings_invalid_package_name">Неправильное название пакета, сброс на com.aliucord</string>
<string name="theme_system">Системная</string>
<string name="theme_dark">Тёмная</string>
<string name="theme_light">Светлая</string>

View file

@ -35,19 +35,9 @@
<string name="settings_appearance">Appearance</string>
<string name="settings_developer_options">Developer options</string>
<string name="setting_clear_cache">Clear cache</string>
<string name="setting_replace_icon">Replace app icon</string>
<string name="setting_replace_icon_desc">Uses the Aliucord variant as opposed to Discord\'s own icon</string>
<string name="setting_debuggable">Debuggable</string>
<string name="setting_debuggable_desc">Enable debuggable flag</string>
<string name="setting_app_name">App Name</string>
<string name="setting_package_name">Package Name</string>
<string name="setting_target_version">Download Version</string>
<string name="setting_dynamic_color">Dynamic color</string>
<string name="setting_hermes_replace_libcpp">Replace libc++ (RN only)</string>
<string name="setting_hermes_replace_libcpp_desc">Downloads and uses libc++ from patched hermes</string>
<string name="setting_keep_patched_apks">Keep patched APKs</string>
<string name="setting_keep_patched_apks_desc">Don\'t delete patched APKs after installing (for installing manually)</string>
<string name="settings_invalid_package_name">Invalid package name, reset to com.aliucord</string>
<string name="theme_system">System</string>
<string name="theme_dark">Dark</string>
<string name="theme_light">Light</string>

View file

@ -35,19 +35,9 @@
<string name="settings_appearance">Appearance</string>
<string name="settings_developer_options">Developer options</string>
<string name="setting_clear_cache">Clear cache</string>
<string name="setting_replace_icon">Replace app icon</string>
<string name="setting_replace_icon_desc">Uses the Aliucord variant as opposed to Discord\'s own icon</string>
<string name="setting_debuggable">Debuggable</string>
<string name="setting_debuggable_desc">Enable debuggable flag</string>
<string name="setting_app_name">App Name</string>
<string name="setting_package_name">Package Name</string>
<string name="setting_target_version">Download Version</string>
<string name="setting_dynamic_color">Dynamic color</string>
<string name="setting_hermes_replace_libcpp">Replace libc++ (RN only)</string>
<string name="setting_hermes_replace_libcpp_desc">Downloads and uses libc++ from patched hermes</string>
<string name="setting_keep_patched_apks">Keep patched APKs</string>
<string name="setting_keep_patched_apks_desc">Don\'t delete patched APKs after installing (for installing manually)</string>
<string name="settings_invalid_package_name">Invalid package name, reset to com.aliucord</string>
<string name="theme_system">System</string>
<string name="theme_dark">Dark</string>
<string name="theme_light">Light</string>

View file

@ -35,19 +35,9 @@
<string name="settings_appearance">Görünüm</string>
<string name="settings_developer_options">Geliştirici seçenekleri</string>
<string name="setting_clear_cache">Önbelleği temizle</string>
<string name="setting_replace_icon">Uygulama simgesini değiştir</string>
<string name="setting_replace_icon_desc">Discord\'un simgesi yerine Aliucord varyant\'ını kullanır</string>
<string name="setting_debuggable">Hata ayıklanabilir</string>
<string name="setting_debuggable_desc">Hata ayıklanabilir seçeneğini etkinleştir</string>
<string name="setting_app_name">Uygulama Adı</string>
<string name="setting_package_name">Paket İsmi</string>
<string name="setting_target_version">Sürümü İndir</string>
<string name="setting_dynamic_color">Dinamik renk</string>
<string name="setting_hermes_replace_libcpp">Replace libc++ (RN only)</string>
<string name="setting_hermes_replace_libcpp_desc">Downloads and uses libc++ from patched hermes</string>
<string name="setting_keep_patched_apks">Keep patched APKs</string>
<string name="setting_keep_patched_apks_desc">Don\'t delete patched APKs after installing (for installing manually)</string>
<string name="settings_invalid_package_name">Geçersiz paket ismi, com.aliucord\'a sıfırlayın</string>
<string name="theme_system">Sistem</string>
<string name="theme_dark">Koyu</string>
<string name="theme_light">Açık</string>

View file

@ -35,19 +35,9 @@
<string name="settings_appearance">Appearance</string>
<string name="settings_developer_options">Developer options</string>
<string name="setting_clear_cache">Clear cache</string>
<string name="setting_replace_icon">Replace app icon</string>
<string name="setting_replace_icon_desc">Uses the Aliucord variant as opposed to Discord\'s own icon</string>
<string name="setting_debuggable">Debuggable</string>
<string name="setting_debuggable_desc">Enable debuggable flag</string>
<string name="setting_app_name">App Name</string>
<string name="setting_package_name">Package Name</string>
<string name="setting_target_version">Download Version</string>
<string name="setting_dynamic_color">Dynamic color</string>
<string name="setting_hermes_replace_libcpp">Replace libc++ (RN only)</string>
<string name="setting_hermes_replace_libcpp_desc">Downloads and uses libc++ from patched hermes</string>
<string name="setting_keep_patched_apks">Keep patched APKs</string>
<string name="setting_keep_patched_apks_desc">Don\'t delete patched APKs after installing (for installing manually)</string>
<string name="settings_invalid_package_name">Invalid package name, reset to com.aliucord</string>
<string name="theme_system">System</string>
<string name="theme_dark">Dark</string>
<string name="theme_light">Light</string>

View file

@ -35,19 +35,9 @@
<string name="settings_appearance">Giao diện</string>
<string name="settings_developer_options">Tùy chọn nhà phát triển</string>
<string name="setting_clear_cache">Xoá bộ nhớ đệm</string>
<string name="setting_replace_icon">Thay thế biểu tượng ứng dụng</string>
<string name="setting_replace_icon_desc">Sử dụng biểu tượng Aliucord thay thế biểu tượng riêng của Discord</string>
<string name="setting_debuggable">Gỡ lỗi</string>
<string name="setting_debuggable_desc">Kích hoạt tùy chọn gỡ lỗi</string>
<string name="setting_app_name">Tên ứng dụng</string>
<string name="setting_package_name">Tên gói</string>
<string name="setting_target_version">Tải xuống phiên bản</string>
<string name="setting_dynamic_color">Màu động</string>
<string name="setting_hermes_replace_libcpp">Thay thế libc++ (Dành cho RN)</string>
<string name="setting_hermes_replace_libcpp_desc">Tải xuống và sử dụng libc++ từ hermes</string>
<string name="setting_keep_patched_apks">Giữ lại các bản vá APKs</string>
<string name="setting_keep_patched_apks_desc">Không xóa bỏ các bản vá APKs sau khi cài đặt (dành cho cài đặt thủ công)</string>
<string name="settings_invalid_package_name">Tên gói không hợp lệ, đặt lại thành com.aliucord</string>
<string name="theme_system">Hệ thống</string>
<string name="theme_dark">Tối</string>
<string name="theme_light">Sáng</string>

View file

@ -35,19 +35,9 @@
<string name="settings_appearance">外觀</string>
<string name="settings_developer_options">開發人員選項</string>
<string name="setting_clear_cache">清除快取</string>
<string name="setting_replace_icon">更換應用程示圖示</string>
<string name="setting_replace_icon_desc">使用 Aliucord 樣式而不是 Discord 自己的圖示</string>
<string name="setting_debuggable">除錯</string>
<string name="setting_debuggable_desc">開啟除錯模式</string>
<string name="setting_app_name">應用程式名稱</string>
<string name="setting_package_name">Package 名稱</string>
<string name="setting_target_version">下載版本</string>
<string name="setting_dynamic_color">動態色彩</string>
<string name="setting_hermes_replace_libcpp">代替 libc++(僅限 RN)</string>
<string name="setting_hermes_replace_libcpp_desc">從安裝補丁的 hermes 下載並使用 libc++</string>
<string name="setting_keep_patched_apks">保持補丁 APKs</string>
<string name="setting_keep_patched_apks_desc">安裝後不刪除已安裝補丁的 APK(用於手動安裝)</string>
<string name="settings_invalid_package_name">無效的 Package 名稱,將重設為 com.aliucord</string>
<string name="theme_system">跟隨系統</string>
<string name="theme_dark">深色模式</string>
<string name="theme_light">淺色模式</string>

View file

@ -35,19 +35,9 @@
<string name="settings_appearance">外觀</string>
<string name="settings_developer_options">開發人員選項</string>
<string name="setting_clear_cache">清除快取</string>
<string name="setting_replace_icon">更換應用程示圖示</string>
<string name="setting_replace_icon_desc">使用 Aliucord 樣式而不是 Discord 自己的圖示</string>
<string name="setting_debuggable">除錯</string>
<string name="setting_debuggable_desc">開啟除錯模式</string>
<string name="setting_app_name">應用程式名稱</string>
<string name="setting_package_name">Package 名稱</string>
<string name="setting_target_version">下載版本</string>
<string name="setting_dynamic_color">動態色彩</string>
<string name="setting_hermes_replace_libcpp">代替 libc++(僅限 RN)</string>
<string name="setting_hermes_replace_libcpp_desc">從安裝補丁的 hermes 下載並使用 libc++</string>
<string name="setting_keep_patched_apks">保持補丁 APKs</string>
<string name="setting_keep_patched_apks_desc">安裝後不刪除已安裝補丁的 APK(用於手動安裝)</string>
<string name="settings_invalid_package_name">無效的 Package 名稱,將重設為 com.aliucord</string>
<string name="theme_system">跟隨系統</string>
<string name="theme_dark">深色模式</string>
<string name="theme_light">淺色模式</string>

View file

@ -13,11 +13,12 @@
<string name="action_apply">Apply</string>
<string name="action_confirm">Confirm</string>
<string name="action_dismiss">Dismiss</string>
<string name="action_install">Install</string>
<string name="action_uninstall">Uninstall</string>
<string name="action_add_install">Add Installation</string>
<string name="action_update">Update</string>
<string name="action_clear">Clear</string>
<string name="action_launch">Launch</string>
<string name="action_uninstall">Uninstall</string>
<string name="action_close">Close</string>
<string name="action_open_settings">Open settings</string>
<string name="action_search">Search</string>
@ -28,6 +29,7 @@
<string name="action_cleared_cache">Cleared cache!</string>
<string name="action_exit_anyways">Exit anyways</string>
<string name="action_open_info">Open info</string>
<string name="action_reset_default">Reset to default</string>
<string name="permissions_grant_title">Grant Permissions</string>
<string name="permissions_grant_body">In order for Aliucord Manager to function, file permissions are required. Since shared data is stored in ~/Aliucord, permissions are required in order to access it.</string>
@ -39,19 +41,9 @@
<string name="settings_appearance">Appearance</string>
<string name="settings_developer_options">Developer options</string>
<string name="setting_clear_cache">Clear cache</string>
<string name="setting_replace_icon">Replace app icon</string>
<string name="setting_replace_icon_desc">Uses the Aliucord variant as opposed to Discord\'s own icon</string>
<string name="setting_debuggable">Debuggable</string>
<string name="setting_debuggable_desc">Enable debuggable flag</string>
<string name="setting_app_name">App Name</string>
<string name="setting_package_name">Package Name</string>
<string name="setting_target_version">Download Version (RN only)</string>
<string name="setting_dynamic_color">Dynamic color</string>
<string name="setting_hermes_replace_libcpp">Replace libc++ (RN only)</string>
<string name="setting_hermes_replace_libcpp_desc">Downloads and uses libc++ from patched hermes</string>
<string name="setting_keep_patched_apks">Keep patched APKs</string>
<string name="setting_keep_patched_apks_desc">Don\'t delete patched APKs after installing (for installing manually)</string>
<string name="settings_invalid_package_name">Invalid package name, reset to com.aliucord</string>
<string name="theme_system">System</string>
<string name="theme_dark">Dark</string>
@ -114,6 +106,7 @@
<string name="install_step_dl_aliuhook">Downloading Aliuhook library</string>
<string name="install_step_copy">Copying dependencies</string>
<string name="install_step_patch_manifests">Patching apk manifests</string>
<string name="install_step_patch_icon">Patching app icon</string>
<string name="install_step_add_injector">Adding Aliucord injector</string>
<string name="install_step_add_aliuhook">Adding Aliuhook library</string>
<string name="install_step_alignment">Aligning APKs</string>
@ -137,4 +130,19 @@
<string name="downloader_err_response">Download failed (Invalid response)</string>
<string name="downloader_err_file_exists">Download failed (File exists)</string>
<string name="downloader_err_storage_space">Download failed (Insufficient space)</string>
<string name="installopts_title">Aliucord provides several customizations at installation time that are not able to be changed once installed.</string>
<string name="installopts_pkgname_title">Package Name</string>
<string name="installopts_pkgname_desc">The package name is a unique identifier for all apps. Using different ones can allow for multiple installations of Aliucord.</string>
<string name="installopts_pkgname_invalid">Invalid package name!</string>
<string name="installopts_pkgname_taken">Target app will be overwritten!</string>
<string name="installopts_pkgname_ok">Valid package name!</string>
<string name="installopts_appname_title">App Name</string>
<string name="installopts_appname_desc">The app name is what\'s displayed in your home launcher. This should be changed on secondary installations for ease of use.</string>
<string name="installopts_debuggable_title">Debuggable</string>
<string name="installopts_debuggable_desc">Enable the debuggable manifest flag. Only use this if you know what you are doing!</string>
<string name="installopts_icon_title">Replace app icon</string>
<string name="installopts_icon_desc">Changes the app\'s icon to use Aliucord branding instead of Discord\'s own.</string>
<string name="installopts_divider_basic">Basic</string>
<string name="installopts_divider_advanced">Advanced</string>
</resources>