refactor: rename mattermost_push_plugin to nexo_messaging package and update branding

This commit is contained in:
toki 2026-05-26 20:19:04 +09:00
parent f6c86fb7a8
commit ec80f64dd8
39 changed files with 136 additions and 135 deletions

1
.gitignore vendored
View file

@ -22,6 +22,7 @@ Thumbs.db
key.properties
# Agent/local scratch
agent-task/
agent-task/archive/
agent-ops/rules/private/

View file

@ -12,7 +12,7 @@ the messaging/notification package contract:
- event-channel delivery from native code to Dart
- notification-open routing callbacks
- Android manifest merge behavior
- manual Firebase FCM and Mattermost ACK smoke testing
- manual Firebase FCM and nexo server ACK smoke testing
Product-specific UI should stay small until Nexo's messaging surface is ready.
This app should keep the minimum surface needed to prove package integration.

View file

@ -372,7 +372,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.tokilabs.mattermostPushPluginExample;
PRODUCT_BUNDLE_IDENTIFIER = com.tokilabs.nexo.client;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
@ -388,7 +388,7 @@
CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.tokilabs.mattermostPushPluginExample.RunnerTests;
PRODUCT_BUNDLE_IDENTIFIER = com.tokilabs.nexo.client.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
@ -405,7 +405,7 @@
CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.tokilabs.mattermostPushPluginExample.RunnerTests;
PRODUCT_BUNDLE_IDENTIFIER = com.tokilabs.nexo.client.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
@ -420,7 +420,7 @@
CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.tokilabs.mattermostPushPluginExample.RunnerTests;
PRODUCT_BUNDLE_IDENTIFIER = com.tokilabs.nexo.client.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
@ -551,7 +551,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.tokilabs.mattermostPushPluginExample;
PRODUCT_BUNDLE_IDENTIFIER = com.tokilabs.nexo.client;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
@ -573,7 +573,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.tokilabs.mattermostPushPluginExample;
PRODUCT_BUNDLE_IDENTIFIER = com.tokilabs.nexo.client;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;

View file

@ -7,7 +7,7 @@
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
<string>Mattermost Push Plugin</string>
<string>Nexo Client</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>

View file

@ -3,7 +3,7 @@ import UIKit
import XCTest
@testable import mattermost_push_plugin
@testable import nexo_messaging
// This demonstrates a simple unit test of the Swift portion of this plugin's implementation.
//
@ -12,7 +12,7 @@ import XCTest
class RunnerTests: XCTestCase {
func testGetPlatformVersion() {
let plugin = MattermostPushPlugin()
let plugin = NexoMessagingPlugin()
let call = FlutterMethodCall(methodName: "getPlatformVersion", arguments: [])

View file

@ -12,5 +12,5 @@ import nexo_messaging
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin"))
FLTFirebaseMessagingPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseMessagingPlugin"))
MattermostPushPlugin.register(with: registry.registrar(forPlugin: "MattermostPushPlugin"))
NexoMessagingPlugin.register(with: registry.registrar(forPlugin: "NexoMessagingPlugin"))
}

View file

@ -385,7 +385,7 @@
CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.tokilabs.mattermostPushPluginExample.RunnerTests;
PRODUCT_BUNDLE_IDENTIFIER = com.tokilabs.nexo.client.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/nexo_client.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/nexo_client";
@ -399,7 +399,7 @@
CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.tokilabs.mattermostPushPluginExample.RunnerTests;
PRODUCT_BUNDLE_IDENTIFIER = com.tokilabs.nexo.client.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/nexo_client.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/nexo_client";
@ -413,7 +413,7 @@
CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.tokilabs.mattermostPushPluginExample.RunnerTests;
PRODUCT_BUNDLE_IDENTIFIER = com.tokilabs.nexo.client.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/nexo_client.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/nexo_client";

View file

@ -8,7 +8,7 @@
PRODUCT_NAME = nexo_client
// The application's bundle identifier
PRODUCT_BUNDLE_IDENTIFIER = com.tokilabs.mattermostPushPluginExample
PRODUCT_BUNDLE_IDENTIFIER = com.tokilabs.nexo.client
// The copyright displayed in application information
PRODUCT_COPYRIGHT = Copyright © 2026 com.tokilabs. All rights reserved.

View file

@ -3,7 +3,7 @@ import FlutterMacOS
import XCTest
@testable import mattermost_push_plugin
@testable import nexo_messaging
// This demonstrates a simple unit test of the Swift portion of this plugin's implementation.
//
@ -12,7 +12,7 @@ import XCTest
class RunnerTests: XCTestCase {
func testGetPlatformVersion() {
let plugin = MattermostPushPlugin()
let plugin = NexoMessagingPlugin()
let call = FlutterMethodCall(methodName: "getPlatformVersion", arguments: [])

View file

@ -1,12 +1,12 @@
# messaging_flutter
# nexo_messaging
Android-first Flutter plugin for Nexo's Mattermost-compatible messaging and
push-notification runtime.
Android-first Flutter plugin for the nexo messaging and push-notification
runtime.
The plugin owns the push-notification domain that should not be duplicated in
each consuming app: native FCM handling, notification display, notification tap
events, inline replies, dismiss handling, ACK delivery, device-token storage,
auth-token storage, and Mattermost signing-key storage.
auth-token storage, and server signing-key storage.
## Platform Status
@ -36,7 +36,7 @@ separate product app.
```mermaid
graph TD
A[Mattermost Server] -->|Secure JWT Push| B(Android FCM Service)
A[nexo Server] -->|Secure JWT Push| B(Android FCM Service)
B -->|Verify signing key| C{Valid?}
C -->|Yes| D[Store payload and build notification]
C -->|No| E[Drop push]
@ -56,10 +56,10 @@ integration:
1. Configure Firebase for the host app, including `google-services.json` under
`android/app/`.
2. Initialize Firebase as required by the host app before push registration.
3. Call `MattermostPushPlugin.instance.initialize()` during app startup.
3. Call `NexoMessagingPlugin.instance.initialize()` during app startup.
4. Save auth tokens and signing keys after login.
5. Clear auth tokens on logout.
6. Send the formatted device token to the Mattermost server.
6. Send the formatted device token to the nexo server.
7. Connect notification-open callbacks to the host app router.
## Installation
@ -69,7 +69,7 @@ dependency:
```yaml
dependencies:
mattermost_push_plugin:
nexo_messaging:
path: ../../packages/messaging_flutter
```
@ -81,19 +81,19 @@ the branch, tag, or commit according to your release process.
Import the public API:
```dart
import 'package:mattermost_push_plugin/mattermost_push_plugin.dart';
import 'package:nexo_messaging/nexo_messaging.dart';
```
Initialize the plugin:
```dart
await MattermostPushPlugin.instance.initialize();
await NexoMessagingPlugin.instance.initialize();
```
Listen to raw notification events:
```dart
MattermostPushPlugin.instance.onNotification.listen((data) {
NexoMessagingPlugin.instance.onNotification.listen((data) {
// data includes the native payload plus a push type.
});
```
@ -101,7 +101,7 @@ MattermostPushPlugin.instance.onNotification.listen((data) {
Listen to notification-open events:
```dart
MattermostPushPlugin.instance.onNotificationOpened.listen((event) {
NexoMessagingPlugin.instance.onNotificationOpened.listen((event) {
final serverUrl = event.serverUrl;
final channelId = event.channelId;
final rootId = event.rootId;
@ -111,14 +111,14 @@ MattermostPushPlugin.instance.onNotificationOpened.listen((event) {
Register navigation callbacks:
```dart
MattermostPushPlugin.instance.onNavigateToChannel = (
NexoMessagingPlugin.instance.onNavigateToChannel = (
String serverUrl,
String channelId,
) {
// Navigate to the channel in the host app.
};
MattermostPushPlugin.instance.onNavigateToThread = (
NexoMessagingPlugin.instance.onNavigateToThread = (
String serverUrl,
String rootId,
) {
@ -129,31 +129,31 @@ MattermostPushPlugin.instance.onNavigateToThread = (
Handle device-token registration:
```dart
MattermostPushPlugin.instance.onDeviceTokenReady = (String deviceToken) {
NexoMessagingPlugin.instance.onDeviceTokenReady = (String deviceToken) {
// Example format: android_rn-v2:YOUR_FCM_TOKEN
// Send this token to the Mattermost server.
// Send this token to the nexo server.
};
```
Store credentials and signing keys:
```dart
await MattermostPushPlugin.instance.setAuthToken(
'https://mattermost.example.com',
await NexoMessagingPlugin.instance.setAuthToken(
'https://nexo.example.com',
'USER_AUTH_TOKEN',
identifier: 'user_session_id',
);
await MattermostPushPlugin.instance.setSigningKey(
'https://mattermost.example.com',
await NexoMessagingPlugin.instance.setSigningKey(
'https://nexo.example.com',
'SERVER_PUBLIC_SIGNING_KEY',
);
await MattermostPushPlugin.instance.clearAuthToken(
'https://mattermost.example.com',
await NexoMessagingPlugin.instance.clearAuthToken(
'https://nexo.example.com',
);
final token = await MattermostPushPlugin.instance.getDeviceToken();
final token = await NexoMessagingPlugin.instance.getDeviceToken();
```
## Event Types
@ -162,7 +162,7 @@ The Dart API currently recognizes these native event types:
| Type | Meaning |
| --- | --- |
| `message` | A Mattermost message notification |
| `message` | A nexo message notification |
| `clear` | Notification clear or dismiss event |
| `session` | Session-related event |
| `token_refresh` | Device-token refresh event |
@ -176,7 +176,7 @@ available.
## Android Notes
The Android manifest declares the plugin's own
`MattermostFirebaseMessagingService` and removes the default FlutterFire
`NexoFirebaseMessagingService` and removes the default FlutterFire
messaging components with `tools:node="remove"`. This avoids duplicate FCM
service registration when the host app also depends on `firebase_messaging`.
@ -231,19 +231,19 @@ Use the repository tests as the source of truth for plugin behavior:
4. `apps/client/integration_test/` covers real plugin registration,
method-channel behavior, event-channel behavior, notification-open routing,
and manifest integration on a device or emulator using the test/debug injection path.
5. Manual smoke tests cover true Firebase FCM delivery and real Mattermost ACK
5. Manual smoke tests cover true Firebase FCM delivery and real nexo server ACK
flows because they depend on external infrastructure.
## Manual Smoke Checklist
Use this checklist before promoting a plugin change to a consuming app:
- [ ] FCM payload wakes `MattermostFirebaseMessagingService`.
- [ ] Valid Mattermost push payload passes signing-key verification.
- [ ] FCM payload wakes `NexoFirebaseMessagingService`.
- [ ] Valid nexo push payload passes signing-key verification.
- [ ] Invalid or unsigned payload is dropped.
- [ ] System notification displays the expected title, message, avatar, and CRT
threading behavior.
- [ ] ACK request is sent to the Mattermost server and receives a successful
- [ ] ACK request is sent to the nexo server and receives a successful
response.
- [ ] Tapping a notification launches or resumes the app and emits
`onNotificationOpened`.

View file

@ -1,4 +1,4 @@
group = "com.tokilabs.mattermost_push_plugin"
group = "com.tokilabs.nexo.messaging"
version = "1.0-SNAPSHOT"
buildscript {
@ -29,7 +29,7 @@ plugins {
}
android {
namespace = "com.tokilabs.mattermost_push_plugin"
namespace = "com.tokilabs.nexo.messaging"
compileSdk = 36

View file

@ -1 +1 @@
rootProject.name = 'mattermost_push_plugin'
rootProject.name = 'nexo_messaging'

View file

@ -1 +1 @@
rootProject.name = 'mattermost_push_plugin'
rootProject.name = 'nexo_messaging'

View file

@ -23,7 +23,7 @@
tools:node="remove" />
<service
android:name="com.tokilabs.mattermost_push_plugin.MattermostFirebaseMessagingService"
android:name="com.tokilabs.nexo.messaging.NexoFirebaseMessagingService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
@ -31,12 +31,12 @@
</service>
<service
android:name="com.tokilabs.mattermost_push_plugin.NotificationDismissService"
android:name="com.tokilabs.nexo.messaging.NotificationDismissService"
android:enabled="true"
android:exported="false" />
<receiver
android:name="com.tokilabs.mattermost_push_plugin.NotificationReplyBroadcastReceiver"
android:name="com.tokilabs.nexo.messaging.NotificationReplyBroadcastReceiver"
android:enabled="true"
android:exported="false" />
</application>

View file

@ -1,4 +1,4 @@
package com.tokilabs.mattermost_push_plugin;
package com.tokilabs.nexo.messaging;
import android.app.IntentService;
import android.content.Context;
@ -6,7 +6,7 @@ import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import com.tokilabs.mattermost_push_plugin.helpers.NotificationHelper;
import com.tokilabs.nexo.messaging.helpers.NotificationHelper;
@SuppressWarnings("deprecation")
public class NotificationDismissService extends IntentService {

View file

@ -1,4 +1,4 @@
package com.tokilabs.mattermost_push_plugin;
package com.tokilabs.nexo.messaging;
import android.app.Notification;
import android.app.NotificationManager;
@ -13,8 +13,8 @@ import android.util.Log;
import androidx.core.app.NotificationCompat;
import androidx.core.app.Person;
import com.tokilabs.mattermost_push_plugin.helpers.CustomPushNotificationHelper;
import com.tokilabs.mattermost_push_plugin.helpers.Network;
import com.tokilabs.nexo.messaging.helpers.CustomPushNotificationHelper;
import com.tokilabs.nexo.messaging.helpers.Network;
import org.json.JSONException;
import org.json.JSONObject;

View file

@ -1,9 +1,9 @@
package com.tokilabs.mattermost_push_plugin;
package com.tokilabs.nexo.messaging;
import android.os.Bundle;
import android.util.Log;
import com.tokilabs.mattermost_push_plugin.helpers.Network;
import com.tokilabs.nexo.messaging.helpers.Network;
import org.json.JSONObject;

View file

@ -1,4 +1,4 @@
package com.tokilabs.mattermost_push_plugin.helpers;
package com.tokilabs.nexo.messaging.helpers;
import android.annotation.SuppressLint;
import android.app.Notification;
@ -29,10 +29,10 @@ import androidx.core.app.Person;
import androidx.core.app.RemoteInput;
import androidx.core.graphics.drawable.IconCompat;
import com.tokilabs.mattermost_push_plugin.NotificationDismissService;
import com.tokilabs.mattermost_push_plugin.NotificationReplyBroadcastReceiver;
import com.tokilabs.mattermost_push_plugin.R;
import com.tokilabs.mattermost_push_plugin.helpers.db.MattermostDatabase;
import com.tokilabs.nexo.messaging.NotificationDismissService;
import com.tokilabs.nexo.messaging.NotificationReplyBroadcastReceiver;
import com.tokilabs.nexo.messaging.R;
import com.tokilabs.nexo.messaging.helpers.db.NexoMessageDatabase;
import java.io.IOException;
import java.security.KeyFactory;
@ -59,7 +59,7 @@ public class CustomPushNotificationHelper {
public static final String PUSH_TYPE_CLEAR = "clear";
public static final String PUSH_TYPE_SESSION = "session";
public static final String CATEGORY_CAN_REPLY = "CAN_REPLY";
public static final String SIGNING_PREFS = "mattermost_signing";
public static final String SIGNING_PREFS = "nexo_signing";
private static final String TAG = "PushNotifHelper";
@ -141,7 +141,7 @@ public class CustomPushNotificationHelper {
return true;
}
MattermostDatabase db = dbHelper.getDatabaseForServer(context, serverUrl);
NexoMessageDatabase db = dbHelper.getDatabaseForServer(context, serverUrl);
if (db == null) {
Log.i(TAG, "Cannot access the server database, skipping signature check");
return true;
@ -472,7 +472,7 @@ public class CustomPushNotificationHelper {
} else {
DatabaseHelper dbHelper = DatabaseHelper.Companion.getInstance();
if (dbHelper != null) {
MattermostDatabase db = dbHelper.getDatabaseForServer(context, serverUrl);
NexoMessageDatabase db = dbHelper.getDatabaseForServer(context, serverUrl);
if (db != null) {
lastUpdateAt = db.getLastPictureUpdate(userId);
if (lastUpdateAt == null) lastUpdateAt = 0.0;

View file

@ -1,4 +1,4 @@
package com.tokilabs.mattermost_push_plugin
package com.tokilabs.nexo.messaging
import android.app.Activity
import android.app.Application

View file

@ -1,4 +1,4 @@
package com.tokilabs.mattermost_push_plugin
package com.tokilabs.nexo.messaging
import android.content.Context
import android.content.Intent

View file

@ -1,4 +1,4 @@
package com.tokilabs.mattermost_push_plugin
package com.tokilabs.nexo.messaging
import android.app.PendingIntent
import android.os.Bundle
@ -7,21 +7,21 @@ import android.os.Looper
import android.util.Log
import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage
import com.tokilabs.mattermost_push_plugin.helpers.CustomPushNotificationHelper
import com.tokilabs.mattermost_push_plugin.helpers.DatabaseHelper
import com.tokilabs.mattermost_push_plugin.helpers.NotificationHelper
import com.tokilabs.mattermost_push_plugin.helpers.PushNotificationDataHelper
import com.tokilabs.nexo.messaging.helpers.CustomPushNotificationHelper
import com.tokilabs.nexo.messaging.helpers.DatabaseHelper
import com.tokilabs.nexo.messaging.helpers.NotificationHelper
import com.tokilabs.nexo.messaging.helpers.PushNotificationDataHelper
import io.flutter.embedding.engine.FlutterEngineCache
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
class MattermostFirebaseMessagingService : FirebaseMessagingService() {
class NexoFirebaseMessagingService : FirebaseMessagingService() {
private val dataHelper by lazy { PushNotificationDataHelper(this) }
companion object {
private const val TAG = "MattermostFCM"
private const val TAG = "NexoFCM"
}
override fun onCreate() {
@ -198,7 +198,7 @@ class MattermostFirebaseMessagingService : FirebaseMessagingService() {
private fun isFlutterEngineRunning(): Boolean {
if (PushNotificationEvents.isFlutterAttached) return true
return FlutterEngineCache.getInstance().contains(MattermostPushPlugin.FLUTTER_ENGINE_ID)
return FlutterEngineCache.getInstance().contains(NexoMessagingPlugin.FLUTTER_ENGINE_ID)
}
private fun isAppInForeground(): Boolean {

View file

@ -1,11 +1,11 @@
package com.tokilabs.mattermost_push_plugin
package com.tokilabs.nexo.messaging
import android.app.Application
import android.content.Context
import android.content.Intent
import com.tokilabs.mattermost_push_plugin.helpers.CustomPushNotificationHelper
import com.tokilabs.mattermost_push_plugin.helpers.DatabaseHelper
import com.tokilabs.mattermost_push_plugin.helpers.Network
import com.tokilabs.nexo.messaging.helpers.CustomPushNotificationHelper
import com.tokilabs.nexo.messaging.helpers.DatabaseHelper
import com.tokilabs.nexo.messaging.helpers.Network
import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.embedding.engine.plugins.activity.ActivityAware
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding
@ -16,17 +16,17 @@ import io.flutter.plugin.common.MethodChannel.MethodCallHandler
import io.flutter.plugin.common.MethodChannel.Result
import io.flutter.plugin.common.PluginRegistry
class MattermostPushPlugin :
class NexoMessagingPlugin :
FlutterPlugin,
ActivityAware,
EventChannel.StreamHandler,
MethodCallHandler {
companion object {
const val CHANNEL_EVENTS = "com.tokilabs.mattermost/notifications"
const val CHANNEL_ACTIONS = "com.tokilabs.mattermost/notification_actions"
const val CHANNEL_EVENTS = "com.tokilabs.nexo.messaging/notifications"
const val CHANNEL_ACTIONS = "com.tokilabs.nexo.messaging/notification_actions"
const val FLUTTER_ENGINE_ID = "main_engine"
const val SIGNING_PREFS = "mattermost_signing"
const val SIGNING_PREFS = "nexo_signing"
}
private var methodChannel: MethodChannel? = null

View file

@ -1,4 +1,4 @@
package com.tokilabs.mattermost_push_plugin
package com.tokilabs.nexo.messaging
import android.os.Handler
import android.os.Looper

View file

@ -1,4 +1,4 @@
package com.tokilabs.mattermost_push_plugin.helpers
package com.tokilabs.nexo.messaging.helpers
import android.graphics.Bitmap
import android.util.LruCache

View file

@ -1,11 +1,11 @@
package com.tokilabs.mattermost_push_plugin.helpers
package com.tokilabs.nexo.messaging.helpers
import android.content.Context
import android.util.Log
import com.tokilabs.mattermost_push_plugin.helpers.db.GlobalDatabase
import com.tokilabs.mattermost_push_plugin.helpers.db.GlobalEntity
import com.tokilabs.mattermost_push_plugin.helpers.db.MattermostDatabase
import com.tokilabs.mattermost_push_plugin.helpers.db.ServerEntity
import com.tokilabs.nexo.messaging.helpers.db.GlobalDatabase
import com.tokilabs.nexo.messaging.helpers.db.GlobalEntity
import com.tokilabs.nexo.messaging.helpers.db.NexoMessageDatabase
import com.tokilabs.nexo.messaging.helpers.db.ServerEntity
class DatabaseHelper private constructor(private val context: Context) {
@ -72,9 +72,9 @@ class DatabaseHelper private constructor(private val context: Context) {
}
}
fun getDatabaseForServer(context: Context, serverUrl: String): MattermostDatabase? {
fun getDatabaseForServer(context: Context, serverUrl: String): NexoMessageDatabase? {
return try {
MattermostDatabase.getInstance(context, serverUrl)
NexoMessageDatabase.getInstance(context, serverUrl)
} catch (e: Exception) {
Log.e(TAG, "getDatabaseForServer error for $serverUrl: ${e.message}")
null

View file

@ -1,4 +1,4 @@
package com.tokilabs.mattermost_push_plugin.helpers
package com.tokilabs.nexo.messaging.helpers
import android.util.Log
import okhttp3.MediaType.Companion.toMediaType

View file

@ -1,4 +1,4 @@
package com.tokilabs.mattermost_push_plugin.helpers
package com.tokilabs.nexo.messaging.helpers
import android.app.NotificationManager
import android.content.Context

View file

@ -1,10 +1,10 @@
package com.tokilabs.mattermost_push_plugin.helpers
package com.tokilabs.nexo.messaging.helpers
import android.content.Context
import android.os.Bundle
import android.util.Log
import com.tokilabs.mattermost_push_plugin.helpers.db.MattermostDatabase
import com.tokilabs.mattermost_push_plugin.helpers.db.SystemEntity
import com.tokilabs.nexo.messaging.helpers.db.NexoMessageDatabase
import com.tokilabs.nexo.messaging.helpers.db.SystemEntity
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
@ -90,7 +90,7 @@ object PushNotificationDataRunnable {
}
}
private fun fetchTeamIfNeeded(db: MattermostDatabase, serverUrl: String, teamId: String): Bundle? {
private fun fetchTeamIfNeeded(db: NexoMessageDatabase, serverUrl: String, teamId: String): Bundle? {
val team = db.teamDao().getTeam(teamId) ?: return null
return Bundle().apply {
putString("id", team.id)
@ -98,7 +98,7 @@ object PushNotificationDataRunnable {
}
}
private fun fetchMyChannel(db: MattermostDatabase, channelId: String): Bundle? {
private fun fetchMyChannel(db: NexoMessageDatabase, channelId: String): Bundle? {
val channel = db.channelDao().getChannel(channelId) ?: return null
return Bundle().apply {
putString("id", channel.id)
@ -109,7 +109,7 @@ object PushNotificationDataRunnable {
}
private fun fetchPosts(
db: MattermostDatabase,
db: NexoMessageDatabase,
serverUrl: String,
channelId: String,
isCRTEnabled: Boolean,
@ -133,7 +133,7 @@ object PushNotificationDataRunnable {
}
}
private fun fetchThread(db: MattermostDatabase, serverUrl: String, rootId: String): Bundle? {
private fun fetchThread(db: NexoMessageDatabase, serverUrl: String, rootId: String): Bundle? {
val posts = db.postDao().getThreadPosts(rootId)
if (posts.isEmpty()) return null
return Bundle().apply {
@ -150,7 +150,7 @@ object PushNotificationDataRunnable {
}
private fun saveToDatabase(
db: MattermostDatabase,
db: NexoMessageDatabase,
data: Bundle,
teamId: String?,
channelId: String?,

View file

@ -1,4 +1,4 @@
package com.tokilabs.mattermost_push_plugin.helpers.db
package com.tokilabs.nexo.messaging.helpers.db
import android.content.Context
import androidx.room.Database
@ -22,7 +22,7 @@ abstract class GlobalDatabase : RoomDatabase() {
instance ?: Room.databaseBuilder(
context.applicationContext,
GlobalDatabase::class.java,
"mattermost_global.db",
"nexo_global.db",
)
.allowMainThreadQueries()
.fallbackToDestructiveMigration()

View file

@ -1,4 +1,4 @@
package com.tokilabs.mattermost_push_plugin.helpers.db
package com.tokilabs.nexo.messaging.helpers.db
import androidx.room.ColumnInfo
import androidx.room.Dao

View file

@ -1,4 +1,4 @@
package com.tokilabs.mattermost_push_plugin.helpers.db
package com.tokilabs.nexo.messaging.helpers.db
import android.content.Context
import androidx.room.Database
@ -13,7 +13,7 @@ import androidx.room.RoomDatabase
version = 2,
exportSchema = false,
)
abstract class MattermostDatabase : RoomDatabase() {
abstract class NexoMessageDatabase : RoomDatabase() {
abstract fun configDao(): ConfigDao
abstract fun userDao(): UserDao
abstract fun systemDao(): SystemDao
@ -31,14 +31,14 @@ abstract class MattermostDatabase : RoomDatabase() {
}
companion object {
@Volatile private var instances = mutableMapOf<String, MattermostDatabase>()
@Volatile private var instances = mutableMapOf<String, NexoMessageDatabase>()
fun getInstance(context: Context, serverUrl: String): MattermostDatabase {
fun getInstance(context: Context, serverUrl: String): NexoMessageDatabase {
return instances.getOrPut(serverUrl) {
val dbName = "mattermost_server_${serverUrl.hashCode()}.db"
val dbName = "nexo_server_${serverUrl.hashCode()}.db"
Room.databaseBuilder(
context.applicationContext,
MattermostDatabase::class.java,
NexoMessageDatabase::class.java,
dbName,
)
.allowMainThreadQueries()

View file

@ -1,4 +1,4 @@
package com.tokilabs.mattermost_push_plugin.helpers.db
package com.tokilabs.nexo.messaging.helpers.db
import androidx.room.ColumnInfo
import androidx.room.Dao

View file

@ -1,4 +1,4 @@
package com.tokilabs.mattermost_push_plugin
package com.tokilabs.nexo.messaging
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
@ -13,10 +13,10 @@ import kotlin.test.Test
* you can run them directly from IDEs that support JUnit such as Android Studio.
*/
internal class MattermostPushPluginTest {
internal class NexoMessagingPluginTest {
@Test
fun onMethodCall_getPlatformVersion_returnsExpectedValue() {
val plugin = MattermostPushPlugin()
val plugin = NexoMessagingPlugin()
val call = MethodCall("getPlatformVersion", null)
val mockResult: MethodChannel.Result = Mockito.mock(MethodChannel.Result::class.java)

View file

@ -99,6 +99,6 @@ cd "$HOME/tmp/nexo-codex-test/apps/client/android"
Android host app.
- `./gradlew testDebugUnitTest` verifies the Android unit-test layer and proves
the Android SDK path is usable.
- Real Firebase FCM delivery, Mattermost ACK delivery, inline reply, and dismiss
- Real Firebase FCM delivery, nexo server ACK delivery, inline reply, and dismiss
behavior remain manual smoke checks because they require external service
configuration.

View file

@ -1,10 +1,10 @@
import Flutter
import UIKit
public class MattermostPushPlugin: NSObject, FlutterPlugin {
public class NexoMessagingPlugin: NSObject, FlutterPlugin {
public static func register(with registrar: FlutterPluginRegistrar) {
let channel = FlutterMethodChannel(name: "mattermost_push_plugin", binaryMessenger: registrar.messenger())
let instance = MattermostPushPlugin()
let channel = FlutterMethodChannel(name: "nexo_messaging", binaryMessenger: registrar.messenger())
let instance = NexoMessagingPlugin()
registrar.addMethodCallDelegate(instance, channel: channel)
}

View file

@ -1,9 +1,9 @@
#
# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html.
# Run `pod lib lint mattermost_push_plugin.podspec` to validate before publishing.
# Run `pod lib lint nexo_messaging.podspec` to validate before publishing.
#
Pod::Spec.new do |s|
s.name = 'mattermost_push_plugin'
s.name = 'nexo_messaging'
s.version = '0.0.1'
s.summary = 'A new Flutter plugin project.'
s.description = <<-DESC
@ -25,5 +25,5 @@ A new Flutter plugin project.
# required reason APIs, update the PrivacyInfo.xcprivacy file to describe your
# plugin's privacy impact, and then uncomment this line. For more information,
# see https://developer.apple.com/documentation/bundleresources/privacy_manifest_files
# s.resource_bundles = {'mattermost_push_plugin_privacy' => ['Resources/PrivacyInfo.xcprivacy']}
# s.resource_bundles = {'nexo_messaging_privacy' => ['Resources/PrivacyInfo.xcprivacy']}
end

View file

@ -1,10 +1,10 @@
import Cocoa
import FlutterMacOS
public class MattermostPushPlugin: NSObject, FlutterPlugin {
public class NexoMessagingPlugin: NSObject, FlutterPlugin {
public static func register(with registrar: FlutterPluginRegistrar) {
let channel = FlutterMethodChannel(name: "mattermost_push_plugin", binaryMessenger: registrar.messenger)
let instance = MattermostPushPlugin()
let channel = FlutterMethodChannel(name: "nexo_messaging", binaryMessenger: registrar.messenger)
let instance = NexoMessagingPlugin()
registrar.addMethodCallDelegate(instance, channel: channel)
}

View file

@ -1,9 +1,9 @@
#
# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html.
# Run `pod lib lint mattermost_push_plugin.podspec` to validate before publishing.
# Run `pod lib lint nexo_messaging.podspec` to validate before publishing.
#
Pod::Spec.new do |s|
s.name = 'mattermost_push_plugin'
s.name = 'nexo_messaging'
s.version = '0.0.1'
s.summary = 'A new Flutter plugin project.'
s.description = <<-DESC
@ -20,7 +20,7 @@ A new Flutter plugin project.
# data, update the PrivacyInfo.xcprivacy file to describe your plugin's
# privacy impact, and then uncomment this line. For more information,
# see https://developer.apple.com/documentation/bundleresources/privacy_manifest_files
# s.resource_bundles = {'mattermost_push_plugin_privacy' => ['Resources/PrivacyInfo.xcprivacy']}
# s.resource_bundles = {'nexo_messaging_privacy' => ['Resources/PrivacyInfo.xcprivacy']}
s.dependency 'FlutterMacOS'

View file

@ -22,9 +22,9 @@ flutter:
plugin:
platforms:
android:
package: com.tokilabs.mattermost_push_plugin
pluginClass: MattermostPushPlugin
package: com.tokilabs.nexo.messaging
pluginClass: NexoMessagingPlugin
ios:
pluginClass: MattermostPushPlugin
pluginClass: NexoMessagingPlugin
macos:
pluginClass: MattermostPushPlugin
pluginClass: NexoMessagingPlugin