mirror of
https://github.com/KRTirtho/spotube.git
synced 2025-09-13 16:05:18 +00:00
147 lines
4.9 KiB
Dart
147 lines
4.9 KiB
Dart
import 'dart:async';
|
|
|
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|
import 'package:shadcn_flutter/shadcn_flutter.dart';
|
|
import 'package:spotube/collections/spotube_icons.dart';
|
|
import 'package:spotube/extensions/context.dart';
|
|
import 'package:spotube/modules/metadata_plugins/plugin_update_available_dialog.dart';
|
|
import 'package:spotube/provider/metadata_plugin/metadata_plugin_provider.dart';
|
|
import 'package:spotube/provider/metadata_plugin/updater/update_checker.dart';
|
|
import 'package:spotube/provider/server/routes/connect.dart';
|
|
import 'package:spotube/services/audio_player/audio_player.dart';
|
|
import 'package:spotube/services/connectivity_adapter.dart';
|
|
import 'package:spotube/utils/service_utils.dart';
|
|
|
|
void useGlobalSubscriptions(WidgetRef ref) {
|
|
final context = useContext();
|
|
final theme = Theme.of(context);
|
|
final connectRoutes = ref.watch(serverConnectRoutesProvider);
|
|
|
|
useEffect(() {
|
|
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
|
ServiceUtils.checkForUpdates(context, ref);
|
|
|
|
final pluginUpdate =
|
|
await ref.read(metadataPluginUpdateCheckerProvider.future);
|
|
|
|
if (pluginUpdate != null) {
|
|
final pluginConfig = await ref.read(metadataPluginsProvider.future);
|
|
if (context.mounted) {
|
|
showDialog(
|
|
context: context,
|
|
builder: (context) => MetadataPluginUpdateAvailableDialog(
|
|
plugin: pluginConfig.defaultPluginConfig!,
|
|
update: pluginUpdate,
|
|
),
|
|
);
|
|
}
|
|
}
|
|
});
|
|
|
|
StreamSubscription? audioPlayerSubscription;
|
|
bool pausedByStream = false;
|
|
|
|
final subscriptions = [
|
|
ConnectionCheckerService.instance.onConnectivityChanged
|
|
.listen((connected) async {
|
|
audioPlayerSubscription?.cancel();
|
|
|
|
/// Pausing or resuming based on connectivity to avoid MPV skipping
|
|
/// audio while retrying to connect
|
|
if (audioPlayer.currentIndex >= 0) {
|
|
if (connected && audioPlayer.isPaused && pausedByStream) {
|
|
await audioPlayer.resume();
|
|
pausedByStream = false;
|
|
} else if (!connected && audioPlayer.isPlaying) {
|
|
if ((audioPlayer.bufferedPosition - const Duration(seconds: 1)) <=
|
|
audioPlayer.position) {
|
|
await audioPlayer.pause();
|
|
pausedByStream = true;
|
|
} else {
|
|
audioPlayerSubscription =
|
|
audioPlayer.positionStream.listen((position) async {
|
|
if (ConnectionCheckerService.instance.isConnectedSync) return;
|
|
|
|
final bufferedPosition =
|
|
audioPlayer.bufferedPosition - const Duration(seconds: 1);
|
|
final duration =
|
|
audioPlayer.duration - const Duration(seconds: 1);
|
|
|
|
if (bufferedPosition <= position || position >= duration) {
|
|
audioPlayer.pause();
|
|
pausedByStream = true;
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
// Show notification for connection related issues
|
|
if (!context.mounted) return;
|
|
|
|
showToast(
|
|
context: context,
|
|
location: ToastLocation.bottomCenter,
|
|
builder: (context, overlay) {
|
|
if (connected) {
|
|
return SurfaceCard(
|
|
child: Basic(
|
|
leading: const Icon(SpotubeIcons.wifi),
|
|
title: Text(context.l10n.connection_restored),
|
|
),
|
|
);
|
|
}
|
|
|
|
return SurfaceCard(
|
|
fillColor: theme.colorScheme.destructive,
|
|
filled: true,
|
|
child: Basic(
|
|
leading: Icon(
|
|
SpotubeIcons.noWifi,
|
|
color: theme.colorScheme.destructiveForeground,
|
|
),
|
|
trailing: Text(
|
|
context.l10n.you_are_offline,
|
|
style: TextStyle(
|
|
color: theme.colorScheme.destructiveForeground,
|
|
),
|
|
),
|
|
),
|
|
);
|
|
},
|
|
);
|
|
}),
|
|
connectRoutes.connectClientStream.listen((clientOrigin) {
|
|
if (!context.mounted) return;
|
|
showToast(
|
|
context: context,
|
|
location: ToastLocation.topRight,
|
|
builder: (context, overlay) {
|
|
return SurfaceCard(
|
|
fillColor: Colors.yellow[600],
|
|
filled: true,
|
|
child: Basic(
|
|
leading: const Icon(
|
|
SpotubeIcons.error,
|
|
color: Colors.black,
|
|
),
|
|
title: Text(
|
|
context.l10n.connect_client_alert(clientOrigin),
|
|
style: const TextStyle(color: Colors.black),
|
|
),
|
|
),
|
|
);
|
|
},
|
|
);
|
|
})
|
|
];
|
|
|
|
return () {
|
|
for (final subscription in subscriptions) {
|
|
subscription.cancel();
|
|
}
|
|
};
|
|
}, []);
|
|
}
|