From 63a55658ab2daae562c2e40455cdaad514013072 Mon Sep 17 00:00:00 2001 From: LittleSheep Date: Sun, 11 Jan 2026 23:32:00 +0800 Subject: [PATCH] :sparkles: Sound effects on notifications --- assets/audio/messages.mp3 | Bin 0 -> 21481 bytes ios/Podfile.lock | 13 +++++++++++++ lib/pods/chat/chat_subscribe.dart | 17 +++++++++++++++-- lib/services/notify.universal.dart | 13 +++++-------- lib/services/notify.windows.dart | 13 +++++-------- lib/widgets/task_overlay.dart | 22 +++++++--------------- 6 files changed, 45 insertions(+), 33 deletions(-) create mode 100644 assets/audio/messages.mp3 diff --git a/assets/audio/messages.mp3 b/assets/audio/messages.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..7f37570289cd64b41554c4a38a1d2da5bd245dba GIT binary patch literal 21481 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 QQObW4e*MGF|J?Wg1Eyv{a{vGU literal 0 HcmV?d00001 diff --git a/ios/Podfile.lock b/ios/Podfile.lock index d8e72f8b..cde3d9ba 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -1,5 +1,7 @@ PODS: - Alamofire (5.11.0) + - audio_session (0.0.1): + - Flutter - connectivity_plus (0.0.1): - Flutter - croppy (0.0.1): @@ -219,6 +221,9 @@ PODS: - Flutter - irondash_engine_context (0.0.1): - Flutter + - just_audio (0.0.1): + - Flutter + - FlutterMacOS - KeychainAccess (4.2.2) - Kingfisher (8.6.2) - KingfisherWebP (1.7.2): @@ -333,6 +338,7 @@ PODS: DEPENDENCIES: - Alamofire + - audio_session (from `.symlinks/plugins/audio_session/ios`) - connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`) - croppy (from `.symlinks/plugins/croppy/ios`) - device_info_plus (from `.symlinks/plugins/device_info_plus/ios`) @@ -357,6 +363,7 @@ DEPENDENCIES: - image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`) - in_app_review (from `.symlinks/plugins/in_app_review/ios`) - irondash_engine_context (from `.symlinks/plugins/irondash_engine_context/ios`) + - just_audio (from `.symlinks/plugins/just_audio/darwin`) - Kingfisher (~> 8.0) - KingfisherWebP - livekit_client (from `.symlinks/plugins/livekit_client/ios`) @@ -418,6 +425,8 @@ SPEC REPOS: - WebRTC-SDK EXTERNAL SOURCES: + audio_session: + :path: ".symlinks/plugins/audio_session/ios" connectivity_plus: :path: ".symlinks/plugins/connectivity_plus/ios" croppy: @@ -466,6 +475,8 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/in_app_review/ios" irondash_engine_context: :path: ".symlinks/plugins/irondash_engine_context/ios" + just_audio: + :path: ".symlinks/plugins/just_audio/darwin" livekit_client: :path: ".symlinks/plugins/livekit_client/ios" local_auth_darwin: @@ -519,6 +530,7 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: Alamofire: bd5e7b23a1a750975288482c1831d71e74415f86 + audio_session: 9bb7f6c970f21241b19f5a3658097ae459681ba0 connectivity_plus: cb623214f4e1f6ef8fe7403d580fdad517d2f7dd croppy: 979e8ddc254f4642bffe7d52dc7193354b27ba30 device_info_plus: 21fcca2080fbcd348be798aa36c3e5ed849eefbe @@ -559,6 +571,7 @@ SPEC CHECKSUMS: image_picker_ios: e0ece4aa2a75771a7de3fa735d26d90817041326 in_app_review: 7dd1ea365263f834b8464673f9df72c80c17c937 irondash_engine_context: 8e58ca8e0212ee9d1c7dc6a42121849986c88486 + just_audio: 4e391f57b79cad2b0674030a00453ca5ce817eed KeychainAccess: c0c4f7f38f6fc7bbe58f5702e25f7bd2f65abf51 Kingfisher: 23d18f54677d973b713e54ce6a8f5eef6e7056ba KingfisherWebP: 38b9721821947f547afb78f933f75f4f9e0ae402 diff --git a/lib/pods/chat/chat_subscribe.dart b/lib/pods/chat/chat_subscribe.dart index 9c2879fc..2f7d4bb7 100644 --- a/lib/pods/chat/chat_subscribe.dart +++ b/lib/pods/chat/chat_subscribe.dart @@ -2,6 +2,8 @@ import "dart:async"; import "dart:convert"; import "package:flutter/material.dart"; import "package:flutter_riverpod/flutter_riverpod.dart"; +import "package:just_audio/just_audio.dart"; +import "package:island/pods/config.dart"; import "package:island/models/chat.dart"; import "package:island/pods/chat/chat_room.dart"; import "package:island/pods/lifecycle.dart"; @@ -198,7 +200,7 @@ class ChatSubscribeNotifier extends _$ChatSubscribeNotifier { return _typingStatuses; } - void onMessage(WebSocketPacket pkt) { + Future onMessage(WebSocketPacket pkt) async { if (!pkt.type.startsWith('messages')) return; if (['messages.read'].contains(pkt.type)) return; @@ -238,6 +240,17 @@ class ChatSubscribeNotifier extends _$ChatSubscribeNotifier { _messagesNotifier.receiveMessage(message); // Send read receipt for new message sendReadReceipt(); + // Play sound for new messages when app is unfocused + if (pkt.type == 'messages.new' && + message.senderId != _chatIdentity.id && + ref.read(appLifecycleStateProvider).value != AppLifecycleState.resumed && + ref.read(appSettingsProvider).soundEffects) { + final player = AudioPlayer(); + await player.setVolume(0.75); + await player.setAudioSource(AudioSource.asset('assets/audio/messages.mp3')); + await player.play(); + player.dispose(); + } } } @@ -275,4 +288,4 @@ class ChatSubscribeNotifier extends _$ChatSubscribeNotifier { _typingCooldownTimer = null; }); } -} +} \ No newline at end of file diff --git a/lib/services/notify.universal.dart b/lib/services/notify.universal.dart index a1abd3a9..f51c273a 100644 --- a/lib/services/notify.universal.dart +++ b/lib/services/notify.universal.dart @@ -107,13 +107,10 @@ StreamSubscription setupNotificationListener( } if (settings.soundEffects) { final player = AudioPlayer(); - player - .setAudioSource( - AudioSource.asset('assets/audio/notification.mp3'), - ) - .then((_) { - player.play().then((_) => player.dispose()); - }); + await player.setVolume(0.75); + await player.setAudioSource(AudioSource.asset('assets/audio/notification.mp3')); + await player.play(); + player.dispose(); } showTopSnackBar( globalOverlay.currentState!, @@ -231,4 +228,4 @@ Future _putTokenToRemote( "/ring/notifications/subscription", data: {"provider": provider, "device_token": token}, ); -} +} \ No newline at end of file diff --git a/lib/services/notify.windows.dart b/lib/services/notify.windows.dart index 17dc2073..373c3ef9 100644 --- a/lib/services/notify.windows.dart +++ b/lib/services/notify.windows.dart @@ -70,13 +70,10 @@ StreamSubscription setupNotificationListener( } if (settings.soundEffects) { final player = AudioPlayer(); - player - .setAudioSource( - AudioSource.asset('assets/audio/notification.mp3'), - ) - .then((_) { - player.play().then((_) => player.dispose()); - }); + await player.setVolume(0.75); + await player.setAudioSource(AudioSource.asset('assets/audio/notification.mp3')); + await player.play(); + player.dispose(); } showTopSnackBar( globalOverlay.currentState!, @@ -224,4 +221,4 @@ Future _putTokenToRemote( "/ring/notifications/subscription", data: {"provider": provider, "device_token": token}, ); -} +} \ No newline at end of file diff --git a/lib/widgets/task_overlay.dart b/lib/widgets/task_overlay.dart index d5dbffe9..5a030571 100644 --- a/lib/widgets/task_overlay.dart +++ b/lib/widgets/task_overlay.dart @@ -275,7 +275,8 @@ class _TaskOverlayContent extends HookConsumerWidget { ), if (activeTasks.any( (task) => - task.status == DriveTaskStatus.inProgress, + task.status == DriveTaskStatus.inProgress && + task.uploadedBytes < task.fileSize, )) CircularProgressIndicator( value: null, // Indeterminate @@ -378,7 +379,8 @@ class _TaskOverlayContent extends HookConsumerWidget { if (activeTasks.any( (task) => task.status == - DriveTaskStatus.inProgress, + DriveTaskStatus.inProgress && + task.uploadedBytes < task.fileSize, )) CircularProgressIndicator( value: null, // Indeterminate @@ -533,14 +535,9 @@ class _TaskOverlayContent extends HookConsumerWidget { } double? _getTaskProgress(DriveTask task) { - if (task.status == DriveTaskStatus.completed) return 1.0; + if (task.status == DriveTaskStatus.completed || (task.uploadedBytes >= task.fileSize && task.fileSize > 0)) return 1.0; if (task.status != DriveTaskStatus.inProgress) return 0.0; - // If all bytes are uploaded but still in progress, show indeterminate - if (task.uploadedBytes >= task.fileSize && task.fileSize > 0) { - return null; // Indeterminate progress - } - return task.fileSize > 0 ? task.uploadedBytes / task.fileSize : 0.0; } @@ -672,14 +669,9 @@ class UploadTaskTile extends StatefulWidget { State createState() => _UploadTaskTileState(); static double? _getTaskProgress(DriveTask task) { - if (task.status == DriveTaskStatus.completed) return 1.0; + if (task.status == DriveTaskStatus.completed || (task.uploadedBytes >= task.fileSize && task.fileSize > 0)) return 1.0; if (task.status == DriveTaskStatus.inProgress) return null; - // If all bytes are uploaded but still in progress, show indeterminate - if (task.uploadedBytes >= task.fileSize && task.fileSize > 0) { - return null; // Indeterminate progress - } - return task.fileSize > 0 ? task.uploadedBytes / task.fileSize : 0.0; } } @@ -1029,4 +1021,4 @@ class _UploadTaskTileState extends State return '${duration.inSeconds}s'; } } -} +} \ No newline at end of file