✨ Sound effects on notifications
This commit is contained in:
BIN
assets/audio/messages.mp3
Normal file
BIN
assets/audio/messages.mp3
Normal file
Binary file not shown.
@@ -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
|
||||
|
||||
@@ -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<void> 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;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -107,13 +107,10 @@ StreamSubscription<WebSocketPacket> 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<void> _putTokenToRemote(
|
||||
"/ring/notifications/subscription",
|
||||
data: {"provider": provider, "device_token": token},
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -70,13 +70,10 @@ StreamSubscription<WebSocketPacket> 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<void> _putTokenToRemote(
|
||||
"/ring/notifications/subscription",
|
||||
data: {"provider": provider, "device_token": token},
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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<UploadTaskTile> 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<UploadTaskTile>
|
||||
return '${duration.inSeconds}s';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user