47 lines
1.6 KiB
Dart
47 lines
1.6 KiB
Dart
import 'dart:io' show Platform;
|
|
|
|
import 'package:flutter/foundation.dart' show kIsWeb;
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import 'package:just_audio_background/just_audio_background.dart';
|
|
|
|
import 'shell/app_shell.dart';
|
|
import 'theme/accent.dart';
|
|
import 'theme/app_theme.dart';
|
|
|
|
Future<void> main() async {
|
|
WidgetsFlutterBinding.ensureInitialized();
|
|
// Lock-screen / notification transport is only available where audio_service
|
|
// has a backend — Android/iOS. Skipping init elsewhere keeps the Linux dev
|
|
// target (and tests) running.
|
|
if (!kIsWeb && (Platform.isAndroid || Platform.isIOS)) {
|
|
// Never let background-audio setup block the first frame: on failure or
|
|
// hang we still start the app (playback just loses lock-screen controls).
|
|
try {
|
|
await JustAudioBackground.init(
|
|
androidNotificationChannelId: 'com.conversionpath.ratune_mobile.audio',
|
|
androidNotificationChannelName: 'Ratune playback',
|
|
androidNotificationOngoing: true,
|
|
).timeout(const Duration(seconds: 8));
|
|
} catch (e, st) {
|
|
debugPrint('JustAudioBackground.init failed: $e\n$st');
|
|
}
|
|
}
|
|
runApp(const ProviderScope(child: RatuneApp()));
|
|
}
|
|
|
|
class RatuneApp extends ConsumerWidget {
|
|
const RatuneApp({super.key});
|
|
|
|
@override
|
|
Widget build(BuildContext context, WidgetRef ref) {
|
|
// The theme rebuilds whenever the album-art accent changes.
|
|
final accent = ref.watch(accentProvider);
|
|
return MaterialApp(
|
|
title: 'Ratune',
|
|
debugShowCheckedModeBanner: false,
|
|
theme: buildRatuneTheme(accent),
|
|
home: const AppShell(),
|
|
);
|
|
}
|
|
}
|