Chat notifications (production-ready) - ChatDeeplinkService: resolves client chat ID from incoming push/WS payloads using the (senderId, chatId) matrix and switches selectedDeviceProvider when the payload references a different watch (multi-device deeplink) - IncomingChatResolver in domain layer with full unit coverage of the 4-case matrix - ChatContext provider (sealed: outsideChat / list / conversation) wired into ChatListScreen and ChatConversationScreen via initState/dispose to enable WhatsApp-style suppression - notifications_init refactor: foreground CHAT_MESSAGE notifications are suppressed on chat list and matching conversation; tap navigation goes through ChatDeeplinkService - ChatSyncService.subscribeToReconnect: reconciles from REST when the WebSocket comes back from a disconnect (recovers messages missed in background) - 5s message-id dedup window in the WS listener (mitigates server-side duplicate chat-message-received events) - Reconcile from remote on conversation mount (covers cached controller from background) - AppBar refresh button + inverted pull-to-refresh in the conversation (overscroll either edge of the reverse list) WS event parser fix - chat-message-received normalises to chat_message_received; parser now accepts both that and chat_message so the conversation reactively refreshes when a watch sends a message Chat application layer - Split the conversation controller into services: chat_send_service, chat_sync_service, chat_participants_service, chat_permission_flow_service, chat_media_cleanup_service - chat_conversation_config centralises page size, polling interval, dedup window - chat_bubble_shell extracted; input bar split into smaller widgets - emoji picker sheet + emoji blocking input formatter + watch_emoji_catalog - Multipart upload header race fixed via synchronized.Lock around the shared Dio instance Videocall (carryover from earlier work in this branch) - Application services: incoming, outgoing, session - Domain entities: VideocallIncomingArgs, VideocallRoom, VideocallUserId, parseDeviceIdFromRoom helper - Views split: idle, incoming, active call, group call - Widgets: picture_in_picture_video, remote_or_fallback_video, video_call_header - videocall_config centralises timeouts, ringing duration, battery threshold - Incoming via push (channel mode) with full-screen notification + ringtone - Hangup-on-remote-left moved to controller; redirect on participant update documented - treezor_token_interceptor: distinguish session expiry from operation-denied 401s Localization & misc - New keys for chat conversation, refresh, errors across en/es/de/fr/it/pt - Location map: dispose ref-after-unmount fix; route history layer cleanup - Legacy device view model: position update event handling - AndroidManifest: notification channel + permissions for incoming-call full-screen intent
90 lines
4.1 KiB
XML
90 lines
4.1 KiB
XML
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
|
xmlns:tools="http://schemas.android.com/tools">
|
|
<uses-permission android:name="android.permission.INTERNET" />
|
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
|
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
|
<uses-permission android:name="android.permission.CAMERA" />
|
|
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
|
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
|
|
<uses-permission android:name="android.permission.BLUETOOTH" />
|
|
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
|
<uses-permission android:name="android.permission.USE_BIOMETRIC" />
|
|
<uses-permission android:name="android.permission.READ_CONTACTS" />
|
|
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
|
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
|
|
<uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" />
|
|
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
|
<uses-permission android:name="android.permission.VIBRATE" />
|
|
|
|
<uses-feature android:name="android.hardware.camera" />
|
|
<uses-feature android:name="android.hardware.camera.autofocus" />
|
|
<uses-feature
|
|
android:name="android.hardware.bluetooth"
|
|
android:required="false" />
|
|
|
|
<application
|
|
android:label="@string/app_name"
|
|
android:name="${applicationName}"
|
|
android:icon="@mipmap/ic_launcher">
|
|
|
|
<activity
|
|
android:name=".MainActivity"
|
|
android:exported="true"
|
|
android:launchMode="singleTop"
|
|
android:taskAffinity=""
|
|
android:theme="@style/LaunchTheme"
|
|
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
|
|
android:hardwareAccelerated="true"
|
|
android:windowSoftInputMode="adjustResize">
|
|
|
|
<meta-data
|
|
android:name="io.flutter.embedding.android.NormalTheme"
|
|
android:resource="@style/NormalTheme" />
|
|
|
|
<intent-filter>
|
|
<action android:name="android.intent.action.MAIN"/>
|
|
<category android:name="android.intent.category.LAUNCHER"/>
|
|
</intent-filter>
|
|
</activity>
|
|
|
|
<meta-data
|
|
android:name="flutterEmbedding"
|
|
android:value="2" />
|
|
|
|
<meta-data
|
|
android:name="com.google.firebase.messaging.default_notification_channel_id"
|
|
android:value="sf_default_channel" />
|
|
|
|
<!-- Wrap FCM with Antelop SDK forwarding (see AntelopAwareMessagingService). -->
|
|
<service
|
|
android:name=".AntelopAwareMessagingService"
|
|
android:exported="false">
|
|
<intent-filter>
|
|
<action android:name="com.google.firebase.MESSAGING_EVENT" />
|
|
</intent-filter>
|
|
</service>
|
|
|
|
<!-- Disable Antelop's stock FCM service so AntelopAwareMessagingService is the only handler. -->
|
|
<service
|
|
android:name="fr.antelop.exposed.DefaultAntelopFirebaseMessagingService"
|
|
tools:node="remove" />
|
|
|
|
<!-- Disable the firebase_messaging plugin's FCM service so AntelopAwareMessagingService is the only handler. -->
|
|
<service
|
|
android:name="io.flutter.plugins.firebase.messaging.FlutterFirebaseMessagingService"
|
|
tools:node="remove" />
|
|
</application>
|
|
|
|
<!-- Required to query activities that can process text, see:
|
|
https://developer.android.com/training/package-visibility and
|
|
https://developer.android.com/reference/android/content/Intent#ACTION_PROCESS_TEXT.
|
|
|
|
In particular, this is used by the Flutter engine in io.flutter.plugin.text.ProcessTextPlugin. -->
|
|
<queries>
|
|
<intent>
|
|
<action android:name="android.intent.action.PROCESS_TEXT"/>
|
|
<data android:mimeType="text/plain"/>
|
|
</intent>
|
|
</queries>
|
|
</manifest>
|