Skip to content

Commit

Permalink
feat: push notification (#406)
Browse files Browse the repository at this point in the history
* refactor: initialize in the top widget

Moved some initialization processes from `BootState` notifier to the
`_init` method in `Aria` widget.
Also moved the initialization of `RustLib` into the method.
This may shorten the startup duration.

* refactor: decide whether to redirect in notifier

* refactor: add nameOrUsername getter

* feat: show better message for DioException

If network request failed, show the error response with `ErrorMessage`
widget.

* feat: add SwRegisterDialog

The `sw/register` endpoint of Misskey is marked `secure` and cannot be
accessed using an access token issued with MiAuth.
This dialog generates an AiScript code that sends the request and
prompts the user to run it on the scratchpad of Misskey Web.
Once the code is executed, the scratchpad shows a dialog with the
response.
Finally, by pasting the response, Aria can indirectly utilise the
endpoint.

* feat: subscribe to push notification

Added a page to register to push notifications.
When the switch is enabled, it generates keys that are used to later
decrypt Web Push messages sent from Misskey.
The keys and an endpoint to which Misskey server sends notifications are
then sent.

The endpoint must be unique among all subscriptions.
If a user is on an Android device and chooses an external UnifiedPush
distributor like ntfy, that distributor will provide the endpoint.
In this case, encrypted Web Push messages will be distributed, and Aria
needs to decrypt that within the app, so the keys will be saved on the
device.
If the user doesn't have any distributor apps, chooses the internal
distributor, or is on iOS, the endpoint directs to [Misskey Web Push
Proxy](https://github.com/poppingmoon/misskey-web-push-proxy).
The keys will be sent to the proxy to allow it to decrypt the messages
on the server.
Generation of the endpoint will be implemented in later commits.

After that, the endpoint will be stored on the device for later
unsubscription.

* feat: unsubscribe to push notification

* feat: get UnifiedPush endpoint

For Android, use [UnifiedPush](https://unifiedpush.org) to get the
target endpoint to which Misskey servers send notifications.
If multiple distributor apps are installed on the user device, shows a
dialog to select one of them.

* feat: use EmbeddedDistributor to get FCM token

Added [Android FOSS Embedded FCM Distributor]
(https://codeberg.org/UnifiedPush/android-embedded_fcm_distributor) for
a fallback of UnifiedPush Distributors.
If the user does not have any distributor apps installed, this will be
automatically selected.
Otherwise, it will appear as one of a distributors that the user can
choose.

According to the official documentation, the `getEndpoint` function is
supposed to return an endpoint.
However, for Aria, it has been modified to return an FCM token instead,
since the actual endpoint will be generated on the Flutter side.

The token is prefixed to indicate that the returned value is from the
embedded distributor or from an external distributor.
On the Flutter side, the prefix is removed and the token will be sent to
the proxy to allow it to send notifications via FCM.

* feat: request notification permissions for Android

* feat: get APNs device token

* feat: request notification permissions for iOS

* feat: show notification for Android

* feat: add localization for iOS notification

* feat: save user id of the account

Added the `UserIdsNotifier` which saves the `userId` associated with the
account.
This will be used to determine which account the notification was sent
to.

The function to save the id will be called on signing in and subscribing
to push notifications.
This ensures that the id is available when a push notification is
received, even if the user was signed in before this feature was added.

* feat: redirect on notification tap

* feat: unsubscribe on sign out
  • Loading branch information
poppingmoon authored Oct 16, 2024
1 parent f63a95c commit cd9d2fe
Show file tree
Hide file tree
Showing 63 changed files with 12,292 additions and 87 deletions.
4 changes: 3 additions & 1 deletion android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,9 @@ flutter {
source '../..'
}

dependencies {}
dependencies {
implementation 'org.unifiedpush.android:foss-embedded-fcm-distributor:1.0.0'
}

ext.abiCodes = ["x86_64": 1, "armeabi-v7a": 2, "arm64-v8a": 3]
import com.android.build.OutputFile
Expand Down
10 changes: 10 additions & 0 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,16 @@
<action android:name="android.intent.action.MEDIA_BUTTON" />
</intent-filter>
</receiver>
<receiver
android:enabled="true"
android:name=".EmbeddedDistributor"
android:exported="false">
<intent-filter>
<action android:name="org.unifiedpush.android.distributor.feature.BYTES_MESSAGE"/>
<action android:name="org.unifiedpush.android.distributor.REGISTER"/>
<action android:name="org.unifiedpush.android.distributor.UNREGISTER"/>
</intent-filter>
</receiver>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.poppingmoon.aria

import android.content.Context
import org.unifiedpush.android.foss_embedded_fcm_distributor.EmbeddedDistributorReceiver

// This value must be the same as `fcmTokenPrefix` at lib/constant/push.dart.
const val fcmTokenPrefix = "fcmToken:"

class EmbeddedDistributor: EmbeddedDistributorReceiver() {
override val googleProjectNumber = "674873867538" // This value comes from the google-services.json

override fun getEndpoint(context: Context, token: String, instance: String): String {
return "$fcmTokenPrefix$token"
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions android/app/src/main/res/raw/keep.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"
tools:keep="@drawable/ic_notification" />
Loading

0 comments on commit cd9d2fe

Please sign in to comment.