different theme color, minor improvements

This commit is contained in:
Egor 2026-02-03 00:55:04 -08:00
parent 8533fba925
commit 56ec5058d4
11 changed files with 176 additions and 85 deletions

View file

@ -5,19 +5,17 @@ on:
branches: [ main ] branches: [ main ]
pull_request: pull_request:
branches: [ main ] branches: [ main ]
release:
types: [ created ]
jobs: jobs:
check: check:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v6
- name: Set up JDK 17 - name: Set up JDK 21
uses: actions/setup-java@v4 uses: actions/setup-java@v5
with: with:
java-version: '17' java-version: '21'
distribution: 'temurin' distribution: 'temurin'
- name: Grant execute permission for gradlew - name: Grant execute permission for gradlew
@ -31,40 +29,3 @@ jobs:
- name: Build debug APK - name: Build debug APK
run: ./gradlew assembleDebug --stacktrace run: ./gradlew assembleDebug --stacktrace
release:
runs-on: ubuntu-latest
if: github.event_name == 'release'
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.release.tag_name }}
fetch-depth: 0
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Build release bundle
run: ./gradlew bundleRelease --stacktrace
- name: Rename bundle
run: mv app/build/outputs/bundle/release/app-release.aab prism.aab
- name: Upload release bundle
uses: actions/upload-artifact@v4
with:
name: prism-bundle
path: prism.aab
- name: Upload to release
uses: softprops/action-gh-release@v1
with:
files: prism.aab
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

42
.github/workflows/release.yml vendored Normal file
View file

@ -0,0 +1,42 @@
name: Release
on:
release:
types: [ created ]
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
ref: ${{ github.event.release.tag_name }}
fetch-depth: 0
- name: Set up JDK 21
uses: actions/setup-java@v5
with:
java-version: '21'
distribution: 'temurin'
- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Build release bundle
run: ./gradlew bundleRelease --stacktrace
- name: Rename bundle
run: mv app/build/outputs/bundle/release/app-release.aab prism.aab
- name: Upload release bundle
uses: actions/upload-artifact@v6
with:
name: prism-bundle
path: prism.aab
- name: Upload to release
uses: softprops/action-gh-release@v2
with:
files: prism.aab
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

1
.gitignore vendored
View file

@ -15,3 +15,4 @@ build
local.properties local.properties
.idea .idea
prism-release.keystore prism-release.keystore
.kotlin/sessions/kotlin-compiler-*

Binary file not shown.

View file

@ -16,15 +16,19 @@ detekt {
buildUponDefaultConfig = true buildUponDefaultConfig = true
} }
kotlin {
jvmToolchain(21)
}
android { android {
compileOptions { compileOptions {
targetCompatibility = JavaVersion.VERSION_17 sourceCompatibility = JavaVersion.VERSION_21
sourceCompatibility = JavaVersion.VERSION_17 targetCompatibility = JavaVersion.VERSION_21
} }
kotlin { kotlin {
compilerOptions { compilerOptions {
jvmTarget.set(org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17) jvmTarget.set(org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_21)
} }
} }

View file

@ -48,7 +48,7 @@ fun AppPickerDialog(
AlertDialog( AlertDialog(
onDismissRequest = onDismiss, onDismissRequest = onDismiss,
modifier = Modifier.fillMaxWidth(0.98f), modifier = Modifier.fillMaxWidth(),
title = { Text(stringResource(R.string.select_target_app_title)) }, title = { Text(stringResource(R.string.select_target_app_title)) },
text = { text = {
Column { Column {

View file

@ -0,0 +1,57 @@
package app.lonecloud.prism.activities.ui
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Switch
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.RectangleShape
import androidx.compose.ui.unit.dp
@Composable
fun PrismTogglePreference(
title: String,
description: String? = null,
checked: Boolean,
onCheckedChange: (Boolean) -> Unit
) {
Surface(
onClick = { onCheckedChange(!checked) },
modifier = Modifier.fillMaxWidth(),
shape = RectangleShape
) {
Row(
modifier = Modifier.padding(16.dp),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {
Column(
modifier = Modifier.weight(1f),
verticalArrangement = Arrangement.spacedBy(4.dp)
) {
Text(
text = title,
style = MaterialTheme.typography.bodyLarge
)
description?.let {
Text(
text = it,
style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
}
}
Switch(
checked = checked,
onCheckedChange = null
)
}
}
}

View file

@ -1,14 +1,36 @@
package app.lonecloud.prism.activities.ui package app.lonecloud.prism.activities.ui
import androidx.compose.material3.Button import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.RectangleShape
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import app.lonecloud.prism.R import app.lonecloud.prism.R
@Composable @Composable
fun RestartServicesPreference(onClick: () -> Unit) { fun RestartServicesPreference(onClick: () -> Unit) {
Button(onClick = onClick) { Surface(
Text(stringResource(R.string.restart_service_button)) onClick = onClick,
modifier = Modifier.fillMaxWidth(),
shape = RectangleShape
) {
Column(
modifier = Modifier.padding(16.dp),
horizontalAlignment = Alignment.Start,
verticalArrangement = Arrangement.spacedBy(4.dp)
) {
Text(
text = stringResource(R.string.restart_service_button),
style = MaterialTheme.typography.bodyLarge
)
}
} }
} }

View file

@ -2,11 +2,9 @@ package app.lonecloud.prism.activities.ui
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
@ -14,16 +12,12 @@ import androidx.lifecycle.Lifecycle
import androidx.lifecycle.compose.LocalLifecycleOwner import androidx.lifecycle.compose.LocalLifecycleOwner
import androidx.lifecycle.repeatOnLifecycle import androidx.lifecycle.repeatOnLifecycle
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.viewmodel.compose.viewModel
import app.lonecloud.prism.R
import app.lonecloud.prism.activities.DistribMigrationViewModel import app.lonecloud.prism.activities.DistribMigrationViewModel
import app.lonecloud.prism.activities.PreviewFactory import app.lonecloud.prism.activities.PreviewFactory
import app.lonecloud.prism.activities.SettingsViewModel import app.lonecloud.prism.activities.SettingsViewModel
import app.lonecloud.prism.activities.ThemeViewModel import app.lonecloud.prism.activities.ThemeViewModel
import org.unifiedpush.android.distributor.ui.compose.DistribMigrationUi import org.unifiedpush.android.distributor.ui.compose.DistribMigrationUi
import org.unifiedpush.android.distributor.ui.compose.DynamicColorsPreferences
import org.unifiedpush.android.distributor.ui.compose.Heading
import org.unifiedpush.android.distributor.ui.compose.MigrationPreferences import org.unifiedpush.android.distributor.ui.compose.MigrationPreferences
import org.unifiedpush.android.distributor.ui.compose.ShowToastsPreference
@Composable @Composable
fun SettingsScreen( fun SettingsScreen(
@ -39,23 +33,9 @@ fun SettingsScreen(
} }
} }
Column( Column(
modifier = Modifier
.padding(16.dp),
horizontalAlignment = Alignment.Start, horizontalAlignment = Alignment.Start,
verticalArrangement = Arrangement.spacedBy(20.dp) verticalArrangement = Arrangement.spacedBy(20.dp)
) { ) {
Heading(R.string.app_name)
ShowToastsPreference(viewModel.state.showToasts) {
viewModel.toggleShowToasts()
}
DynamicColorsPreferences(themeViewModel.dynamicColors) {
themeViewModel.toggleDynamicColors()
}
MigrationPreferences(migrationViewModel)
PrismServerConfigButton( PrismServerConfigButton(
currentUrl = viewModel.state.prismServerUrl, currentUrl = viewModel.state.prismServerUrl,
onConfigure = { url, apiKey -> onConfigure = { url, apiKey ->
@ -64,6 +44,21 @@ fun SettingsScreen(
} }
) )
PrismTogglePreference(
title = "Show Toasts",
description = "Display toast notifications for registration and unregistration events",
checked = viewModel.state.showToasts,
onCheckedChange = { viewModel.toggleShowToasts() }
)
PrismTogglePreference(
title = "Dynamic Colors",
checked = themeViewModel.dynamicColors,
onCheckedChange = { themeViewModel.toggleDynamicColors() }
)
MigrationPreferences(migrationViewModel)
RestartServicesPreference { RestartServicesPreference {
viewModel.restartService() viewModel.restartService()
} }

View file

@ -5,12 +5,14 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.material3.AlertDialog import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Button import androidx.compose.material3.Button
import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Surface
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.TextButton import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
@ -20,6 +22,7 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.RectangleShape
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
@ -29,22 +32,28 @@ import app.lonecloud.prism.R
fun PrismServerConfigButton(currentUrl: String, onConfigure: (url: String, apiKey: String) -> Unit) { fun PrismServerConfigButton(currentUrl: String, onConfigure: (url: String, apiKey: String) -> Unit) {
var showDialog by remember { mutableStateOf(false) } var showDialog by remember { mutableStateOf(false) }
TextButton( Surface(
onClick = { showDialog = true }, onClick = { showDialog = true },
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth(),
shape = RectangleShape
) { ) {
Column( Column(
modifier = Modifier.padding(16.dp),
horizontalAlignment = Alignment.Start, horizontalAlignment = Alignment.Start,
modifier = Modifier.fillMaxWidth() verticalArrangement = Arrangement.spacedBy(4.dp)
) { ) {
Text(stringResource(R.string.configure_server)) Text(
text = stringResource(R.string.configure_server),
style = MaterialTheme.typography.bodyLarge
)
Text( Text(
text = if (currentUrl.isNotBlank()) { text = if (currentUrl.isNotBlank()) {
stringResource(R.string.prism_server_configured, currentUrl) stringResource(R.string.prism_server_configured, currentUrl)
} else { } else {
stringResource(R.string.prism_server_not_configured) stringResource(R.string.prism_server_not_configured)
}, },
style = MaterialTheme.typography.bodySmall style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.onSurfaceVariant
) )
} }
} }

View file

@ -2,11 +2,11 @@ package app.lonecloud.prism.activities.ui.theme
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
// Prism theme: pleasant sky blue primary with bright, modern accents // Prism theme: modern Twitter/Bluesky blue primary with bright, modern accents
val primaryLight = Color(0xFF0288D1) val primaryLight = Color(0xFF1DA1F2)
val onPrimaryLight = Color(0xFFFFFFFF) val onPrimaryLight = Color(0xFFFFFFFF)
val primaryContainerLight = Color(0xFFB3E5FC) val primaryContainerLight = Color(0xFFB3E0FF)
val onPrimaryContainerLight = Color(0xFF01579B) val onPrimaryContainerLight = Color(0xFF0A4E73)
val secondaryLight = Color(0xFF625B71) val secondaryLight = Color(0xFF625B71)
val onSecondaryLight = Color(0xFFFFFFFF) val onSecondaryLight = Color(0xFFFFFFFF)
val secondaryContainerLight = Color(0xFFE8DEF8) val secondaryContainerLight = Color(0xFFE8DEF8)
@ -30,7 +30,7 @@ val outlineVariantLight = Color(0xFFCAC4CF)
val scrimLight = Color(0xFF000000) val scrimLight = Color(0xFF000000)
val inverseSurfaceLight = Color(0xFF313033) val inverseSurfaceLight = Color(0xFF313033)
val inverseOnSurfaceLight = Color(0xFFF4EFF4) val inverseOnSurfaceLight = Color(0xFFF4EFF4)
val inversePrimaryLight = Color(0xFF81D4FA) val inversePrimaryLight = Color(0xFF71C9F8)
val surfaceDimLight = Color(0xFFDDD8DD) val surfaceDimLight = Color(0xFFDDD8DD)
val surfaceBrightLight = Color(0xFFFFFBFF) val surfaceBrightLight = Color(0xFFFFFBFF)
val surfaceContainerLowestLight = Color(0xFFFFFFFF) val surfaceContainerLowestLight = Color(0xFFFFFFFF)
@ -39,10 +39,10 @@ val surfaceContainerLight = Color(0xFFF1ECF1)
val surfaceContainerHighLight = Color(0xFFEBE6EB) val surfaceContainerHighLight = Color(0xFFEBE6EB)
val surfaceContainerHighestLight = Color(0xFFE6E1E6) val surfaceContainerHighestLight = Color(0xFFE6E1E6)
val primaryDark = Color(0xFF81D4FA) val primaryDark = Color(0xFF71C9F8)
val onPrimaryDark = Color(0xFF004D6F) val onPrimaryDark = Color(0xFF003D5C)
val primaryContainerDark = Color(0xFF00668C) val primaryContainerDark = Color(0xFF0A6EA8)
val onPrimaryContainerDark = Color(0xFFB3E5FC) val onPrimaryContainerDark = Color(0xFFB3E0FF)
val secondaryDark = Color(0xFFCBC2DB) val secondaryDark = Color(0xFFCBC2DB)
val onSecondaryDark = Color(0xFF332D41) val onSecondaryDark = Color(0xFF332D41)
val secondaryContainerDark = Color(0xFF4A4458) val secondaryContainerDark = Color(0xFF4A4458)
@ -66,7 +66,7 @@ val outlineVariantDark = Color(0xFF49454E)
val scrimDark = Color(0xFF000000) val scrimDark = Color(0xFF000000)
val inverseSurfaceDark = Color(0xFFE6E1E6) val inverseSurfaceDark = Color(0xFFE6E1E6)
val inverseOnSurfaceDark = Color(0xFF313033) val inverseOnSurfaceDark = Color(0xFF313033)
val inversePrimaryDark = Color(0xFF0288D1) val inversePrimaryDark = Color(0xFF1DA1F2)
val surfaceDimDark = Color(0xFF141218) val surfaceDimDark = Color(0xFF141218)
val surfaceBrightDark = Color(0xFF3A383E) val surfaceBrightDark = Color(0xFF3A383E)
val surfaceContainerLowestDark = Color(0xFF0F0D13) val surfaceContainerLowestDark = Color(0xFF0F0D13)