Skip to content

Commit

Permalink
feat: 添加修改语言的功能
Browse files Browse the repository at this point in the history
  • Loading branch information
jixiaoyong committed Mar 31, 2024
1 parent a52e8a6 commit a74cd08
Show file tree
Hide file tree
Showing 15 changed files with 227 additions and 157 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,9 @@ APK 文件。
- [ ] 导入多个签名文件
- [x] 自动保存/匹配 APK 对应的签名信息
- [ ] 优化签名配置
- [ ] 美化主题
- [x] 美化主题
- [ ] 添加查看日志功能
- [ ] 支持国际化语言 🚧进行中
- [x] 支持国际化语言,可自动识别系统语言

## 界面预览

Expand Down
6 changes: 6 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ repositories {
google()
maven("https://jitpack.io")
}

ksp {
arg("lyricist.generateStringsProperty", "true")

}

val multiplatformSettings = "1.1.1"
val lyricist = "1.6.2-1.8.20"
dependencies {
Expand Down
84 changes: 46 additions & 38 deletions src/main/kotlin/Main.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,23 @@ import androidx.compose.ui.window.Window
import androidx.compose.ui.window.application
import androidx.compose.ui.window.rememberWindowState
import cafe.adriel.lyricist.Lyricist
import cafe.adriel.lyricist.ProvideStrings
import cafe.adriel.lyricist.rememberStrings
import cafe.adriel.lyricist.strings
import io.github.jixiaoyong.beans.AppState
import io.github.jixiaoyong.i18n.EnStrings
import io.github.jixiaoyong.i18n.Locales
import io.github.jixiaoyong.i18n.Strings
import io.github.jixiaoyong.i18n.ZhStrings
import io.github.jixiaoyong.pages.App
import io.github.jixiaoyong.utils.AppProcessUtil
import io.github.jixiaoyong.utils.SettingsTool
import io.github.jixiaoyong.widgets.ButtonWidget
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.util.*
import kotlin.system.exitProcess

val LocalWindow = compositionLocalOf<ComposeWindow> { error("No Window provided") }
val LocalSettings = compositionLocalOf<SettingsTool> { error("No SettingsTool provided") }
val LocalI18nStrings = compositionLocalOf<Lyricist<Strings>> { error("No SettingsTool provided") }
val LocalLyricist = compositionLocalOf<Lyricist<Strings>> { error("No SettingsTool provided") }

fun main() =
application {
Expand All @@ -47,43 +47,53 @@ fun main() =
) {
var appState by remember { mutableStateOf<AppState>(AppState.Idle) }
var checkDualRunning by remember { mutableStateOf(true) }
val settingsTool = SettingsTool(scope = rememberCoroutineScope())
val stringsLyricist = rememberStrings()

val lyricist = rememberStrings(mapOf(Locales.ZH to ZhStrings, Locales.EN to EnStrings))
// app语言:优先用户选择的,其次系统默认的,其次英文
val systemLanguage = Locale.getDefault().language
val language by settingsTool.language.collectAsState(systemLanguage)
if (null != language) {
stringsLyricist.languageTag = language.toString()
}

LaunchedEffect(Unit) {
window.minimumSize = window.size
}
CompositionLocalProvider(
LocalWindow provides window,
LocalSettings provides SettingsTool(scope = rememberCoroutineScope()),
LocalI18nStrings provides lyricist
) {
LaunchedEffect(checkDualRunning) {
appState = AppState.Loading
val isAppRunning = withContext(Dispatchers.IO) {
AppProcessUtil.isDualAppRunning("ApkSigner")
}
appState =
if (isAppRunning) {
AppState.AlreadyExists
} else {
AppState.Success
}
}
ProvideStrings(stringsLyricist) {
CompositionLocalProvider(
LocalWindow provides window,
LocalSettings provides settingsTool,
LocalLyricist provides stringsLyricist
) {

when (appState) {
is AppState.Idle, AppState.Loading -> {
LoadingPage()
LaunchedEffect(checkDualRunning) {
appState = AppState.Loading
val isAppRunning = withContext(Dispatchers.IO) {
AppProcessUtil.isDualAppRunning("ApkSigner")
}
appState =
if (isAppRunning) {
AppState.AlreadyExists
} else {
AppState.Success
}
}

is AppState.AlreadyExists -> {
AlreadyExistsPage {
checkDualRunning = !checkDualRunning
when (appState) {
is AppState.Idle, AppState.Loading -> {
LoadingPage()
}

is AppState.AlreadyExists -> {
AlreadyExistsPage {
checkDualRunning = !checkDualRunning
}
}
}

AppState.Success -> {
App()
AppState.Success -> {
App()
}
}
}
}
Expand All @@ -98,20 +108,18 @@ fun LoadingPage() {
verticalArrangement = Arrangement.Center,
) {
CircularProgressIndicator()
Text(LocalI18nStrings.current.strings.loading, Modifier.padding(top = 10.dp))
Text(strings.loading, Modifier.padding(top = 10.dp))
}
}

@Composable
fun AlreadyExistsPage(tryAgainFunc: () -> Unit) {
val i18nString = LocalI18nStrings.current.strings
Box(
modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.Center,
) {
Column(
modifier =
Modifier.widthIn(300.dp).heightIn(200.dp).background(
modifier = Modifier.widthIn(300.dp).heightIn(200.dp).background(
MaterialTheme.colors.surface.copy(0.8f),
RoundedCornerShape(10.dp),
),
Expand All @@ -124,13 +132,13 @@ fun AlreadyExistsPage(tryAgainFunc: () -> Unit) {
contentDescription = "already exists",
modifier = Modifier.size(50.dp),
)
Text(i18nString.alreadyRunning, Modifier.padding(vertical = 20.dp))
Text(strings.alreadyRunning, Modifier.padding(vertical = 20.dp))
Row {
ButtonWidget(onClick = { exitProcess(0) }) {
Text(i18nString.exit)
Text(strings.exit)
}
ButtonWidget(onClick = tryAgainFunc) {
Text(i18nString.retry)
Text(strings.retry)
}
}
}
Expand Down
26 changes: 25 additions & 1 deletion src/main/kotlin/io/github/jixiaoyong/i18n/Locales.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,36 @@ package io.github.jixiaoyong.i18n

/**
* @author : jixiaoyong
* @description :TODO
* @description :每次更新语言都必须同步更新下面两个类
*
* @email : jixiaoyong1995@gmail.com
* @date : 30/3/2024
*/

object Locales {
const val EN = "en"
const val ZH = "zh"
}

enum class Locale(val code: String, val languageName: String) {
EN(Locales.EN, "English"),
ZH(Locales.ZH, "中文 | Chinese");

companion object {
fun getLocale(code: String?): Locale {
return if (null == code) EN
else if (code.areLanguagesEqual(Locales.ZH)) ZH
else EN
}
}
}

fun String.areLanguagesEqual(otherLang: String): Boolean {
if (this == otherLang) {
return true
}

val locale1 = java.util.Locale.forLanguageTag(this)
val locale2 = java.util.Locale.forLanguageTag(otherLang)
return locale1.language == locale2.language
}
6 changes: 4 additions & 2 deletions src/main/kotlin/io/github/jixiaoyong/i18n/StringEn.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import cafe.adriel.lyricist.LyricistStrings
* @email : jixiaoyong1995@gmail.com
* @date : 30/3/2024
*/
@LyricistStrings(languageTag = Locales.EN)
@LyricistStrings(languageTag = Locales.EN, default = true)
internal val EnStrings = Strings(
loading = "Loading...",
alreadyRunning = "Apk Signer has been started, please do not start it again.",
Expand Down Expand Up @@ -78,7 +78,9 @@ internal val EnStrings = Strings(
open = "Open",
signedFailed = "Signing failed: ",
copyErrorMsg = "Copy error message",
startSignApk = "Start signing apk"
startSignApk = "Start signing apk",
changeLanguage = "Modify language",
currentLanguageTitle = "Languages"
)

//internal val EnStrings = Strings(
Expand Down
6 changes: 4 additions & 2 deletions src/main/kotlin/io/github/jixiaoyong/i18n/StringZh.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import cafe.adriel.lyricist.LyricistStrings
* @email : jixiaoyong1995@gmail.com
* @date : 30/3/2024
*/
@LyricistStrings(languageTag = Locales.ZH, default = true)
@LyricistStrings(languageTag = Locales.ZH)
internal val ZhStrings = Strings(
loading = "加载中……",
alreadyRunning = "ApkSigner已经启动了,请不要重复启动",
Expand Down Expand Up @@ -78,5 +78,7 @@ internal val ZhStrings = Strings(
open = "打开",
signedFailed = "签名失败,:",
copyErrorMsg = "复制错误信息",
startSignApk = "开始签名apk"
startSignApk = "开始签名apk",
changeLanguage = "修改语言",
currentLanguageTitle = "语言"
)
4 changes: 3 additions & 1 deletion src/main/kotlin/io/github/jixiaoyong/i18n/Strings.kt
Original file line number Diff line number Diff line change
Expand Up @@ -72,5 +72,7 @@ data class Strings(
val open:String,
val signedFailed:String,
val copyErrorMsg:String,
val startSignApk:String
val startSignApk:String,
val changeLanguage:String,
val currentLanguageTitle:String,
)
50 changes: 25 additions & 25 deletions src/main/kotlin/io/github/jixiaoyong/pages/MainPage.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package io.github.jixiaoyong.pages

import LocalI18nStrings
import LocalSettings
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
Expand All @@ -9,11 +8,16 @@ import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Icon
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.List
import androidx.compose.material.icons.filled.Lock
import androidx.compose.material.icons.filled.Settings
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import cafe.adriel.lyricist.strings
import com.jthemedetecor.OsThemeDetector
import io.github.jixiaoyong.base.viewModel
import io.github.jixiaoyong.pages.settings.PageSettingInfo
Expand All @@ -36,10 +40,15 @@ import kotlinx.coroutines.launch
@Composable
fun App() {
val settings = LocalSettings.current
val i18nString = LocalI18nStrings.current

val scope = rememberCoroutineScope()
val viewModel = viewModel { MainViewModel(settings, i18nString.strings) }
val viewModel = viewModel { MainViewModel(settings) }

val routes = listOf(
Triple(Icons.Default.List, strings.signConfig, Routes.SignInfo),
Triple(Icons.Default.Lock, strings.signApp, Routes.SignApp),
Triple(Icons.Default.Settings, strings.settingsConfig, Routes.SettingInfo),
)

var isDarkTheme by viewModel.isDarkTheme
val pageIndex by viewModel.currentIndex.collectAsState()
Expand Down Expand Up @@ -72,30 +81,22 @@ fun App() {
AppTheme(darkTheme = isDarkTheme) {
Column(modifier = Modifier.fillMaxSize()) {
Row(
modifier =
Modifier.fillMaxWidth()
.heightIn(min = 65.dp)
.background(MaterialTheme.colors.secondaryVariant)
.padding(horizontal = 2.dp),
modifier = Modifier.fillMaxWidth().heightIn(min = 65.dp)
.background(MaterialTheme.colors.secondaryVariant).padding(horizontal = 2.dp),
horizontalArrangement = Arrangement.SpaceEvenly,
verticalAlignment = Alignment.CenterVertically,
) {
for (route in viewModel.routes) {
for (route in routes) {
val isActive = route.third == pageIndex
val backgroundColor =
if (isActive) {
MaterialTheme.colors.secondary
} else {
Color.Transparent
}
val backgroundColor = if (isActive) {
MaterialTheme.colors.secondary
} else {
Color.Transparent
}

Row(
modifier =
Modifier
.weight(1f)
.padding(horizontal = 1.dp)
.background(backgroundColor, RoundedCornerShape(5.dp))
.clickable {
modifier = Modifier.weight(1f).padding(horizontal = 1.dp)
.background(backgroundColor, RoundedCornerShape(5.dp)).clickable {
viewModel.changePage(route.third)
}.padding(vertical = 15.dp),
horizontalArrangement = Arrangement.Center,
Expand All @@ -115,10 +116,9 @@ fun App() {
when (pageIndex) {
Routes.SignInfo -> PageSignInfo(signInfoViewModel)

Routes.SignApp ->
PageSignApp(signAppViewModel) { route ->
viewModel.changePage(route)
}
Routes.SignApp -> PageSignApp(signAppViewModel) { route ->
viewModel.changePage(route)
}

Routes.SettingInfo -> PageSettingInfo()
}
Expand Down
13 changes: 1 addition & 12 deletions src/main/kotlin/io/github/jixiaoyong/pages/MainViewModel.kt
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
package io.github.jixiaoyong.pages

import ApkSigner
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.List
import androidx.compose.material.icons.filled.Lock
import androidx.compose.material.icons.filled.Settings
import androidx.compose.runtime.mutableStateOf
import io.github.jixiaoyong.base.BaseViewModel
import io.github.jixiaoyong.i18n.Strings
import io.github.jixiaoyong.utils.SettingsTool
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
Expand All @@ -21,13 +16,7 @@ import kotlinx.coroutines.launch
* @email : jixiaoyong1995@gmail.com
* @date : 25/3/2024
*/
class MainViewModel(private val settings: SettingsTool, i18nString: Strings) : BaseViewModel() {
val routes =
listOf(
Triple(Icons.Default.List, i18nString.signConfig, Routes.SignInfo),
Triple(Icons.Default.Lock, i18nString.signApp, Routes.SignApp),
Triple(Icons.Default.Settings, i18nString.settingsConfig, Routes.SettingInfo),
)
class MainViewModel(private val settings: SettingsTool) : BaseViewModel() {

val currentIndex = MutableStateFlow(Routes.SignInfo)
val isDarkTheme = mutableStateOf(false)
Expand Down

0 comments on commit a74cd08

Please sign in to comment.