113 lines
3.6 KiB
Dart
113 lines
3.6 KiB
Dart
import 'package:flutter/material.dart';
|
||
import 'package:flutter/scheduler.dart';
|
||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||
import 'package:flutter/services.dart';
|
||
import '../provider/timer_provider.dart';
|
||
|
||
class TimerRunningScreen extends ConsumerStatefulWidget {
|
||
const TimerRunningScreen({super.key});
|
||
|
||
@override
|
||
ConsumerState<TimerRunningScreen> createState() => _TimerRunningScreenState();
|
||
}
|
||
|
||
class _TimerRunningScreenState extends ConsumerState<TimerRunningScreen> with TickerProviderStateMixin {
|
||
late Ticker _ticker;
|
||
|
||
@override
|
||
void initState() {
|
||
super.initState();
|
||
SystemChrome.setPreferredOrientations([
|
||
DeviceOrientation.landscapeLeft,
|
||
DeviceOrientation.landscapeRight,
|
||
]);
|
||
|
||
_ticker = createTicker((_) {
|
||
ref.read(timerProvider.notifier).tick();
|
||
});
|
||
_ticker.start();
|
||
}
|
||
|
||
@override
|
||
void dispose() {
|
||
_ticker.dispose();
|
||
SystemChrome.setPreferredOrientations([
|
||
DeviceOrientation.portraitUp,
|
||
DeviceOrientation.portraitDown,
|
||
DeviceOrientation.landscapeLeft,
|
||
DeviceOrientation.landscapeRight,
|
||
]);
|
||
ref.read(timerProvider.notifier).stop(); // Wakelock aus
|
||
super.dispose();
|
||
}
|
||
|
||
@override
|
||
Widget build(BuildContext context) {
|
||
final timerState = ref.watch(timerProvider);
|
||
final remaining = timerState.remaining;
|
||
final minutes = remaining.inMinutes.toString().padLeft(2, '0');
|
||
final seconds = (remaining.inSeconds % 60).toString().padLeft(2, '0');
|
||
|
||
final isLast30 = remaining.inSeconds <= 30 && remaining.inSeconds > 0;
|
||
final isFinished = remaining == Duration.zero;
|
||
|
||
return Scaffold(
|
||
backgroundColor: Colors.black,
|
||
body: Stack(
|
||
children: [
|
||
// Dunkler Overlay – wird transparent in letzten 30s
|
||
AnimatedContainer(
|
||
duration: const Duration(milliseconds: 800),
|
||
color: isLast30 || isFinished ? Colors.transparent : Colors.black.withOpacity(0.75),
|
||
),
|
||
|
||
Center(
|
||
child: Column(
|
||
mainAxisAlignment: MainAxisAlignment.center,
|
||
children: [
|
||
AnimatedDefaultTextStyle(
|
||
duration: const Duration(milliseconds: 400),
|
||
style: TextStyle(
|
||
fontSize: isLast30 ? 180 : 140,
|
||
fontWeight: FontWeight.bold,
|
||
color: isFinished ? Colors.green : (isLast30 ? Colors.red : Colors.white),
|
||
shadows: isLast30
|
||
? [const Shadow(blurRadius: 30, color: Colors.red)]
|
||
: null,
|
||
),
|
||
child: Text('$minutes:$seconds'),
|
||
),
|
||
const SizedBox(height: 60),
|
||
if (isFinished)
|
||
const Text(
|
||
'Runde vorbei!',
|
||
style: TextStyle(fontSize: 48, color: Colors.green),
|
||
)
|
||
else if (timerState.isRunning)
|
||
ElevatedButton(
|
||
onPressed: () {
|
||
ref.read(timerProvider.notifier).pause();
|
||
},
|
||
child: const Text('Pause', style: TextStyle(fontSize: 32)),
|
||
),
|
||
],
|
||
),
|
||
),
|
||
|
||
// Zurück-Button oben links
|
||
Positioned(
|
||
top: 40,
|
||
left: 20,
|
||
child: IconButton(
|
||
icon: const Icon(Icons.close, color: Colors.white, size: 40),
|
||
onPressed: () {
|
||
ref.read(timerProvider.notifier).stop();
|
||
Navigator.of(context).pop();
|
||
},
|
||
),
|
||
),
|
||
],
|
||
),
|
||
);
|
||
}
|
||
} |