2024-08-17 16:51:47 -04:00
|
|
|
import 'dart:async';
|
2024-08-10 13:27:12 -04:00
|
|
|
import 'package:flutter/material.dart';
|
2024-08-20 09:11:21 -04:00
|
|
|
import 'package:intl/intl.dart';
|
2024-08-17 16:51:47 -04:00
|
|
|
import 'package:provider/provider.dart';
|
|
|
|
import 'package:just_audio/just_audio.dart';
|
2024-10-14 11:42:48 -04:00
|
|
|
import 'package:audio_session/audio_session.dart';
|
2024-08-14 09:30:27 -04:00
|
|
|
import '../../views/lcd.dart';
|
|
|
|
import '../../views/keypad.dart';
|
2024-09-29 15:34:53 -04:00
|
|
|
import '../../views/login.dart';
|
2024-08-17 16:51:47 -04:00
|
|
|
import '../controller/stillbox.dart';
|
|
|
|
import 'play.dart';
|
2024-08-10 13:27:12 -04:00
|
|
|
|
|
|
|
class MainRadio extends StatefulWidget {
|
|
|
|
const MainRadio({super.key, required this.title});
|
|
|
|
|
|
|
|
final String title;
|
|
|
|
|
|
|
|
@override
|
|
|
|
State<MainRadio> createState() => _MainRadioState();
|
|
|
|
}
|
|
|
|
|
|
|
|
class _MainRadioState extends State<MainRadio> {
|
2024-08-18 08:27:03 -04:00
|
|
|
final player = JustAudioDriver();
|
2024-08-17 16:51:47 -04:00
|
|
|
bool lcdState = false;
|
|
|
|
static const _lcdTimeout = 3;
|
|
|
|
static const _lcdOnColor = Colors.amber;
|
|
|
|
static const _lcdOffColor = Color.fromARGB(255, 255, 219, 110);
|
|
|
|
Color _lcdColor = _lcdOffColor;
|
|
|
|
Color _ledColor = Colors.black;
|
|
|
|
Timer? _lcdTimer;
|
|
|
|
SBCall? _call;
|
2024-08-18 08:41:29 -04:00
|
|
|
Completer _completer = Completer();
|
2024-08-18 09:17:10 -04:00
|
|
|
int queueLen = 0;
|
2024-08-20 09:11:21 -04:00
|
|
|
DateFormat timeFormat = DateFormat('HH:mm');
|
2024-08-17 16:51:47 -04:00
|
|
|
|
2024-10-14 11:42:48 -04:00
|
|
|
void _setupAudioSession() async {
|
|
|
|
final session = await AudioSession.instance;
|
|
|
|
await session.configure(AudioSessionConfiguration.music());
|
|
|
|
}
|
|
|
|
|
2024-08-17 16:51:47 -04:00
|
|
|
@override
|
|
|
|
void initState() {
|
|
|
|
super.initState();
|
2024-10-14 11:42:48 -04:00
|
|
|
_setupAudioSession();
|
2024-08-17 16:51:47 -04:00
|
|
|
final sb = Provider.of<Stillbox>(context, listen: false);
|
2024-10-14 11:42:48 -04:00
|
|
|
|
2024-08-18 08:27:03 -04:00
|
|
|
player.player.playerStateStream.listen((event) async {
|
2024-08-18 09:17:10 -04:00
|
|
|
if (event.processingState == ProcessingState.completed &&
|
|
|
|
!_completer.isCompleted) {
|
2024-08-18 08:41:29 -04:00
|
|
|
_completer.complete();
|
2024-08-17 16:51:47 -04:00
|
|
|
setState(() {
|
|
|
|
_ledColor = Colors.black;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
2024-10-24 20:00:19 -04:00
|
|
|
|
2024-08-18 09:17:10 -04:00
|
|
|
sb.callQStream.stream.listen((ctAdd) {
|
|
|
|
setState(() {
|
|
|
|
queueLen += ctAdd;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2024-08-17 21:53:19 -04:00
|
|
|
_callLoop(sb);
|
|
|
|
}
|
|
|
|
|
2024-11-08 15:42:38 -05:00
|
|
|
void _handleSocketError(dynamic error) {
|
2024-09-29 15:34:53 -04:00
|
|
|
Navigator.pushReplacement(
|
|
|
|
context,
|
|
|
|
PageRouteBuilder(
|
|
|
|
pageBuilder: (context, animation, secondaryAnimation) => const Login(),
|
|
|
|
transitionsBuilder: (context, animation, secondaryAnimation, child) {
|
|
|
|
return child;
|
|
|
|
},
|
|
|
|
transitionDuration: const Duration(milliseconds: 0),
|
|
|
|
),
|
|
|
|
);
|
2024-10-24 20:00:19 -04:00
|
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
2024-10-30 11:18:11 -04:00
|
|
|
SnackBar(content: Text(error.toString())),
|
2024-10-24 20:00:19 -04:00
|
|
|
);
|
2024-09-29 15:34:53 -04:00
|
|
|
}
|
|
|
|
|
2024-08-17 21:53:19 -04:00
|
|
|
void _callLoop(Stillbox sb) async {
|
2024-09-29 15:34:53 -04:00
|
|
|
var streamWithoutErrors =
|
|
|
|
sb.callStream.stream.handleError((error) => _handleSocketError(error));
|
|
|
|
await for (final call in streamWithoutErrors) {
|
2024-08-17 16:51:47 -04:00
|
|
|
lcdOn();
|
|
|
|
setState(() {
|
|
|
|
_call = call;
|
2024-08-18 09:17:10 -04:00
|
|
|
queueLen--;
|
2024-08-17 16:51:47 -04:00
|
|
|
});
|
2024-08-18 08:41:29 -04:00
|
|
|
_completer = Completer();
|
2024-08-18 09:17:10 -04:00
|
|
|
player.play(call.call);
|
2024-08-18 08:41:29 -04:00
|
|
|
await _completer.future;
|
2024-08-17 16:51:47 -04:00
|
|
|
lcdOff();
|
2024-08-17 21:53:19 -04:00
|
|
|
} //);
|
2024-08-17 16:51:47 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void lcdOn() {
|
|
|
|
if (_lcdTimer != null) {
|
|
|
|
_lcdTimer!.cancel();
|
|
|
|
_lcdTimer = null;
|
|
|
|
}
|
|
|
|
setState(() {
|
2024-08-21 09:11:27 -04:00
|
|
|
_ledColor = const Color.fromARGB(255, 226, 62, 255);
|
2024-08-17 16:51:47 -04:00
|
|
|
_lcdColor = _lcdOnColor;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
void lcdOff() {
|
|
|
|
if (_lcdTimer != null) {
|
|
|
|
_lcdTimer!.cancel();
|
|
|
|
}
|
|
|
|
_lcdTimer = Timer(const Duration(seconds: _lcdTimeout), () {
|
|
|
|
setState(() {
|
|
|
|
_lcdColor = _lcdOffColor;
|
|
|
|
});
|
|
|
|
_lcdTimer = null;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2024-08-10 13:27:12 -04:00
|
|
|
@override
|
|
|
|
Widget build(BuildContext context) {
|
2024-08-17 16:51:47 -04:00
|
|
|
return SafeArea(
|
2024-08-14 09:30:27 -04:00
|
|
|
child: Scaffold(
|
|
|
|
body: Center(
|
2024-08-10 13:27:12 -04:00
|
|
|
child: SizedBox(
|
|
|
|
width: 500.0,
|
|
|
|
child: Column(
|
|
|
|
mainAxisAlignment: MainAxisAlignment.start,
|
|
|
|
children: <Widget>[
|
2024-08-17 16:51:47 -04:00
|
|
|
Row(
|
|
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
|
|
children: <Widget>[
|
|
|
|
const ScannerLabel('Stillbox'),
|
|
|
|
LED(_ledColor),
|
|
|
|
]),
|
2024-08-20 09:11:21 -04:00
|
|
|
LCD(_call, _lcdColor, queueLen, timeFormat),
|
2024-08-17 16:51:47 -04:00
|
|
|
const Keypad(),
|
2024-08-10 13:27:12 -04:00
|
|
|
],
|
|
|
|
)),
|
|
|
|
),
|
2024-08-14 09:30:27 -04:00
|
|
|
));
|
2024-08-10 13:27:12 -04:00
|
|
|
}
|
2024-08-17 16:51:47 -04:00
|
|
|
|
|
|
|
Widget lcdContents() {
|
|
|
|
return Consumer<Stillbox>(builder: (context, sb, child) {
|
|
|
|
return Container();
|
|
|
|
});
|
|
|
|
}
|
2024-08-10 13:27:12 -04:00
|
|
|
}
|