mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-03-31 16:15:55 +00:00
Register for push notifications with VAPID key
This commit is contained in:
@@ -270,11 +270,15 @@ class SimplexApp: Application(), LifecycleEventObserver {
|
||||
// Prevents from showing "Enable notifications" alert when onboarding wasn't complete yet
|
||||
if (chatModel.controller.appPrefs.onboardingStage.get() == OnboardingStage.OnboardingComplete) {
|
||||
SimplexService.showBackgroundServiceNoticeIfNeeded()
|
||||
PushManager.initStart(context)
|
||||
if (appPrefs.notificationsMode.get() == NotificationsMode.SERVICE)
|
||||
withBGApi {
|
||||
when (appPrefs.notificationsMode.get()) {
|
||||
NotificationsMode.SERVICE -> withBGApi {
|
||||
platform.androidServiceStart()
|
||||
}
|
||||
NotificationsMode.INSTANT -> withBGApi {
|
||||
PushManager.initStart(context)
|
||||
}
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,12 +24,14 @@ import dev.icerock.moko.resources.compose.painterResource
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
import kotlinx.coroutines.*
|
||||
import org.unifiedpush.android.connector.UnifiedPush
|
||||
import androidx.core.net.toUri
|
||||
|
||||
/**
|
||||
* Object with functions to interact with push services
|
||||
*/
|
||||
object PushManager {
|
||||
private const val TAG = "PushManager"
|
||||
private val VAPID_REGEX = Regex("^[A-Za-z0-9_-]{87}(=+)?$")
|
||||
|
||||
/**
|
||||
* Check if a NTF server is setup and ask user's push distributor
|
||||
@@ -42,12 +44,20 @@ object PushManager {
|
||||
suspend fun initUnifiedPush(context: Context, scope: CoroutineScope, onSuccess: () -> Unit) {
|
||||
val rh = chatModel.remoteHostId()
|
||||
val userServers = getUserServers(rh) ?: listOf()
|
||||
if (!userServers.hasNtfServer()) {
|
||||
val userNtfServer = userServers.userNtfServer()
|
||||
?: run {
|
||||
Log.d(TAG, "User doesn't have any NTF server")
|
||||
showMissingNTFDialog(scope, rh, userServers)
|
||||
// After coming back from the server view, users will have to click on "Instant" again
|
||||
return
|
||||
}
|
||||
val vapid = userNtfServer.vapid()
|
||||
?: run {
|
||||
Log.d(TAG, "User NTF Server doesn't have any VAPID FP")
|
||||
showNTFNoVAPIDDialog(scope, rh, userServers)
|
||||
// After coming back from the server view, users will have to click on "Instant" again
|
||||
return
|
||||
}
|
||||
val distributors = UnifiedPush.getDistributors(context)
|
||||
when (distributors.size) {
|
||||
0 -> {
|
||||
@@ -57,7 +67,7 @@ object PushManager {
|
||||
1 -> {
|
||||
Log.d(TAG, "Found only one distributor installed")
|
||||
UnifiedPush.saveDistributor(context, distributors.first())
|
||||
register(context)
|
||||
register(context, vapid)
|
||||
onSuccess()
|
||||
}
|
||||
else -> {
|
||||
@@ -65,7 +75,7 @@ object PushManager {
|
||||
showSelectPushServiceIntroDialog {
|
||||
showSelectPushServiceDialog(context, distributors) {
|
||||
UnifiedPush.saveDistributor(context, it)
|
||||
register(context)
|
||||
register(context, vapid)
|
||||
onSuccess()
|
||||
}
|
||||
}
|
||||
@@ -79,27 +89,40 @@ object PushManager {
|
||||
* To run when the app starts; call [chat.simplex.app.PushService.onUnregistered]
|
||||
* if the distributor is uninstalled
|
||||
*/
|
||||
fun initStart(context: Context) {
|
||||
suspend fun initStart(context: Context) {
|
||||
Log.d(TAG, "Init UnifiedPush during app startup")
|
||||
//TODO: limit to once a day to reduce registrations to ntf server ?
|
||||
UnifiedPush.getAckDistributor(context)?.let {
|
||||
register(context)
|
||||
val vapid = getUserServers(chatModel.remoteHostId())
|
||||
?.userNtfServer()
|
||||
?.vapid()
|
||||
// Unregister if the user deleted the ntf server or change it with one without vapid
|
||||
?: return UnifiedPush.unregister(context)
|
||||
register(context, vapid)
|
||||
}
|
||||
}
|
||||
|
||||
private fun register(context: Context) {
|
||||
// TODO: add VAPID
|
||||
UnifiedPush.register(context)
|
||||
private fun register(context: Context, vapid: String) {
|
||||
UnifiedPush.register(context, vapid = vapid)
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if any NTF server is recorded
|
||||
* Get user NTF server
|
||||
*/
|
||||
private fun List<UserOperatorServers>.hasNtfServer(): Boolean {
|
||||
// TODO: check if ntf server has a VAPID key
|
||||
return this.any { it.ntfServers.any { s -> s.enabled } }
|
||||
private fun List<UserOperatorServers>.userNtfServer(): UserServer? {
|
||||
return this.firstNotNullOfOrNull {
|
||||
it.ntfServers.firstOrNull { s -> s.enabled }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get vapid fingerprint from the URI
|
||||
*/
|
||||
private fun UserServer.vapid(): String ? = server
|
||||
.toUri()
|
||||
.getQueryParameter("vapid")
|
||||
?.takeIf { VAPID_REGEX.matches(it) }
|
||||
|
||||
/**
|
||||
* Show a dialog to inform about missing NTF server
|
||||
*/
|
||||
@@ -136,6 +159,41 @@ object PushManager {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a dialog to inform about missing VAPID with the NTF server
|
||||
*/
|
||||
private fun showNTFNoVAPIDDialog(scope: CoroutineScope, rh: Long?, userServers: List<UserOperatorServers>) = AlertManager.shared.showAlert {
|
||||
AlertDialog(
|
||||
onDismissRequest = AlertManager.shared::hideAlert,
|
||||
title = {
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
Icon(
|
||||
painterResource(MR.images.ic_warning),
|
||||
contentDescription = null, // The icon doesn't add any meaning and must not be transcripted with screen readers
|
||||
)
|
||||
Text(
|
||||
stringResource(MR.strings.icon_descr_instant_notifications),
|
||||
fontWeight = FontWeight.Bold
|
||||
)
|
||||
}
|
||||
},
|
||||
text = {
|
||||
Text(stringResource(MR.strings.warning_push_needs_ntf_server_with_vapid))
|
||||
},
|
||||
// Go to user's servers settings
|
||||
confirmButton = {
|
||||
TextButton(onClick = {
|
||||
AlertManager.shared.hideAlert()
|
||||
showAddServerDialog(scope, rh, userServers)
|
||||
}) { Text(stringResource(MR.strings.smp_servers_add)) }
|
||||
},
|
||||
// Ignore
|
||||
dismissButton = {
|
||||
TextButton(onClick = AlertManager.shared::hideAlert) { Text(stringResource(android.R.string.cancel)) }
|
||||
},
|
||||
shape = RoundedCornerShape(corner = CornerSize(25.dp))
|
||||
)
|
||||
}
|
||||
/**
|
||||
* Dialog to add a server, manually or with a QR code
|
||||
*/
|
||||
|
||||
@@ -277,7 +277,9 @@
|
||||
<string name="notification_contact_connected">Connected</string>
|
||||
<string name="error_showing_desktop_notification">Error showing notification, contact developers.</string>
|
||||
<string name="warning_push_needs_ntf_server">You first need to set a NTF server to get push notifications.\n\nIt will send the notifications to your push provider.</string>
|
||||
<string name="warning_push_needs_ntf_server_with_vapid">Your NTF server doesn\'t support VAPID, which is required to get push notifications.</string>
|
||||
<string name="warning_push_needs_push_service">You don\'t have any push service installed on your device.\n\nPlease installed one and try again.\n\nFor more information, visit\ </string>
|
||||
<string name="warning_ntf_server_changed">Your NTF server has been removed or has changed and doesn\'t support VAPID, which is required to get push notifications.</string>
|
||||
<string name="select_push_service">Select Push Service</string>
|
||||
<string name="select_push_service_intro">Multiple push services are installed on your system, please select the service you wish to use.</string>
|
||||
<string name="unifiedpush_unregistered">SimpleX is no longer registered with your UnifiedPush distributor. The distributor may have been uninstalled or been logged out. You should reset your notifications settings.</string>
|
||||
|
||||
@@ -12,7 +12,7 @@ constraints: zip +disable-bzip2 +disable-zstd
|
||||
source-repository-package
|
||||
type: git
|
||||
location: https://codeberg.org/s1m/sxmq.git
|
||||
tag: a9ef465c0af3829c58fb5e45627d9673aa5b1ee7
|
||||
tag: f28a2052ae88c59653993ca0e409231b5ed00b11
|
||||
|
||||
-- source-repository-package
|
||||
-- type: git
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"https://codeberg.org/s1m/sxmq.git"."a9ef465c0af3829c58fb5e45627d9673aa5b1ee7" = "5921e554cd08372335a415d7c6edcb8d83893f77fffcf5370edaaff7fe47bea6";
|
||||
"https://codeberg.org/s1m/sxmq.git"."f28a2052ae88c59653993ca0e409231b5ed00b11" = "86128d5cdb952e28460b4450042622807e0b683de5598817cac80e85ecee8c3f";
|
||||
"https://github.com/simplex-chat/simplexmq.git"."d352d518c2b3a42bc7a298954dde799422e1457f" = "1rha84pfpaqx3mf218szkfra334vhijqf17hanxqmp1sicfbf1x3";
|
||||
"https://github.com/simplex-chat/hs-socks.git"."a30cc7a79a08d8108316094f8f2f82a0c5e1ac51" = "0yasvnr7g91k76mjkamvzab2kvlb1g5pspjyjn2fr6v83swjhj38";
|
||||
"https://github.com/simplex-chat/direct-sqlcipher.git"."f814ee68b16a9447fbb467ccc8f29bdd3546bfd9" = "1ql13f4kfwkbaq7nygkxgw84213i0zm7c1a8hwvramayxl38dq5d";
|
||||
|
||||
Reference in New Issue
Block a user