Add german localization (#60)
This commit is contained in:
parent
b038641326
commit
4c5b6aac15
@ -72,7 +72,7 @@ tasks.register("generateManifest") {
|
|||||||
"latestVersionCode" to android.defaultConfig.versionCode,
|
"latestVersionCode" to android.defaultConfig.versionCode,
|
||||||
"developer" to "github.com/timklge",
|
"developer" to "github.com/timklge",
|
||||||
"description" to "Open-source extension that adds colored power or heart rate progress bars to the edges of the screen, similar to the LEDs on Wahoo computers",
|
"description" to "Open-source extension that adds colored power or heart rate progress bars to the edges of the screen, similar to the LEDs on Wahoo computers",
|
||||||
"releaseNotes" to "* Add gear data sources\n* Show zero value on bars to indicate sensor availability\n* Fix pedal balance values\n* Add pedal balance data source\n* Add option to split bars",
|
"releaseNotes" to "* Add german localization\n* Add gear data sources\n* Show zero value on bars to indicate sensor availability\n* Fix pedal balance values\n* Add pedal balance data source\n* Add option to split bars",
|
||||||
"screenshotUrls" to listOf(
|
"screenshotUrls" to listOf(
|
||||||
"$baseUrl/powerbar_min.gif",
|
"$baseUrl/powerbar_min.gif",
|
||||||
"$baseUrl/powerbar0.png",
|
"$baseUrl/powerbar0.png",
|
||||||
|
|||||||
@ -3,17 +3,17 @@ package de.timklge.karoopowerbar
|
|||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
enum class CustomProgressBarSize(val id: String, val label: String, val fontSize: Float, val barHeight: Float) {
|
enum class CustomProgressBarSize(val id: String, val labelResId: Int, val fontSize: Float, val barHeight: Float) {
|
||||||
SMALL("small", "Small", 35f, 10f),
|
SMALL("small", R.string.size_small, 35f, 10f),
|
||||||
MEDIUM("medium", "Medium", 40f, 15f),
|
MEDIUM("medium", R.string.size_medium, 40f, 15f),
|
||||||
LARGE("large", "Large", 60f, 25f),
|
LARGE("large", R.string.size_large, 60f, 25f),
|
||||||
}
|
}
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
enum class CustomProgressBarFontSize(val id: String, val label: String, val fontSize: Float) {
|
enum class CustomProgressBarFontSize(val id: String, val labelResId: Int, val fontSize: Float) {
|
||||||
SMALL("small", "Small", 35f),
|
SMALL("small", R.string.size_small, 35f),
|
||||||
MEDIUM("medium", "Medium", 40f),
|
MEDIUM("medium", R.string.size_medium, 40f),
|
||||||
LARGE("large", "Large", 60f);
|
LARGE("large", R.string.size_large, 60f);
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun fromSize(size: CustomProgressBarSize): CustomProgressBarFontSize {
|
fun fromSize(size: CustomProgressBarSize): CustomProgressBarFontSize {
|
||||||
@ -27,11 +27,11 @@ enum class CustomProgressBarFontSize(val id: String, val label: String, val font
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
enum class CustomProgressBarBarSize(val id: String, val label: String, val barHeight: Float) {
|
enum class CustomProgressBarBarSize(val id: String, val labelResId: Int, val barHeight: Float) {
|
||||||
NONE("none", "None", 0f),
|
NONE("none", R.string.size_none, 0f),
|
||||||
SMALL("small", "Small", 10f),
|
SMALL("small", R.string.size_small, 10f),
|
||||||
MEDIUM("medium", "Medium", 15f),
|
MEDIUM("medium", R.string.size_medium, 15f),
|
||||||
LARGE("large", "Large", 25f);
|
LARGE("large", R.string.size_large, 25f);
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun fromSize(size: CustomProgressBarSize): CustomProgressBarBarSize {
|
fun fromSize(size: CustomProgressBarSize): CustomProgressBarBarSize {
|
||||||
|
|||||||
@ -79,7 +79,7 @@ class ForegroundService : Service() {
|
|||||||
|
|
||||||
private fun setupForeground() {
|
private fun setupForeground() {
|
||||||
val channelId = "de.timklge.karoopowerbar"
|
val channelId = "de.timklge.karoopowerbar"
|
||||||
val channelName = "Background Service"
|
val channelName = getString(R.string.notification_channel_name)
|
||||||
val chan = NotificationChannel(
|
val chan = NotificationChannel(
|
||||||
channelId,
|
channelId,
|
||||||
channelName,
|
channelName,
|
||||||
@ -88,14 +88,13 @@ class ForegroundService : Service() {
|
|||||||
|
|
||||||
val manager =
|
val manager =
|
||||||
checkNotNull(getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager?)
|
checkNotNull(getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager?)
|
||||||
manager.createNotificationChannel(chan)
|
|
||||||
|
|
||||||
val notificationBuilder: NotificationCompat.Builder =
|
manager.createNotificationChannel(chan)
|
||||||
NotificationCompat.Builder(this, channelId)
|
val notificationBuilder = NotificationCompat.Builder(this, channelId)
|
||||||
val notification: Notification = notificationBuilder.setOngoing(true)
|
val notification = notificationBuilder.setOngoing(true)
|
||||||
.setContentTitle("Powerbar service running")
|
|
||||||
.setContentText("Displaying on top of other apps")
|
|
||||||
.setSmallIcon(R.drawable.bar)
|
.setSmallIcon(R.drawable.bar)
|
||||||
|
.setContentTitle(getString(R.string.app_name))
|
||||||
|
.setContentText(getString(R.string.notification_text))
|
||||||
.setPriority(NotificationManager.IMPORTANCE_MIN)
|
.setPriority(NotificationManager.IMPORTANCE_MIN)
|
||||||
.setCategory(Notification.CATEGORY_SERVICE)
|
.setCategory(Notification.CATEGORY_SERVICE)
|
||||||
.build()
|
.build()
|
||||||
|
|||||||
@ -50,6 +50,7 @@ import androidx.compose.ui.focus.FocusState
|
|||||||
import androidx.compose.ui.focus.onFocusEvent
|
import androidx.compose.ui.focus.onFocusEvent
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.input.KeyboardType
|
import androidx.compose.ui.text.input.KeyboardType
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
@ -77,22 +78,22 @@ import kotlinx.serialization.encodeToString
|
|||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
enum class SelectedSource(val id: String, val label: String) {
|
enum class SelectedSource(val id: String, val labelResId: Int) {
|
||||||
NONE("none", "None"),
|
NONE("none", R.string.source_none),
|
||||||
HEART_RATE("hr", "Heart Rate"),
|
HEART_RATE("hr", R.string.source_heart_rate),
|
||||||
POWER("power", "Power"),
|
POWER("power", R.string.source_power),
|
||||||
POWER_3S("power_3s", "Power (3 sec avg)"),
|
POWER_3S("power_3s", R.string.source_power_3s),
|
||||||
POWER_10S("power_10s", "Power (10 sec avg)"),
|
POWER_10S("power_10s", R.string.source_power_10s),
|
||||||
SPEED("speed", "Speed"),
|
SPEED("speed", R.string.source_speed),
|
||||||
SPEED_3S("speed_3s", "Speed (3 sec avg)"),
|
SPEED_3S("speed_3s", R.string.source_speed_3s),
|
||||||
CADENCE("cadence", "Cadence"),
|
CADENCE("cadence", R.string.source_cadence),
|
||||||
CADENCE_3S("cadence_3s", "Cadence (3 sec avg)"),
|
CADENCE_3S("cadence_3s", R.string.source_cadence_3s),
|
||||||
GRADE("grade", "Grade"),
|
GRADE("grade", R.string.source_grade),
|
||||||
POWER_BALANCE("power_balance", "Power Balance"),
|
POWER_BALANCE("power_balance", R.string.source_power_balance),
|
||||||
ROUTE_PROGRESS("route_progress", "Route Progress"),
|
ROUTE_PROGRESS("route_progress", R.string.source_route_progress),
|
||||||
REMAINING_ROUTE("route_progress_remaining", "Route Remaining"),
|
REMAINING_ROUTE("route_progress_remaining", R.string.source_route_remaining),
|
||||||
FRONT_GEAR("front_gear", "Front Gear"),
|
FRONT_GEAR("front_gear", R.string.source_front_gear),
|
||||||
REAR_GEAR("rear_gear", "Rear Gear");
|
REAR_GEAR("rear_gear", R.string.source_rear_gear);
|
||||||
|
|
||||||
fun isPower() = this == POWER || this == POWER_3S || this == POWER_10S
|
fun isPower() = this == POWER || this == POWER_3S || this == POWER_10S
|
||||||
}
|
}
|
||||||
@ -121,7 +122,7 @@ fun BarSelectDialog(currentSelectedSource: SelectedSource, onHide: () -> Unit, o
|
|||||||
onSelect(pattern)
|
onSelect(pattern)
|
||||||
})
|
})
|
||||||
Text(
|
Text(
|
||||||
text = pattern.label,
|
text = stringResource(pattern.labelResId),
|
||||||
modifier = Modifier.padding(start = 10.dp)
|
modifier = Modifier.padding(start = 10.dp)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -305,7 +306,7 @@ fun MainScreen(onFinish: () -> Unit) {
|
|||||||
Column(modifier = Modifier
|
Column(modifier = Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.background(MaterialTheme.colorScheme.background)) {
|
.background(MaterialTheme.colorScheme.background)) {
|
||||||
TopAppBar(title = { Text("Powerbar") })
|
TopAppBar(title = { Text(stringResource(R.string.powerbar_title)) })
|
||||||
Column(modifier = Modifier
|
Column(modifier = Modifier
|
||||||
.padding(5.dp)
|
.padding(5.dp)
|
||||||
.verticalScroll(rememberScrollState())
|
.verticalScroll(rememberScrollState())
|
||||||
@ -313,11 +314,11 @@ fun MainScreen(onFinish: () -> Unit) {
|
|||||||
|
|
||||||
if (showAlerts){
|
if (showAlerts){
|
||||||
if(!karooConnected){
|
if(!karooConnected){
|
||||||
Text(modifier = Modifier.padding(5.dp), text = "Could not read device status. Is your Karoo updated?")
|
Text(modifier = Modifier.padding(5.dp), text = stringResource(R.string.karoo_connection_error))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!givenPermissions) {
|
if (!givenPermissions) {
|
||||||
Text(modifier = Modifier.padding(5.dp), text = "You have not granted the permission to show the power bar overlay. Please do so.")
|
Text(modifier = Modifier.padding(5.dp), text = stringResource(R.string.permission_not_granted))
|
||||||
|
|
||||||
FilledTonalButton(modifier = Modifier
|
FilledTonalButton(modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
@ -325,17 +326,17 @@ fun MainScreen(onFinish: () -> Unit) {
|
|||||||
val myIntent = Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION)
|
val myIntent = Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION)
|
||||||
startActivity(ctx, myIntent, null)
|
startActivity(ctx, myIntent, null)
|
||||||
}) {
|
}) {
|
||||||
Icon(Icons.Default.Build, contentDescription = "Give permission")
|
Icon(Icons.Default.Build, contentDescription = stringResource(R.string.content_desc_give_permission))
|
||||||
Spacer(modifier = Modifier.width(5.dp))
|
Spacer(modifier = Modifier.width(5.dp))
|
||||||
Text("Give permission")
|
Text(stringResource(R.string.give_permission))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Row(verticalAlignment = Alignment.CenterVertically, modifier = Modifier.padding(horizontal = 10.dp)) {
|
Row(verticalAlignment = Alignment.CenterVertically, modifier = Modifier.padding(horizontal = 10.dp)) {
|
||||||
Text("Top Bar", style = MaterialTheme.typography.titleMedium)
|
Text(stringResource(R.string.top_bar), style = MaterialTheme.typography.titleMedium)
|
||||||
Spacer(modifier = Modifier.weight(1f))
|
Spacer(modifier = Modifier.weight(1f))
|
||||||
Text("Split")
|
Text(stringResource(R.string.split))
|
||||||
Spacer(modifier = Modifier.width(10.dp))
|
Spacer(modifier = Modifier.width(10.dp))
|
||||||
Switch(checked = splitTopBar, onCheckedChange = {
|
Switch(checked = splitTopBar, onCheckedChange = {
|
||||||
splitTopBar = it
|
splitTopBar = it
|
||||||
@ -350,9 +351,9 @@ fun MainScreen(onFinish: () -> Unit) {
|
|||||||
onClick = {
|
onClick = {
|
||||||
topBarLeftDialogVisible = true
|
topBarLeftDialogVisible = true
|
||||||
}) {
|
}) {
|
||||||
Icon(Icons.Default.Build, contentDescription = "Select", modifier = Modifier.size(20.dp))
|
Icon(Icons.Default.Build, contentDescription = stringResource(R.string.content_desc_select), modifier = Modifier.size(20.dp))
|
||||||
Spacer(modifier = Modifier.width(5.dp))
|
Spacer(modifier = Modifier.width(5.dp))
|
||||||
Text("Top Bar (Left): ${topSelectedSourceLeft.label}", modifier = Modifier.weight(1.0f))
|
Text(stringResource(R.string.top_bar_left, stringResource(topSelectedSourceLeft.labelResId)), modifier = Modifier.weight(1.0f))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (topBarLeftDialogVisible){
|
if (topBarLeftDialogVisible){
|
||||||
@ -369,9 +370,9 @@ fun MainScreen(onFinish: () -> Unit) {
|
|||||||
onClick = {
|
onClick = {
|
||||||
topBarRightDialogVisible = true
|
topBarRightDialogVisible = true
|
||||||
}) {
|
}) {
|
||||||
Icon(Icons.Default.Build, contentDescription = "Select", modifier = Modifier.size(20.dp))
|
Icon(Icons.Default.Build, contentDescription = stringResource(R.string.content_desc_select), modifier = Modifier.size(20.dp))
|
||||||
Spacer(modifier = Modifier.width(5.dp))
|
Spacer(modifier = Modifier.width(5.dp))
|
||||||
Text("Top Bar (Right): ${topSelectedSourceRight.label}", modifier = Modifier.weight(1.0f))
|
Text(stringResource(R.string.top_bar_right, stringResource(topSelectedSourceRight.labelResId)), modifier = Modifier.weight(1.0f))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (topBarRightDialogVisible){
|
if (topBarRightDialogVisible){
|
||||||
@ -388,9 +389,9 @@ fun MainScreen(onFinish: () -> Unit) {
|
|||||||
onClick = {
|
onClick = {
|
||||||
topBarDialogVisible = true
|
topBarDialogVisible = true
|
||||||
}) {
|
}) {
|
||||||
Icon(Icons.Default.Build, contentDescription = "Select", modifier = Modifier.size(20.dp))
|
Icon(Icons.Default.Build, contentDescription = stringResource(R.string.content_desc_select), modifier = Modifier.size(20.dp))
|
||||||
Spacer(modifier = Modifier.width(5.dp))
|
Spacer(modifier = Modifier.width(5.dp))
|
||||||
Text("Top Bar: ${topSelectedSource.label}", modifier = Modifier.weight(1.0f))
|
Text(stringResource(R.string.top_bar_single, stringResource(topSelectedSource.labelResId)), modifier = Modifier.weight(1.0f))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -403,9 +404,9 @@ fun MainScreen(onFinish: () -> Unit) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Row(verticalAlignment = Alignment.CenterVertically, modifier = Modifier.padding(horizontal = 10.dp)) {
|
Row(verticalAlignment = Alignment.CenterVertically, modifier = Modifier.padding(horizontal = 10.dp)) {
|
||||||
Text("Bottom Bar", style = MaterialTheme.typography.titleMedium)
|
Text(stringResource(R.string.bottom_bar), style = MaterialTheme.typography.titleMedium)
|
||||||
Spacer(modifier = Modifier.weight(1f))
|
Spacer(modifier = Modifier.weight(1f))
|
||||||
Text("Split")
|
Text(stringResource(R.string.split))
|
||||||
Spacer(modifier = Modifier.width(10.dp))
|
Spacer(modifier = Modifier.width(10.dp))
|
||||||
Switch(checked = splitBottomBar, onCheckedChange = {
|
Switch(checked = splitBottomBar, onCheckedChange = {
|
||||||
splitBottomBar = it
|
splitBottomBar = it
|
||||||
@ -420,9 +421,9 @@ fun MainScreen(onFinish: () -> Unit) {
|
|||||||
onClick = {
|
onClick = {
|
||||||
bottomBarLeftDialogVisible = true
|
bottomBarLeftDialogVisible = true
|
||||||
}) {
|
}) {
|
||||||
Icon(Icons.Default.Build, contentDescription = "Select", modifier = Modifier.size(20.dp))
|
Icon(Icons.Default.Build, contentDescription = stringResource(R.string.content_desc_select), modifier = Modifier.size(20.dp))
|
||||||
Spacer(modifier = Modifier.width(5.dp))
|
Spacer(modifier = Modifier.width(5.dp))
|
||||||
Text("Bottom Bar (Left): ${bottomSelectedSourceLeft.label}", modifier = Modifier.weight(1.0f))
|
Text(stringResource(R.string.bottom_bar_left, stringResource(bottomSelectedSourceLeft.labelResId)), modifier = Modifier.weight(1.0f))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bottomBarLeftDialogVisible){
|
if (bottomBarLeftDialogVisible){
|
||||||
@ -439,9 +440,9 @@ fun MainScreen(onFinish: () -> Unit) {
|
|||||||
onClick = {
|
onClick = {
|
||||||
bottomBarRightDialogVisible = true
|
bottomBarRightDialogVisible = true
|
||||||
}) {
|
}) {
|
||||||
Icon(Icons.Default.Build, contentDescription = "Select", modifier = Modifier.size(20.dp))
|
Icon(Icons.Default.Build, contentDescription = stringResource(R.string.content_desc_select), modifier = Modifier.size(20.dp))
|
||||||
Spacer(modifier = Modifier.width(5.dp))
|
Spacer(modifier = Modifier.width(5.dp))
|
||||||
Text("Bottom Bar (Right): ${bottomSelectedSourceRight.label}", modifier = Modifier.weight(1.0f))
|
Text(stringResource(R.string.bottom_bar_right, stringResource(bottomSelectedSourceRight.labelResId)), modifier = Modifier.weight(1.0f))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bottomBarRightDialogVisible){
|
if (bottomBarRightDialogVisible){
|
||||||
@ -458,9 +459,9 @@ fun MainScreen(onFinish: () -> Unit) {
|
|||||||
onClick = {
|
onClick = {
|
||||||
bottomBarDialogVisible = true
|
bottomBarDialogVisible = true
|
||||||
}) {
|
}) {
|
||||||
Icon(Icons.Default.Build, contentDescription = "Select", modifier = Modifier.size(20.dp))
|
Icon(Icons.Default.Build, contentDescription = stringResource(R.string.content_desc_select), modifier = Modifier.size(20.dp))
|
||||||
Spacer(modifier = Modifier.width(5.dp))
|
Spacer(modifier = Modifier.width(5.dp))
|
||||||
Text("Bottom Bar: ${bottomSelectedSource.label}", modifier = Modifier.weight(1.0f))
|
Text(stringResource(R.string.bottom_bar_single, stringResource(bottomSelectedSource.labelResId)), modifier = Modifier.weight(1.0f))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -473,22 +474,22 @@ fun MainScreen(onFinish: () -> Unit) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
apply {
|
apply {
|
||||||
val dropdownOptions = CustomProgressBarBarSize.entries.toList().map { unit -> DropdownOption(unit.id, unit.label) }
|
val dropdownOptions = CustomProgressBarBarSize.entries.toList().map { unit -> DropdownOption(unit.id, stringResource(unit.labelResId)) }
|
||||||
val dropdownInitialSelection by remember(barBarSize) {
|
val dropdownInitialSelection by remember(barBarSize) {
|
||||||
mutableStateOf(dropdownOptions.find { option -> option.id == barBarSize.id }!!)
|
mutableStateOf(dropdownOptions.find { option -> option.id == barBarSize.id }!!)
|
||||||
}
|
}
|
||||||
Dropdown(label = "Bar Size", options = dropdownOptions, selected = dropdownInitialSelection) { selectedOption ->
|
Dropdown(label = stringResource(R.string.bar_size), options = dropdownOptions, selected = dropdownInitialSelection) { selectedOption ->
|
||||||
barBarSize = CustomProgressBarBarSize.entries.find { unit -> unit.id == selectedOption.id }!!
|
barBarSize = CustomProgressBarBarSize.entries.find { unit -> unit.id == selectedOption.id }!!
|
||||||
coroutineScope.launch { updateSettings() }
|
coroutineScope.launch { updateSettings() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
apply {
|
apply {
|
||||||
val dropdownOptions = CustomProgressBarFontSize.entries.toList().map { unit -> DropdownOption(unit.id, unit.label) }
|
val dropdownOptions = CustomProgressBarFontSize.entries.toList().map { unit -> DropdownOption(unit.id, stringResource(unit.labelResId)) }
|
||||||
val dropdownInitialSelection by remember(barFontSize) {
|
val dropdownInitialSelection by remember(barFontSize) {
|
||||||
mutableStateOf(dropdownOptions.find { option -> option.id == barFontSize.id }!!)
|
mutableStateOf(dropdownOptions.find { option -> option.id == barFontSize.id }!!)
|
||||||
}
|
}
|
||||||
Dropdown(label = "Text Size", options = dropdownOptions, selected = dropdownInitialSelection) { selectedOption ->
|
Dropdown(label = stringResource(R.string.text_size), options = dropdownOptions, selected = dropdownInitialSelection) { selectedOption ->
|
||||||
barFontSize = CustomProgressBarFontSize.entries.find { unit -> unit.id == selectedOption.id }!!
|
barFontSize = CustomProgressBarFontSize.entries.find { unit -> unit.id == selectedOption.id }!!
|
||||||
coroutineScope.launch { updateSettings() }
|
coroutineScope.launch { updateSettings() }
|
||||||
}
|
}
|
||||||
@ -506,8 +507,8 @@ fun MainScreen(onFinish: () -> Unit) {
|
|||||||
.absolutePadding(right = 2.dp)
|
.absolutePadding(right = 2.dp)
|
||||||
.onFocusEvent(::updateFocus),
|
.onFocusEvent(::updateFocus),
|
||||||
onValueChange = { minSpeed = it.filter { c -> c.isDigit() } },
|
onValueChange = { minSpeed = it.filter { c -> c.isDigit() } },
|
||||||
label = { Text("Min Speed") },
|
label = { Text(stringResource(R.string.min_speed)) },
|
||||||
suffix = { Text(if (isImperial) "mph" else "kph") },
|
suffix = { Text(stringResource(if (isImperial) R.string.unit_mph else R.string.unit_kph)) },
|
||||||
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
|
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
|
||||||
singleLine = true
|
singleLine = true
|
||||||
)
|
)
|
||||||
@ -517,8 +518,8 @@ fun MainScreen(onFinish: () -> Unit) {
|
|||||||
.absolutePadding(left = 2.dp)
|
.absolutePadding(left = 2.dp)
|
||||||
.onFocusEvent(::updateFocus),
|
.onFocusEvent(::updateFocus),
|
||||||
onValueChange = { maxSpeed = it.filter { c -> c.isDigit() } },
|
onValueChange = { maxSpeed = it.filter { c -> c.isDigit() } },
|
||||||
label = { Text("Max Speed") },
|
label = { Text(stringResource(R.string.max_speed)) },
|
||||||
suffix = { Text(if (isImperial) "mph" else "kph") },
|
suffix = { Text(stringResource(if (isImperial) R.string.unit_mph else R.string.unit_kph)) },
|
||||||
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
|
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
|
||||||
singleLine = true
|
singleLine = true
|
||||||
)
|
)
|
||||||
@ -535,7 +536,7 @@ fun MainScreen(onFinish: () -> Unit) {
|
|||||||
coroutineScope.launch { updateSettings() }
|
coroutineScope.launch { updateSettings() }
|
||||||
})
|
})
|
||||||
Spacer(modifier = Modifier.width(10.dp))
|
Spacer(modifier = Modifier.width(10.dp))
|
||||||
Text("Use custom power range")
|
Text(stringResource(R.string.use_custom_power_range))
|
||||||
}
|
}
|
||||||
|
|
||||||
if(useCustomPowerRange){
|
if(useCustomPowerRange){
|
||||||
@ -545,8 +546,8 @@ fun MainScreen(onFinish: () -> Unit) {
|
|||||||
.absolutePadding(right = 2.dp)
|
.absolutePadding(right = 2.dp)
|
||||||
.onFocusEvent(::updateFocus),
|
.onFocusEvent(::updateFocus),
|
||||||
onValueChange = { customMinPower = it.filter { c -> c.isDigit() } },
|
onValueChange = { customMinPower = it.filter { c -> c.isDigit() } },
|
||||||
label = { Text("Min Power", fontSize = 12.sp) },
|
label = { Text(stringResource(R.string.min_power), fontSize = 12.sp) },
|
||||||
suffix = { Text("W") },
|
suffix = { Text(stringResource(R.string.unit_watts)) },
|
||||||
placeholder = { Text("$profileMinPower") },
|
placeholder = { Text("$profileMinPower") },
|
||||||
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
|
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
|
||||||
singleLine = true
|
singleLine = true
|
||||||
@ -557,8 +558,8 @@ fun MainScreen(onFinish: () -> Unit) {
|
|||||||
.absolutePadding(left = 2.dp)
|
.absolutePadding(left = 2.dp)
|
||||||
.onFocusEvent(::updateFocus),
|
.onFocusEvent(::updateFocus),
|
||||||
onValueChange = { customMaxPower = it.filter { c -> c.isDigit() } },
|
onValueChange = { customMaxPower = it.filter { c -> c.isDigit() } },
|
||||||
label = { Text("Max Power", fontSize = 12.sp) },
|
label = { Text(stringResource(R.string.max_power), fontSize = 12.sp) },
|
||||||
suffix = { Text("W") },
|
suffix = { Text(stringResource(R.string.unit_watts)) },
|
||||||
placeholder = { Text("$profileMaxPower") },
|
placeholder = { Text("$profileMaxPower") },
|
||||||
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
|
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
|
||||||
singleLine = true
|
singleLine = true
|
||||||
@ -577,7 +578,7 @@ fun MainScreen(onFinish: () -> Unit) {
|
|||||||
coroutineScope.launch { updateSettings() }
|
coroutineScope.launch { updateSettings() }
|
||||||
})
|
})
|
||||||
Spacer(modifier = Modifier.width(10.dp))
|
Spacer(modifier = Modifier.width(10.dp))
|
||||||
Text("Use custom HR range")
|
Text(stringResource(R.string.use_custom_hr_range))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (useCustomHrRange){
|
if (useCustomHrRange){
|
||||||
@ -587,8 +588,8 @@ fun MainScreen(onFinish: () -> Unit) {
|
|||||||
.absolutePadding(right = 2.dp)
|
.absolutePadding(right = 2.dp)
|
||||||
.onFocusEvent(::updateFocus),
|
.onFocusEvent(::updateFocus),
|
||||||
onValueChange = { customMinHr = it.filter { c -> c.isDigit() } },
|
onValueChange = { customMinHr = it.filter { c -> c.isDigit() } },
|
||||||
label = { Text("Min Hr") },
|
label = { Text(stringResource(R.string.min_hr)) },
|
||||||
suffix = { Text("bpm") },
|
suffix = { Text(stringResource(R.string.unit_bpm)) },
|
||||||
placeholder = { if(profileRestHr > 0) Text("$profileRestHr") else Unit },
|
placeholder = { if(profileRestHr > 0) Text("$profileRestHr") else Unit },
|
||||||
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
|
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
|
||||||
singleLine = true
|
singleLine = true
|
||||||
@ -599,8 +600,8 @@ fun MainScreen(onFinish: () -> Unit) {
|
|||||||
.absolutePadding(left = 2.dp)
|
.absolutePadding(left = 2.dp)
|
||||||
.onFocusEvent(::updateFocus),
|
.onFocusEvent(::updateFocus),
|
||||||
onValueChange = { customMaxHr = it.filter { c -> c.isDigit() } },
|
onValueChange = { customMaxHr = it.filter { c -> c.isDigit() } },
|
||||||
label = { Text("Max Hr") },
|
label = { Text(stringResource(R.string.max_hr)) },
|
||||||
suffix = { Text("bpm") },
|
suffix = { Text(stringResource(R.string.unit_bpm)) },
|
||||||
placeholder = { if(profileMaxHr > 0) Text("$profileMaxHr") else Unit },
|
placeholder = { if(profileMaxHr > 0) Text("$profileMaxHr") else Unit },
|
||||||
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
|
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
|
||||||
singleLine = true
|
singleLine = true
|
||||||
@ -621,8 +622,8 @@ fun MainScreen(onFinish: () -> Unit) {
|
|||||||
.absolutePadding(right = 2.dp)
|
.absolutePadding(right = 2.dp)
|
||||||
.onFocusEvent(::updateFocus),
|
.onFocusEvent(::updateFocus),
|
||||||
onValueChange = { minCadence = it.filter { c -> c.isDigit() } },
|
onValueChange = { minCadence = it.filter { c -> c.isDigit() } },
|
||||||
label = { Text("Min Cadence") },
|
label = { Text(stringResource(R.string.min_cadence)) },
|
||||||
suffix = { Text("rpm") },
|
suffix = { Text(stringResource(R.string.unit_rpm)) },
|
||||||
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
|
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
|
||||||
singleLine = true
|
singleLine = true
|
||||||
)
|
)
|
||||||
@ -632,8 +633,8 @@ fun MainScreen(onFinish: () -> Unit) {
|
|||||||
.absolutePadding(left = 2.dp)
|
.absolutePadding(left = 2.dp)
|
||||||
.onFocusEvent(::updateFocus),
|
.onFocusEvent(::updateFocus),
|
||||||
onValueChange = { maxCadence = it.filter { c -> c.isDigit() } },
|
onValueChange = { maxCadence = it.filter { c -> c.isDigit() } },
|
||||||
label = { Text("Min Cadence") },
|
label = { Text(stringResource(R.string.max_cadence)) },
|
||||||
suffix = { Text("rpm") },
|
suffix = { Text(stringResource(R.string.unit_rpm)) },
|
||||||
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
|
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
|
||||||
singleLine = true
|
singleLine = true
|
||||||
)
|
)
|
||||||
@ -650,8 +651,8 @@ fun MainScreen(onFinish: () -> Unit) {
|
|||||||
.absolutePadding(right = 2.dp)
|
.absolutePadding(right = 2.dp)
|
||||||
.onFocusEvent(::updateFocus),
|
.onFocusEvent(::updateFocus),
|
||||||
onValueChange = { minGrade = it.filterIndexed { index, c -> c.isDigit() || (c == '-' && index == 0) } },
|
onValueChange = { minGrade = it.filterIndexed { index, c -> c.isDigit() || (c == '-' && index == 0) } },
|
||||||
label = { Text("Min Grade") },
|
label = { Text(stringResource(R.string.min_grade)) },
|
||||||
suffix = { Text("%") },
|
suffix = { Text(stringResource(R.string.unit_percent)) },
|
||||||
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
|
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
|
||||||
singleLine = true
|
singleLine = true
|
||||||
)
|
)
|
||||||
@ -661,8 +662,8 @@ fun MainScreen(onFinish: () -> Unit) {
|
|||||||
.absolutePadding(left = 2.dp)
|
.absolutePadding(left = 2.dp)
|
||||||
.onFocusEvent(::updateFocus),
|
.onFocusEvent(::updateFocus),
|
||||||
onValueChange = { maxGrade = it.filterIndexed { index, c -> c.isDigit() || (c == '-' && index == 0) } },
|
onValueChange = { maxGrade = it.filterIndexed { index, c -> c.isDigit() || (c == '-' && index == 0) } },
|
||||||
label = { Text("Max Grade") },
|
label = { Text(stringResource(R.string.max_grade)) },
|
||||||
suffix = { Text("%") },
|
suffix = { Text(stringResource(R.string.unit_percent)) },
|
||||||
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
|
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
|
||||||
singleLine = true
|
singleLine = true
|
||||||
)
|
)
|
||||||
@ -675,7 +676,7 @@ fun MainScreen(onFinish: () -> Unit) {
|
|||||||
coroutineScope.launch { updateSettings() }
|
coroutineScope.launch { updateSettings() }
|
||||||
})
|
})
|
||||||
Spacer(modifier = Modifier.width(10.dp))
|
Spacer(modifier = Modifier.width(10.dp))
|
||||||
Text("Color based on HR / power zones")
|
Text(stringResource(R.string.color_based_on_zones))
|
||||||
}
|
}
|
||||||
|
|
||||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||||
@ -684,7 +685,7 @@ fun MainScreen(onFinish: () -> Unit) {
|
|||||||
coroutineScope.launch { updateSettings() }
|
coroutineScope.launch { updateSettings() }
|
||||||
})
|
})
|
||||||
Spacer(modifier = Modifier.width(10.dp))
|
Spacer(modifier = Modifier.width(10.dp))
|
||||||
Text("Show value on bars")
|
Text(stringResource(R.string.show_value_on_bars))
|
||||||
}
|
}
|
||||||
|
|
||||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||||
@ -693,7 +694,7 @@ fun MainScreen(onFinish: () -> Unit) {
|
|||||||
coroutineScope.launch { updateSettings() }
|
coroutineScope.launch { updateSettings() }
|
||||||
})
|
})
|
||||||
Spacer(modifier = Modifier.width(10.dp))
|
Spacer(modifier = Modifier.width(10.dp))
|
||||||
Text("Solid background")
|
Text(stringResource(R.string.solid_background))
|
||||||
}
|
}
|
||||||
|
|
||||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||||
@ -702,7 +703,7 @@ fun MainScreen(onFinish: () -> Unit) {
|
|||||||
coroutineScope.launch { updateSettings() }
|
coroutineScope.launch { updateSettings() }
|
||||||
})
|
})
|
||||||
Spacer(modifier = Modifier.width(10.dp))
|
Spacer(modifier = Modifier.width(10.dp))
|
||||||
Text("Only show while riding")
|
Text(stringResource(R.string.only_show_while_riding))
|
||||||
}
|
}
|
||||||
|
|
||||||
Spacer(modifier = Modifier.padding(30.dp))
|
Spacer(modifier = Modifier.padding(30.dp))
|
||||||
@ -711,7 +712,7 @@ fun MainScreen(onFinish: () -> Unit) {
|
|||||||
|
|
||||||
Image(
|
Image(
|
||||||
painter = painterResource(id = R.drawable.back),
|
painter = painterResource(id = R.drawable.back),
|
||||||
contentDescription = "Back",
|
contentDescription = stringResource(R.string.content_desc_back),
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.align(Alignment.BottomStart)
|
.align(Alignment.BottomStart)
|
||||||
.padding(bottom = 10.dp)
|
.padding(bottom = 10.dp)
|
||||||
|
|||||||
77
app/src/main/res/values-de/strings.xml
Normal file
77
app/src/main/res/values-de/strings.xml
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
<resources>
|
||||||
|
<string name="app_name">Powerbar</string>
|
||||||
|
<string name="extension_name">Powerbar</string>
|
||||||
|
|
||||||
|
<!-- Main Screen Strings -->
|
||||||
|
<string name="powerbar_title">Powerbar</string>
|
||||||
|
<string name="karoo_connection_error">Gerätestatus konnte nicht gelesen werden. Ist Ihr Karoo aktualisiert?</string>
|
||||||
|
<string name="permission_not_granted">Sie haben die Berechtigung zum Anzeigen der Powerbar nicht erteilt. Bitte tun Sie dies.</string>
|
||||||
|
<string name="give_permission">Berechtigung erteilen</string>
|
||||||
|
<string name="top_bar">Oben</string>
|
||||||
|
<string name="bottom_bar">Unten</string>
|
||||||
|
<string name="split">Teilen</string>
|
||||||
|
<string name="top_bar_left">Oben (Links): %s</string>
|
||||||
|
<string name="top_bar_right">Oben (Rechts): %s</string>
|
||||||
|
<string name="top_bar_single">Oben: %s</string>
|
||||||
|
<string name="bottom_bar_left">Unten (Links): %s</string>
|
||||||
|
<string name="bottom_bar_right">Unten (Rechts): %s</string>
|
||||||
|
<string name="bottom_bar_single">Unten: %s</string>
|
||||||
|
<string name="bar_size">Balkengröße</string>
|
||||||
|
<string name="text_size">Textgröße</string>
|
||||||
|
<string name="min_speed">Min. Geschwindigkeit</string>
|
||||||
|
<string name="max_speed">Max. Geschwindigkeit</string>
|
||||||
|
<string name="use_custom_power_range">Eigenen Leistungsbereich verwenden</string>
|
||||||
|
<string name="min_power">Min. Leistung</string>
|
||||||
|
<string name="max_power">Max. Leistung</string>
|
||||||
|
<string name="use_custom_hr_range">Eigenen HF-Bereich verwenden</string>
|
||||||
|
<string name="min_hr">Min. HF</string>
|
||||||
|
<string name="max_hr">Max. HF</string>
|
||||||
|
<string name="min_cadence">Min. Trittfrequenz</string>
|
||||||
|
<string name="max_cadence">Max. Trittfrequenz</string>
|
||||||
|
<string name="min_grade">Min. Steigung</string>
|
||||||
|
<string name="max_grade">Max. Steigung</string>
|
||||||
|
<string name="color_based_on_zones">Farbe basierend auf HF-/Leistungszonen</string>
|
||||||
|
<string name="show_value_on_bars">Werte auf Balken anzeigen</string>
|
||||||
|
<string name="solid_background">Fester Hintergrund</string>
|
||||||
|
<string name="only_show_while_riding">Nur während der Fahrt anzeigen</string>
|
||||||
|
|
||||||
|
<!-- Data Source Labels -->
|
||||||
|
<string name="source_none">Keine</string>
|
||||||
|
<string name="source_heart_rate">Herzfrequenz</string>
|
||||||
|
<string name="source_power">Leistung</string>
|
||||||
|
<string name="source_power_3s">Leistung (3 Sek. Ø)</string>
|
||||||
|
<string name="source_power_10s">Leistung (10 Sek. Ø)</string>
|
||||||
|
<string name="source_speed">Geschwindigkeit</string>
|
||||||
|
<string name="source_speed_3s">Geschwindigkeit (3 Sek. Ø)</string>
|
||||||
|
<string name="source_cadence">Trittfrequenz</string>
|
||||||
|
<string name="source_cadence_3s">Trittfrequenz (3 Sek. Ø)</string>
|
||||||
|
<string name="source_grade">Steigung</string>
|
||||||
|
<string name="source_power_balance">Leistungsbalance</string>
|
||||||
|
<string name="source_route_progress">Routenfortschritt</string>
|
||||||
|
<string name="source_route_remaining">Verbleibende Route</string>
|
||||||
|
<string name="source_front_gear">Vorderer Gang</string>
|
||||||
|
<string name="source_rear_gear">Hinterer Gang</string>
|
||||||
|
|
||||||
|
<!-- Units -->
|
||||||
|
<string name="unit_mph">mph</string>
|
||||||
|
<string name="unit_kph">km/h</string>
|
||||||
|
<string name="unit_watts">W</string>
|
||||||
|
<string name="unit_bpm">S/min</string>
|
||||||
|
<string name="unit_rpm">U/min</string>
|
||||||
|
<string name="unit_percent">%</string>
|
||||||
|
|
||||||
|
<!-- Content Descriptions -->
|
||||||
|
<string name="content_desc_give_permission">Berechtigung erteilen</string>
|
||||||
|
<string name="content_desc_select">Auswählen</string>
|
||||||
|
<string name="content_desc_back">Zurück</string>
|
||||||
|
|
||||||
|
<!-- Notification -->
|
||||||
|
<string name="notification_text">Anzeige über anderen Apps</string>
|
||||||
|
<string name="notification_channel_name">Hintergrunddienst</string>
|
||||||
|
|
||||||
|
<!-- Size Options -->
|
||||||
|
<string name="size_none">Keine</string>
|
||||||
|
<string name="size_small">Klein</string>
|
||||||
|
<string name="size_medium">Mittel</string>
|
||||||
|
<string name="size_large">Groß</string>
|
||||||
|
</resources>
|
||||||
@ -1,4 +1,77 @@
|
|||||||
<resources>
|
<resources>
|
||||||
<string name="app_name">Powerbar</string>
|
<string name="app_name">Powerbar</string>
|
||||||
<string name="extension_name">Powerbar</string>
|
<string name="extension_name">Powerbar</string>
|
||||||
|
|
||||||
|
<!-- Main Screen Strings -->
|
||||||
|
<string name="powerbar_title">Powerbar</string>
|
||||||
|
<string name="karoo_connection_error">Could not read device status. Is your Karoo updated?</string>
|
||||||
|
<string name="permission_not_granted">You have not granted the permission to show the power bar overlay. Please do so.</string>
|
||||||
|
<string name="give_permission">Give permission</string>
|
||||||
|
<string name="top_bar">Top Bar</string>
|
||||||
|
<string name="bottom_bar">Bottom Bar</string>
|
||||||
|
<string name="split">Split</string>
|
||||||
|
<string name="top_bar_left">Top Bar (Left): %s</string>
|
||||||
|
<string name="top_bar_right">Top Bar (Right): %s</string>
|
||||||
|
<string name="top_bar_single">Top Bar: %s</string>
|
||||||
|
<string name="bottom_bar_left">Bottom Bar (Left): %s</string>
|
||||||
|
<string name="bottom_bar_right">Bottom Bar (Right): %s</string>
|
||||||
|
<string name="bottom_bar_single">Bottom Bar: %s</string>
|
||||||
|
<string name="bar_size">Bar Size</string>
|
||||||
|
<string name="text_size">Text Size</string>
|
||||||
|
<string name="min_speed">Min Speed</string>
|
||||||
|
<string name="max_speed">Max Speed</string>
|
||||||
|
<string name="use_custom_power_range">Use custom power range</string>
|
||||||
|
<string name="min_power">Min Power</string>
|
||||||
|
<string name="max_power">Max Power</string>
|
||||||
|
<string name="use_custom_hr_range">Use custom HR range</string>
|
||||||
|
<string name="min_hr">Min Hr</string>
|
||||||
|
<string name="max_hr">Max Hr</string>
|
||||||
|
<string name="min_cadence">Min Cadence</string>
|
||||||
|
<string name="max_cadence">Max Cadence</string>
|
||||||
|
<string name="min_grade">Min Grade</string>
|
||||||
|
<string name="max_grade">Max Grade</string>
|
||||||
|
<string name="color_based_on_zones">Color based on HR / power zones</string>
|
||||||
|
<string name="show_value_on_bars">Show value on bars</string>
|
||||||
|
<string name="solid_background">Solid background</string>
|
||||||
|
<string name="only_show_while_riding">Only show while riding</string>
|
||||||
|
|
||||||
|
<!-- Data Source Labels -->
|
||||||
|
<string name="source_none">None</string>
|
||||||
|
<string name="source_heart_rate">Heart Rate</string>
|
||||||
|
<string name="source_power">Power</string>
|
||||||
|
<string name="source_power_3s">Power (3 sec avg)</string>
|
||||||
|
<string name="source_power_10s">Power (10 sec avg)</string>
|
||||||
|
<string name="source_speed">Speed</string>
|
||||||
|
<string name="source_speed_3s">Speed (3 sec avg)</string>
|
||||||
|
<string name="source_cadence">Cadence</string>
|
||||||
|
<string name="source_cadence_3s">Cadence (3 sec avg)</string>
|
||||||
|
<string name="source_grade">Grade</string>
|
||||||
|
<string name="source_power_balance">Power Balance</string>
|
||||||
|
<string name="source_route_progress">Route Progress</string>
|
||||||
|
<string name="source_route_remaining">Route Remaining</string>
|
||||||
|
<string name="source_front_gear">Front Gear</string>
|
||||||
|
<string name="source_rear_gear">Rear Gear</string>
|
||||||
|
|
||||||
|
<!-- Units -->
|
||||||
|
<string name="unit_mph">mph</string>
|
||||||
|
<string name="unit_kph">kph</string>
|
||||||
|
<string name="unit_watts">W</string>
|
||||||
|
<string name="unit_bpm">bpm</string>
|
||||||
|
<string name="unit_rpm">rpm</string>
|
||||||
|
<string name="unit_percent">%</string>
|
||||||
|
|
||||||
|
<!-- Content Descriptions -->
|
||||||
|
<string name="content_desc_give_permission">Give permission</string>
|
||||||
|
<string name="content_desc_select">Select</string>
|
||||||
|
<string name="content_desc_back">Back</string>
|
||||||
|
|
||||||
|
<!-- Notification -->
|
||||||
|
<string name="notification_text">Displaying on top of other apps</string>
|
||||||
|
<string name="notification_channel_name">Background Service</string>
|
||||||
|
|
||||||
|
<!-- Size Options -->
|
||||||
|
<string name="size_none">None</string>
|
||||||
|
<string name="size_small">Small</string>
|
||||||
|
<string name="size_medium">Medium</string>
|
||||||
|
<string name="size_large">Large</string>
|
||||||
</resources>
|
</resources>
|
||||||
Loading…
x
Reference in New Issue
Block a user