corrected icon text. created info panel to replace web view with station stream info from airtime

This commit is contained in:
2026-04-30 07:42:46 +00:00
parent dd429a9687
commit af7eb3b7f8
45 changed files with 751 additions and 74 deletions
+22 -63
View File
@@ -1,8 +1,9 @@
import 'package:flutter/material.dart';
import 'package:just_audio_background/just_audio_background.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'app_theme_business_object.dart';
import 'live_info_business_object.dart';
import 'live_info_panel.dart';
import 'streaming_audio_business_object.dart';
Future<void> main() async {
@@ -56,7 +57,8 @@ class MainPage extends StatefulWidget {
class _MainPageState extends State<MainPage> {
StreamingAudioBusinessObject get _audio => widget.audio;
late final WebViewController _webViewController;
final LiveInfoBusinessObject _liveInfo = LiveInfoBusinessObject();
static const List<int> _intervalOptions = <int>[5, 10, 15, 30, 60];
String _playbackStatusLabel() {
switch (_audio.playbackStatus) {
@@ -72,10 +74,9 @@ class _MainPageState extends State<MainPage> {
@override
void initState() {
super.initState();
_webViewController = WebViewController()
..setJavaScriptMode(JavaScriptMode.unrestricted)
..loadRequest(Uri.parse('https://kryzradio.org'));
_audio.addListener(_handleAudioStateChanged);
_liveInfo.addListener(_handleLiveInfoChanged);
_liveInfo.start();
}
void _handleAudioStateChanged() {
@@ -88,6 +89,16 @@ class _MainPageState extends State<MainPage> {
});
}
void _handleLiveInfoChanged() {
if (!mounted) {
return;
}
setState(() {
// Rebuild when live metadata updates from the polling API.
});
}
Future<void> _play() async {
await _audio.play();
}
@@ -99,6 +110,8 @@ class _MainPageState extends State<MainPage> {
@override
void dispose() {
_audio.removeListener(_handleAudioStateChanged);
_liveInfo.removeListener(_handleLiveInfoChanged);
_liveInfo.dispose();
super.dispose();
}
@@ -114,64 +127,10 @@ class _MainPageState extends State<MainPage> {
flex: 9,
child: Padding(
padding: const EdgeInsets.all(12),
child: Container(
width: double.infinity,
decoration: BoxDecoration(
border: Border.all(
color: themeColors.webViewBorder,
width: 2,
),
borderRadius: BorderRadius.circular(8),
color: themeColors.webViewBackground,
),
child: ClipRRect(
borderRadius: BorderRadius.circular(6),
child: Column(
children: [
Container(
width: double.infinity,
padding: const EdgeInsets.symmetric(
horizontal: 12,
vertical: 8,
),
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
color: themeColors.webViewBorder,
),
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Text(
'Station Information',
style: Theme.of(context).textTheme.labelMedium
?.copyWith(
color: themeColors.statusText,
fontWeight: FontWeight.w700,
),
),
const SizedBox(height: 2),
Text(
'https://kryzradio.org',
style: Theme.of(context).textTheme.labelMedium
?.copyWith(
color: Colors.blue,
decoration: TextDecoration.underline,
decorationColor: Colors.blue,
),
),
],
),
),
Expanded(
child: WebViewWidget(controller: _webViewController),
),
],
),
),
child: LiveInfoPanel(
liveInfo: _liveInfo,
themeColors: themeColors,
intervalOptions: _intervalOptions,
),
),
),