Sound effects on notifications

This commit is contained in:
2026-01-11 23:32:00 +08:00
parent 00e063e99f
commit 63a55658ab
6 changed files with 45 additions and 33 deletions

View File

@@ -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;
});
}
}
}

View File

@@ -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},
);
}
}

View File

@@ -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},
);
}
}

View File

@@ -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';
}
}
}
}