This commit is contained in:
sim 2025-09-26 16:12:11 +02:00
parent a1fd80366e
commit 36826185b8
14 changed files with 64 additions and 43 deletions

View file

@ -3,3 +3,4 @@ ktlint_code_style = android_studio
ktlint_function_naming_ignore_when_annotated_with=Composable
max_line_length = 140
ktlint_class_signature_rule_force_multiline_when_parameter_count_greater_or_equal_than=3
ktlint_function_signature_rule_force_multiline_when_parameter_count_greater_or_equal_than=3

View file

@ -89,7 +89,6 @@ dependencies {
implementation(libs.androidx.material3.android)
implementation(libs.kotlinx.serialization.json)
implementation(libs.androidx.ui.tooling.preview.android)
implementation(libs.androidx.navigation.runtime.ktx)
implementation(libs.androidx.navigation.compose)
debugImplementation(libs.androidx.ui.tooling)
}

View file

@ -12,8 +12,8 @@ import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import org.unifiedpush.distributor.sunup.EventBus
import org.unifiedpush.distributor.sunup.Migrations
import org.unifiedpush.distributor.sunup.activities.ThemeViewModel
import org.unifiedpush.distributor.sunup.activities.ui.App
import org.unifiedpush.distributor.sunup.activities.ui.ThemeViewModel
import org.unifiedpush.distributor.sunup.activities.ui.theme.AppTheme
import org.unifiedpush.distributor.sunup.services.RestartWorker
import org.unifiedpush.distributor.sunup.utils.TAG

View file

@ -20,6 +20,14 @@ class MainViewModel(
val registrationsViewModel: RegistrationsViewModel,
val application: Application? = null
) : ViewModel() {
constructor(application: Application) : this(
mainUiState = MainUiState(),
batteryOptimisationViewModel = BatteryOptimisationViewModel(application),
registrationsViewModel = RegistrationsViewModel(
getRegistrationListState(application)
),
application
)
var mainUiState by mutableStateOf(mainUiState)
private set
@ -78,17 +86,4 @@ class MainViewModel(
fun restartService() {
publishAction(AppAction(AppAction.Action.RestartService))
}
companion object {
fun from(application: Application): MainViewModel {
return MainViewModel(
mainUiState = MainUiState(),
batteryOptimisationViewModel = BatteryOptimisationViewModel(application),
registrationsViewModel = RegistrationsViewModel(
getRegistrationListState(application)
),
application
)
}
}
}

View file

@ -7,17 +7,14 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import java.net.URL
import kotlinx.coroutines.launch
import org.unifiedpush.distributor.sunup.AppStore
import org.unifiedpush.distributor.sunup.BuildConfig
import org.unifiedpush.distributor.sunup.activities.ui.SettingsState
import org.unifiedpush.distributor.sunup.utils.TAG
import java.net.URL
class SettingsViewModel(
state: SettingsState,
val application: Application? = null
): ViewModel() {
class SettingsViewModel(state: SettingsState, val application: Application? = null) : ViewModel() {
constructor(application: Application) : this(
SettingsState.from(application),
application
@ -26,10 +23,9 @@ class SettingsViewModel(
var state by mutableStateOf(state)
private set
fun toggleChangeServer() {
viewModelScope.launch {
state = state.copy(showChangeServerDialog = !state.showChangeServerDialog,)
state = state.copy(showChangeServerDialog = !state.showChangeServerDialog)
}
}
@ -52,7 +48,7 @@ class SettingsViewModel(
URL(url)
state = state.copy(
currentApiUrl = url,
showChangeServerDialog = false,
showChangeServerDialog = false
)
publishAction(AppAction(AppAction.Action.NewPushServer(url)))
} catch (e: Exception) {
@ -75,4 +71,4 @@ class SettingsViewModel(
publishAction(AppAction(AppAction.Action.ShowToasts(state.showToasts)))
}
}
}
}

View file

@ -0,0 +1,25 @@
package org.unifiedpush.distributor.sunup.activities
import android.app.Application
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.launch
import org.unifiedpush.distributor.sunup.AppStore
class ThemeViewModel(val application: Application? = null) : ViewModel() {
var dynamicColors by mutableStateOf(
application?.let { AppStore(it).dynamicColors } ?: false
)
fun toggleDynamicColors() {
viewModelScope.launch {
dynamicColors = !dynamicColors
application?.run {
AppStore(this).dynamicColors = dynamicColors
}
}
}
}

View file

@ -8,13 +8,13 @@ import org.unifiedpush.android.distributor.ui.compose.BatteryOptimisationViewMod
import org.unifiedpush.android.distributor.ui.compose.previewRegistrationsViewModel
import org.unifiedpush.android.distributor.ui.compose.state.DistribMigrationState
import org.unifiedpush.distributor.sunup.BuildConfig
import org.unifiedpush.distributor.sunup.activities.ThemeViewModel
import org.unifiedpush.distributor.sunup.activities.ui.MainUiState
import org.unifiedpush.distributor.sunup.activities.ui.SettingsState
import org.unifiedpush.distributor.sunup.activities.ui.ThemeViewModel
class ViewModelFactory(val application: Application) : ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T = when {
modelClass.isAssignableFrom(MainViewModel::class.java) -> MainViewModel.from(application)
modelClass.isAssignableFrom(MainViewModel::class.java) -> MainViewModel(application)
modelClass.isAssignableFrom(SettingsViewModel::class.java) -> SettingsViewModel(
application
)
@ -36,9 +36,9 @@ class PreviewFactory(val context: Context) : ViewModelProvider.Factory {
modelClass.isAssignableFrom(SettingsViewModel::class.java) -> {
SettingsViewModel(
SettingsState(
BuildConfig.DEFAULT_API_URL,
BuildConfig.DEFAULT_API_URL,
false
),
)
)
}
modelClass.isAssignableFrom(ThemeViewModel::class.java) -> ThemeViewModel()
@ -47,4 +47,4 @@ class PreviewFactory(val context: Context) : ViewModelProvider.Factory {
}
else -> throw IllegalArgumentException("Unknown ViewModel class")
} as T
}
}

View file

@ -34,8 +34,8 @@ import androidx.lifecycle.Lifecycle
import androidx.lifecycle.compose.LocalLifecycleOwner
import androidx.lifecycle.repeatOnLifecycle
import androidx.lifecycle.viewmodel.compose.viewModel
import org.unifiedpush.android.distributor.ui.compose.AppBar
import org.unifiedpush.android.distributor.ui.R as LibR
import org.unifiedpush.android.distributor.ui.compose.AppBar
import org.unifiedpush.android.distributor.ui.compose.CardDisableBatteryOptimisation
import org.unifiedpush.android.distributor.ui.compose.CardDisabledForMigration
import org.unifiedpush.android.distributor.ui.compose.DistribMigrationUi
@ -67,7 +67,6 @@ fun MainAppBarOrSelection(viewModel: MainViewModel, onGoToSettings: () -> Unit)
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun MainAppBar(viewModel: MainViewModel, onGoToSettings: () -> Unit) {

View file

@ -25,6 +25,7 @@ import androidx.lifecycle.Lifecycle
import androidx.lifecycle.compose.LocalLifecycleOwner
import androidx.lifecycle.repeatOnLifecycle
import androidx.lifecycle.viewmodel.compose.viewModel
import org.unifiedpush.android.distributor.ui.R as LibR
import org.unifiedpush.android.distributor.ui.compose.AboutHeading
import org.unifiedpush.android.distributor.ui.compose.DistribMigrationUi
import org.unifiedpush.android.distributor.ui.compose.Heading
@ -34,8 +35,8 @@ import org.unifiedpush.distributor.sunup.R
import org.unifiedpush.distributor.sunup.activities.DistribMigrationViewModel
import org.unifiedpush.distributor.sunup.activities.PreviewFactory
import org.unifiedpush.distributor.sunup.activities.SettingsViewModel
import org.unifiedpush.distributor.sunup.activities.ThemeViewModel
import org.unifiedpush.distributor.sunup.activities.UiAction
import org.unifiedpush.android.distributor.ui.R as LibR
@Composable
fun SettingsScreen(
@ -92,7 +93,7 @@ fun SettingsScreen(
}
)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S ) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
Preference(
stringResource(LibR.string.dynamic_colors),
stringResource(LibR.string.clicklabel_dynamic_colors),
@ -162,7 +163,7 @@ fun Preference(
warning: Boolean = false,
onSelect: () -> Unit
) {
Row (
Row(
Modifier.clickable(
true,
onclickLabel,
@ -207,4 +208,4 @@ fun PreviewSettingsScreen() {
val themeVM = viewModel<ThemeViewModel>(factory = factory)
val migrationVM = viewModel<DistribMigrationViewModel>(factory = factory)
SettingsScreen(settVM, themeVM, migrationVM)
}
}

View file

@ -18,4 +18,4 @@ data class SettingsState(
)
}
}
}
}

View file

@ -261,8 +261,7 @@ fun AppTheme(
// Dynamic color is available on Android 12+
dynamicColor: Boolean = false,
content:
@Composable()
() -> Unit
@Composable () -> Unit
) {
val colorScheme = when {
dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {

View file

@ -1,10 +1,10 @@
package org.unifiedpush.distributor.sunup.api
import android.content.Context
import java.util.concurrent.atomic.AtomicReference
import org.unifiedpush.distributor.sunup.DatabaseFactory
import org.unifiedpush.distributor.sunup.services.RestartWorker
import org.unifiedpush.distributor.sunup.services.SourceManager
import java.util.concurrent.atomic.AtomicReference
/**
* Candidate for a new API url

View file

@ -159,7 +159,11 @@ class ServerConnection(private val context: Context, private val releaseLock: ()
Distributor.deleteChannelFromServer(context, message.channelID)
}
override fun onClosed(webSocket: WebSocket, code: Int, reason: String) {
override fun onClosed(
webSocket: WebSocket,
code: Int,
reason: String
) {
Log.d(TAG, "onClosed: $webSocket")
webSocket.cancel()
releaseLock()
@ -168,7 +172,11 @@ class ServerConnection(private val context: Context, private val releaseLock: ()
}
}
override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
override fun onFailure(
webSocket: WebSocket,
t: Throwable,
response: Response?
) {
Log.d(TAG, "onFailure: An error occurred: $t")
response?.let {
Log.d(TAG, "onFailure: ${it.code}")

View file

@ -13,7 +13,6 @@ material3Android = "1.3.2"
okhttp = "5.1.0"
uiTooling = "1.9.1"
runtimeAndroid = "1.9.1"
navigationRuntimeKtx = "2.9.4"
navigationCompose = "2.9.4"
[libraries]
@ -31,7 +30,6 @@ kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serializa
ktlint-gradle = { module = "org.jlleitschuh.gradle:ktlint-gradle", version.ref = "ktlint"}
okhttp = { module = "com.squareup.okhttp3:okhttp", version.ref = "okhttp" }
androidx-runtime-android = { group = "androidx.compose.runtime", name = "runtime-android", version.ref = "runtimeAndroid" }
androidx-navigation-runtime-ktx = { group = "androidx.navigation", name = "navigation-runtime-ktx", version.ref = "navigationRuntimeKtx" }
androidx-navigation-compose = { group = "androidx.navigation", name = "navigation-compose", version.ref = "navigationCompose" }
[plugins]