✨ Sound effects on notifications
This commit is contained in:
@@ -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