diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 0000000..e41407c --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,26 @@ +# GitHub Copilot Instructions + +## Code Style + +- Do NOT add obvious comments that just describe what the code does +- Only add comments for complex logic, non-obvious behavior, or important context +- Prefer self-documenting code with clear variable and function names over comments +- Avoid redundant comments like "// Create button" or "// Set text color" + +## Examples of BAD comments to avoid: +```kotlin +// Description with clickable link +val description = stringResource(R.string.prism_server_description) + +// Get the URI handler +val uriHandler = LocalUriHandler.current +``` + +## Examples of GOOD comments: +```kotlin +// Retry with exponential backoff, max 5 attempts +for (attempt in 1..5) { ... } + +// WorkAround: Android 12+ requires explicit mutation flag +val pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_MUTABLE) +``` diff --git a/README.md b/README.md index 050210c..6d37ae6 100644 --- a/README.md +++ b/README.md @@ -6,4 +6,4 @@ -A notification provider to use with [Prism](https://github.com/lone-cloud/prism) \ No newline at end of file +A notification provider for [Prism](https://github.com/lone-cloud/prism) and [UnifiedPush](https://unifiedpush.org/) applications. diff --git a/app/src/main/java/app/lonecloud/prism/AppStore.kt b/app/src/main/java/app/lonecloud/prism/PrismPreferences.kt similarity index 98% rename from app/src/main/java/app/lonecloud/prism/AppStore.kt rename to app/src/main/java/app/lonecloud/prism/PrismPreferences.kt index a48bb4c..5c755b8 100644 --- a/app/src/main/java/app/lonecloud/prism/AppStore.kt +++ b/app/src/main/java/app/lonecloud/prism/PrismPreferences.kt @@ -5,7 +5,7 @@ import androidx.core.content.edit import org.unifiedpush.android.distributor.MigrationManager import org.unifiedpush.android.distributor.Store -class AppStore(context: Context) : +class PrismPreferences(context: Context) : Store(context, PREF_NAME), MigrationManager.MigrationStore { var uaid: String? diff --git a/app/src/main/java/app/lonecloud/prism/PrismServerClient.kt b/app/src/main/java/app/lonecloud/prism/PrismServerClient.kt index f5873fc..75248cf 100644 --- a/app/src/main/java/app/lonecloud/prism/PrismServerClient.kt +++ b/app/src/main/java/app/lonecloud/prism/PrismServerClient.kt @@ -3,7 +3,7 @@ package app.lonecloud.prism import android.content.Context import android.util.Base64 import android.util.Log -import app.lonecloud.prism.AppStore +import app.lonecloud.prism.PrismPreferences import app.lonecloud.prism.DatabaseFactory import java.io.IOException import java.util.concurrent.TimeUnit @@ -23,11 +23,7 @@ object PrismServerClient { .readTimeout(10, TimeUnit.SECONDS) .build() - private fun getAuthHeader(apiKey: String): String { - val credentials = ":$apiKey" - val encoded = Base64.encodeToString(credentials.toByteArray(), Base64.NO_WRAP) - return "Basic $encoded" - } + private fun getAuthHeader(apiKey: String): String = "Bearer $apiKey" fun registerApp( context: Context, @@ -39,7 +35,7 @@ object PrismServerClient { onSuccess: () -> Unit = {}, onError: (String) -> Unit = {} ) { - val store = AppStore(context) + val store = PrismPreferences(context) val serverUrl = store.prismServerUrl val apiKey = store.prismApiKey @@ -86,7 +82,7 @@ object PrismServerClient { } fun registerAllApps(context: Context) { - val store = AppStore(context) + val store = PrismPreferences(context) val serverUrl = store.prismServerUrl val apiKey = store.prismApiKey @@ -128,7 +124,7 @@ object PrismServerClient { onSuccess: () -> Unit = {}, onError: (String) -> Unit = {} ) { - val store = AppStore(context) + val store = PrismPreferences(context) val url = serverUrl ?: store.prismServerUrl val key = apiKey ?: store.prismApiKey @@ -170,7 +166,7 @@ object PrismServerClient { serverUrl: String? = null, apiKey: String? = null ) { - val store = AppStore(context) + val store = PrismPreferences(context) val url = serverUrl ?: store.prismServerUrl val key = apiKey ?: store.prismApiKey @@ -206,8 +202,9 @@ object PrismServerClient { ) { CoroutineScope(Dispatchers.IO).launch { try { + val healthUrl = "$serverUrl/api/health" val request = Request.Builder() - .url(serverUrl) + .url(healthUrl) .addHeader("Authorization", getAuthHeader(apiKey)) .get() .build() diff --git a/app/src/main/java/app/lonecloud/prism/activities/MainViewModel.kt b/app/src/main/java/app/lonecloud/prism/activities/MainViewModel.kt index 6fe566b..42ee5aa 100644 --- a/app/src/main/java/app/lonecloud/prism/activities/MainViewModel.kt +++ b/app/src/main/java/app/lonecloud/prism/activities/MainViewModel.kt @@ -12,8 +12,8 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import app.lonecloud.prism.AppStore -import app.lonecloud.prism.DatabaseFactory +import app.lonecloud.prism.PrismPreferences + import app.lonecloud.prism.DatabaseFactory import app.lonecloud.prism.EncryptionKeyStore import app.lonecloud.prism.PrismServerClient import app.lonecloud.prism.activities.ui.InstalledApp @@ -41,8 +41,8 @@ class MainViewModel( ) : ViewModel() { constructor(requireBatteryOpt: Boolean, messenger: InternalMessenger?, application: Application) : this( mainUiState = MainUiState( - prismServerConfigured = !AppStore(application).prismServerUrl.isNullOrBlank() && - !AppStore(application).prismApiKey.isNullOrBlank() + prismServerConfigured = !PrismPreferences(application).prismServerUrl.isNullOrBlank() && + !PrismPreferences(application).prismApiKey.isNullOrBlank() ), batteryOptimisationViewModel = BatteryOptimisationViewModel(requireBatteryOpt, messenger), registrationsViewModel = RegistrationsViewModel( diff --git a/app/src/main/java/app/lonecloud/prism/activities/SettingsViewModel.kt b/app/src/main/java/app/lonecloud/prism/activities/SettingsViewModel.kt index 8b83836..86b3f4e 100644 --- a/app/src/main/java/app/lonecloud/prism/activities/SettingsViewModel.kt +++ b/app/src/main/java/app/lonecloud/prism/activities/SettingsViewModel.kt @@ -7,7 +7,7 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import app.lonecloud.prism.AppStore +import app.lonecloud.prism.PrismPreferences import app.lonecloud.prism.PrismServerClient import app.lonecloud.prism.activities.ui.SettingsState import app.lonecloud.prism.receivers.PrismConfigReceiver @@ -33,7 +33,7 @@ class SettingsViewModel( fun toggleShowToasts() { viewModelScope.launch { state = state.copy(showToasts = !state.showToasts) - application?.let { AppStore(it).showToasts = state.showToasts } + application?.let { PrismPreferences(it).showToasts = state.showToasts } messenger?.sendIMessage(InternalOpcode.SHOW_TOASTS_SET, if (state.showToasts) 1 else 0) } } @@ -43,7 +43,7 @@ class SettingsViewModel( val trimmedUrl = url.trim() state = state.copy(prismServerUrl = trimmedUrl) application?.let { - AppStore(it).prismServerUrl = trimmedUrl.ifBlank { null } + PrismPreferences(it).prismServerUrl = trimmedUrl.ifBlank { null } val intent = Intent(PrismConfigReceiver.ACTION_SET_PRISM_SERVER_URL).apply { putExtra(PrismConfigReceiver.EXTRA_URL, trimmedUrl) @@ -65,7 +65,7 @@ class SettingsViewModel( val trimmedKey = apiKey.trim() state = state.copy(prismApiKey = trimmedKey) application?.let { - AppStore(it).prismApiKey = trimmedKey.ifBlank { null } + PrismPreferences(it).prismApiKey = trimmedKey.ifBlank { null } val intent = Intent(PrismConfigReceiver.ACTION_SET_PRISM_API_KEY).apply { putExtra(PrismConfigReceiver.EXTRA_API_KEY, trimmedKey) diff --git a/app/src/main/java/app/lonecloud/prism/activities/ThemeViewModel.kt b/app/src/main/java/app/lonecloud/prism/activities/ThemeViewModel.kt index 0664218..1c70fa2 100644 --- a/app/src/main/java/app/lonecloud/prism/activities/ThemeViewModel.kt +++ b/app/src/main/java/app/lonecloud/prism/activities/ThemeViewModel.kt @@ -6,18 +6,18 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import app.lonecloud.prism.AppStore +import app.lonecloud.prism.PrismPreferences import kotlinx.coroutines.launch import org.unifiedpush.android.distributor.ipc.InternalMessenger import org.unifiedpush.android.distributor.ipc.InternalOpcode class ThemeViewModel(val messenger: InternalMessenger?, val application: Application?) : ViewModel() { - var dynamicColors by mutableStateOf(application?.let { AppStore(it).dynamicColors } ?: false) + var dynamicColors by mutableStateOf(application?.let { PrismPreferences(it).dynamicColors } ?: false) fun toggleDynamicColors() { viewModelScope.launch { dynamicColors = !dynamicColors - application?.let { AppStore(it).dynamicColors = dynamicColors } + application?.let { PrismPreferences(it).dynamicColors = dynamicColors } messenger?.sendIMessage(InternalOpcode.THEME_DYN_SET, if (dynamicColors) 1 else 0) } } diff --git a/app/src/main/java/app/lonecloud/prism/activities/ui/MainScreen.kt b/app/src/main/java/app/lonecloud/prism/activities/ui/MainScreen.kt index 90a6388..2ffca29 100644 --- a/app/src/main/java/app/lonecloud/prism/activities/ui/MainScreen.kt +++ b/app/src/main/java/app/lonecloud/prism/activities/ui/MainScreen.kt @@ -24,7 +24,7 @@ import androidx.lifecycle.Lifecycle import androidx.lifecycle.compose.LocalLifecycleOwner import androidx.lifecycle.repeatOnLifecycle import androidx.lifecycle.viewmodel.compose.viewModel -import app.lonecloud.prism.AppStore +import app.lonecloud.prism.PrismPreferences import app.lonecloud.prism.R import app.lonecloud.prism.activities.MainViewModel import app.lonecloud.prism.activities.PreviewFactory @@ -89,7 +89,7 @@ fun MainScreen( "RefreshRegistrations" -> viewModel.refreshRegistrations() "UpdatePrismServerConfigured" -> { viewModel.application?.let { app -> - val store = AppStore(app) + val store = PrismPreferences(app) viewModel.updatePrismServerConfigured( !store.prismServerUrl.isNullOrBlank() && !store.prismApiKey.isNullOrBlank() diff --git a/app/src/main/java/app/lonecloud/prism/activities/ui/PrismServerConfig.kt b/app/src/main/java/app/lonecloud/prism/activities/ui/PrismServerConfig.kt index ff95320..75d3531 100644 --- a/app/src/main/java/app/lonecloud/prism/activities/ui/PrismServerConfig.kt +++ b/app/src/main/java/app/lonecloud/prism/activities/ui/PrismServerConfig.kt @@ -7,6 +7,7 @@ import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size +import androidx.compose.foundation.text.ClickableText import androidx.compose.material3.AlertDialog import androidx.compose.material3.Button import androidx.compose.material3.CircularProgressIndicator @@ -24,7 +25,12 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.RectangleShape import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.LocalUriHandler import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.SpanStyle +import androidx.compose.ui.text.buildAnnotatedString +import androidx.compose.ui.text.style.TextDecoration +import androidx.compose.ui.text.withStyle import androidx.compose.ui.unit.dp import app.lonecloud.prism.R @@ -52,7 +58,7 @@ fun PrismServerConfigButton( ) Text( text = if (currentUrl.isNotBlank()) { - stringResource(R.string.prism_server_configured, currentUrl) + currentUrl } else { stringResource(R.string.prism_server_not_configured) }, @@ -87,7 +93,9 @@ fun PrismServerConfigDialog( var isTesting by remember { mutableStateOf(false) } var testResult by remember { mutableStateOf(null) } var showServerChangeWarning by remember { mutableStateOf(false) } + var showClearConfirmation by remember { mutableStateOf(false) } val context = LocalContext.current + val uriHandler = LocalUriHandler.current AlertDialog( onDismissRequest = onDismiss, @@ -97,6 +105,46 @@ fun PrismServerConfigDialog( verticalArrangement = Arrangement.spacedBy(16.dp), modifier = Modifier.fillMaxWidth() ) { + val description = stringResource(R.string.prism_server_description) + val repoUrl = stringResource(R.string.prism_server_repo_link) + val fullText = "$description\n\n$repoUrl" + val annotatedString = buildAnnotatedString { + append(description) + append("\n\n") + + val linkStart = length + withStyle( + style = SpanStyle( + color = MaterialTheme.colorScheme.primary, + textDecoration = TextDecoration.Underline + ) + ) { + append(repoUrl) + } + addStringAnnotation( + tag = "URL", + annotation = repoUrl, + start = linkStart, + end = length + ) + } + + ClickableText( + text = annotatedString, + style = MaterialTheme.typography.bodySmall.copy( + color = MaterialTheme.colorScheme.onSurfaceVariant + ), + onClick = { offset -> + annotatedString.getStringAnnotations( + tag = "URL", + start = offset, + end = offset + ).firstOrNull()?.let { annotation -> + uriHandler.openUri(annotation.item) + } + } + ) + OutlinedTextField( value = url, onValueChange = { @@ -163,7 +211,7 @@ fun PrismServerConfigDialog( .count { it.description?.startsWith("target:") == true } if (manualAppsCount > 0) { val oldUrl = initialUrl - val oldKey = app.lonecloud.prism.AppStore(context).prismApiKey + val oldKey = app.lonecloud.prism.PrismPreferences(context).prismApiKey if (!oldUrl.isNullOrBlank() && !oldKey.isNullOrBlank()) { app.lonecloud.prism.PrismServerClient.deleteAllApps( context, @@ -197,12 +245,76 @@ fun PrismServerConfigDialog( } }, dismissButton = { - TextButton(onClick = onDismiss, enabled = !isTesting) { - Text(stringResource(R.string.cancel_button)) + Row( + horizontalArrangement = Arrangement.spacedBy(8.dp) + ) { + if (initialUrl.isNotBlank()) { + TextButton( + onClick = { showClearConfirmation = true }, + enabled = !isTesting + ) { + Text( + text = stringResource(R.string.clear_server_button), + color = MaterialTheme.colorScheme.error + ) + } + } + TextButton(onClick = onDismiss, enabled = !isTesting) { + Text(stringResource(R.string.cancel_button)) + } } } ) + if (showClearConfirmation) { + val db = app.lonecloud.prism.DatabaseFactory.getDb(context) + val manualAppsCount = db.listApps() + .count { it.description?.startsWith("target:") == true } + + AlertDialog( + onDismissRequest = { showClearConfirmation = false }, + title = { Text(stringResource(R.string.clear_server_confirm_title)) }, + text = { + Text( + if (manualAppsCount > 0) { + stringResource(R.string.clear_server_confirm_message_with_apps, manualAppsCount) + } else { + stringResource(R.string.clear_server_confirm_message_no_apps) + } + ) + }, + confirmButton = { + Button( + onClick = { + if (initialUrl.isNotBlank()) { + val oldKey = app.lonecloud.prism.PrismPreferences(context).prismApiKey + if (!oldKey.isNullOrBlank() && manualAppsCount > 0) { + app.lonecloud.prism.PrismServerClient.deleteAllApps( + context, + serverUrl = initialUrl, + apiKey = oldKey + ) + } + } + onSave("", "") + showClearConfirmation = false + onDismiss() + }, + colors = androidx.compose.material3.ButtonDefaults.buttonColors( + containerColor = MaterialTheme.colorScheme.error + ) + ) { + Text(stringResource(R.string.clear_server_button)) + } + }, + dismissButton = { + TextButton(onClick = { showClearConfirmation = false }) { + Text(stringResource(R.string.cancel_button)) + } + } + ) + } + if (showServerChangeWarning) { val db = app.lonecloud.prism.DatabaseFactory.getDb(context) val manualAppsCount = db.listApps() diff --git a/app/src/main/java/app/lonecloud/prism/activities/ui/RestartServicesPreference.kt b/app/src/main/java/app/lonecloud/prism/activities/ui/RestartServicesPreference.kt index 3525524..3d8b671 100644 --- a/app/src/main/java/app/lonecloud/prism/activities/ui/RestartServicesPreference.kt +++ b/app/src/main/java/app/lonecloud/prism/activities/ui/RestartServicesPreference.kt @@ -28,7 +28,7 @@ fun RestartServicesPreference(onClick: () -> Unit) { verticalArrangement = Arrangement.spacedBy(4.dp) ) { Text( - text = stringResource(R.string.restart_service_button), + text = stringResource(R.string.reset_connection_button), style = MaterialTheme.typography.bodyLarge ) } diff --git a/app/src/main/java/app/lonecloud/prism/activities/ui/SettingsState.kt b/app/src/main/java/app/lonecloud/prism/activities/ui/SettingsState.kt index 0e50842..d96ff11 100644 --- a/app/src/main/java/app/lonecloud/prism/activities/ui/SettingsState.kt +++ b/app/src/main/java/app/lonecloud/prism/activities/ui/SettingsState.kt @@ -1,7 +1,7 @@ package app.lonecloud.prism.activities.ui import android.content.Context -import app.lonecloud.prism.AppStore +import app.lonecloud.prism.PrismPreferences data class SettingsState( val showToasts: Boolean, @@ -10,7 +10,7 @@ data class SettingsState( ) { companion object { fun from(context: Context): SettingsState { - val store = AppStore(context) + val store = PrismPreferences(context) return SettingsState( showToasts = store.showToasts, prismServerUrl = store.prismServerUrl ?: "", diff --git a/app/src/main/java/app/lonecloud/prism/api/ServerConnection.kt b/app/src/main/java/app/lonecloud/prism/api/ServerConnection.kt index d27f0d2..4da6d14 100644 --- a/app/src/main/java/app/lonecloud/prism/api/ServerConnection.kt +++ b/app/src/main/java/app/lonecloud/prism/api/ServerConnection.kt @@ -6,7 +6,7 @@ import android.os.Looper import android.util.Base64 import android.util.Log import android.widget.Toast -import app.lonecloud.prism.AppStore +import app.lonecloud.prism.PrismPreferences import app.lonecloud.prism.DatabaseFactory import app.lonecloud.prism.Distributor import app.lonecloud.prism.Distributor.sendMessage @@ -32,7 +32,7 @@ import org.unifiedpush.android.distributor.ChannelCreationStatus class ServerConnection(private val context: Context, private val releaseLock: () -> Unit) : WebSocketListener() { - private val store = AppStore(context) + private val store = PrismPreferences(context) fun start(): WebSocket { val client = OkHttpClient.Builder() @@ -107,8 +107,6 @@ class ServerConnection(private val context: Context, private val releaseLock: () } db.deleteDisabledApps() } else { - // We remove pending unregistrations - // and register pending registrations db.listDisabledChannelIds().forEach { Log.d(TAG, "Hello, unregistering $it") ClientMessage.Unregister(channelID = it).send(webSocket) @@ -226,7 +224,6 @@ class ServerConnection(private val context: Context, private val releaseLock: () if (failToUseUrlCandidate(context)) return if (!shouldRestart()) return if (SourceManager.addFail(context, webSocket)) { - // If null, we keep the worker with its 16min val delay = SourceManager.getTimeout() ?: return Log.d(TAG, "Retrying in $delay ms") RestartWorker.run(context, delay = delay) @@ -262,7 +259,6 @@ class ServerConnection(private val context: Context, private val releaseLock: () } if (!NetworkCallbackFactory.hasInternet()) { Log.d(TAG, "No Internet: do not restart") - // It will be restarted when Internet is back return false } return true diff --git a/app/src/main/java/app/lonecloud/prism/receivers/PrismConfigReceiver.kt b/app/src/main/java/app/lonecloud/prism/receivers/PrismConfigReceiver.kt index 640125b..5c56a85 100644 --- a/app/src/main/java/app/lonecloud/prism/receivers/PrismConfigReceiver.kt +++ b/app/src/main/java/app/lonecloud/prism/receivers/PrismConfigReceiver.kt @@ -3,12 +3,12 @@ package app.lonecloud.prism.receivers import android.content.BroadcastReceiver import android.content.Context import android.content.Intent -import app.lonecloud.prism.AppStore +import app.lonecloud.prism.PrismPreferences class PrismConfigReceiver : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { - val store = AppStore(context) + val store = PrismPreferences(context) when (intent.action) { ACTION_SET_PRISM_SERVER_URL -> { diff --git a/app/src/main/java/app/lonecloud/prism/receivers/RegisterBroadcastReceiver.kt b/app/src/main/java/app/lonecloud/prism/receivers/RegisterBroadcastReceiver.kt index 2684188..1541c71 100644 --- a/app/src/main/java/app/lonecloud/prism/receivers/RegisterBroadcastReceiver.kt +++ b/app/src/main/java/app/lonecloud/prism/receivers/RegisterBroadcastReceiver.kt @@ -3,7 +3,7 @@ package app.lonecloud.prism.receivers import android.content.Context -import app.lonecloud.prism.AppStore +import app.lonecloud.prism.PrismPreferences import app.lonecloud.prism.Distributor import app.lonecloud.prism.callback.NetworkCallbackFactory import org.unifiedpush.android.distributor.receiver.DistributorReceiver @@ -16,5 +16,5 @@ class RegisterBroadcastReceiver : DistributorReceiver() { override fun hasInternet(context: Context): Boolean = NetworkCallbackFactory.hasInternet() - override fun showToasts(context: Context): Boolean = AppStore(context).showToasts + override fun showToasts(context: Context): Boolean = PrismPreferences(context).showToasts } diff --git a/app/src/main/java/app/lonecloud/prism/services/MigrationManager.kt b/app/src/main/java/app/lonecloud/prism/services/MigrationManager.kt index 199af35..bce9437 100644 --- a/app/src/main/java/app/lonecloud/prism/services/MigrationManager.kt +++ b/app/src/main/java/app/lonecloud/prism/services/MigrationManager.kt @@ -1,11 +1,11 @@ package app.lonecloud.prism.services import android.content.Context -import app.lonecloud.prism.AppStore +import app.lonecloud.prism.PrismPreferences import app.lonecloud.prism.Distributor import org.unifiedpush.android.distributor.MigrationManager as MManager class MigrationManager : MManager() { override val distrib = Distributor - override fun getStore(context: Context): MigrationStore = AppStore(context) + override fun getStore(context: Context): MigrationStore = PrismPreferences(context) } diff --git a/app/src/main/java/app/lonecloud/prism/services/PrismInternalService.kt b/app/src/main/java/app/lonecloud/prism/services/PrismInternalService.kt index 60199d0..e51726b 100644 --- a/app/src/main/java/app/lonecloud/prism/services/PrismInternalService.kt +++ b/app/src/main/java/app/lonecloud/prism/services/PrismInternalService.kt @@ -3,7 +3,7 @@ package app.lonecloud.prism.services import android.content.pm.PackageManager import android.os.Bundle import androidx.core.graphics.drawable.toBitmap -import app.lonecloud.prism.AppStore +import app.lonecloud.prism.PrismPreferences import app.lonecloud.prism.DatabaseFactory import app.lonecloud.prism.Distributor import org.unifiedpush.android.distributor.Database @@ -28,7 +28,7 @@ class PrismInternalService : InternalService() { override val distributor: UnifiedPushDistributor = Distributor override val db: Database by lazy { DatabaseFactory.getDb(this) } - private val appStore by lazy { AppStore(this) } + private val appStore by lazy { PrismPreferences(this) } override var themeDynamicColors: Boolean get() = appStore.dynamicColors @@ -44,9 +44,7 @@ class PrismInternalService : InternalService() { override fun getDebugInfo(): String = "Prism Distributor" - override fun runAppMigration() { - // No app migration needed for Prism currently - } + override fun runAppMigration() {} override fun account(): IAccount = object : IAccount { override fun get(): String? = null @@ -55,22 +53,20 @@ class PrismInternalService : InternalService() { } override fun api(): IApi = object : IApi { - override fun newPushServer(url: String?) { - // Prism uses fixed Mozilla server, but can be customized - } + override fun newPushServer(url: String?) {} override fun getUrl(): String = appStore.apiUrl } override fun registrations() = object : IRegistrations { override fun delete(registrations: List) { registrations.forEach { token -> - distributor.deleteApp(context, token) + distributor.deleteApp(this@PrismInternalService, token) } } override fun list(): List = db .listApps().map { - val pm = context.packageManager + val pm = this@PrismInternalService.packageManager val isManualApp = it.description?.startsWith("target:") == true val targetPackage = if (isManualApp) { @@ -96,22 +92,20 @@ class PrismInternalService : InternalService() { vapidKey = it.vapidKey, title = displayTitle, msgCount = it.msgCount, - description = if (it.packageName == context.packageName) { + description = if (it.packageName == this@PrismInternalService.packageName) { Description.LocalChannel } else { Description.StringDescription(packageToResolve) }, icon = getApplicationIcon(packageToResolve)?.toBitmap(), - isLocal = it.packageName == context.packageName + isLocal = it.packageName == this@PrismInternalService.packageName ) } override fun copyEndpoint(token: String?) { - super@PrismInternalService.registrations().copyEndpoint(token) } override fun addLocal(title: String) { - super@PrismInternalService.registrations().addLocal(title) } } } diff --git a/app/src/main/java/app/lonecloud/prism/services/RestartWorker.kt b/app/src/main/java/app/lonecloud/prism/services/RestartWorker.kt index c2306f5..80c8fcf 100644 --- a/app/src/main/java/app/lonecloud/prism/services/RestartWorker.kt +++ b/app/src/main/java/app/lonecloud/prism/services/RestartWorker.kt @@ -5,7 +5,7 @@ package app.lonecloud.prism.services import android.content.Context import android.util.Log import androidx.work.* -import app.lonecloud.prism.AppStore +import app.lonecloud.prism.PrismPreferences import app.lonecloud.prism.Distributor import app.lonecloud.prism.api.MessageSender import app.lonecloud.prism.callback.NetworkCallbackFactory @@ -20,7 +20,6 @@ class RestartWorker(ctx: Context, params: WorkerParameters) : Worker(ctx, params */ @Suppress("ReturnCount") override fun doWork(): Result { - // We avoid running twice at the same time synchronized(lock) { Log.d(TAG, "Working [$id]") if (!NetworkCallbackFactory.hasInternet()) { @@ -29,8 +28,6 @@ class RestartWorker(ctx: Context, params: WorkerParameters) : Worker(ctx, params } if (SourceManager.isRunningWithoutFailure) { Log.d(TAG, "Running without failure") - // We send a ping, if it fails it will restart this worker, and wont - // pass this check MessageSender.ping(applicationContext) return Result.success() } @@ -44,10 +41,7 @@ class RestartWorker(ctx: Context, params: WorkerParameters) : Worker(ctx, params private val lock = Object() override fun canRun(context: Context): Boolean { - // We don't have any credential requirement, if we don't have - // a uaid yet, it will be created during the initial sync - // So, as soon as the user hasn't migrated, we can run - return !AppStore(context).migrated + return !PrismPreferences(context).migrated } override fun isServiceStarted(context: Context): Boolean = FgService.isServiceStarted() diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index e5def83..997dc63 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -47,7 +47,10 @@ Add manual app Debug Information Configure Prism Server + Self-host a Prism server to unlock manual app registrations. Otherwise, this distributor works normally with UnifiedPush apps. + https://github.com/lone-cloud/prism Prism server configured + %1$s (v%2$s) Prism server not configured Server URL https://prism.example.com @@ -57,7 +60,11 @@ Connection successful Connection failed Test and Save - Restart Service + Clear + Remove Prism Server? + This will remove your Prism server configuration. + You have %d manual app registration(s). Clearing the server will delete them from the server and remove the configuration. + Reset Connection Notify when apps register Dynamic Colors