Skip to content

Instantly share code, notes, and snippets.

@KingsleyUsoroeno
Created February 10, 2026 15:07
Show Gist options
  • Select an option

  • Save KingsleyUsoroeno/0de994dcdf09976f367aa4fe6d7d4501 to your computer and use it in GitHub Desktop.

Select an option

Save KingsleyUsoroeno/0de994dcdf09976f367aa4fe6d7d4501 to your computer and use it in GitHub Desktop.
A gist for a session timer
// Overview Screen
// [Upcoming, In-Progress, Completed]
// When completed -> show a count down timer
// Trigger
import 'dart:async';
import 'dart:math';
import 'package:bloc/bloc.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
final class _SessionMonitorState {
const _SessionMonitorState({this.status = SessionStatus.unknown, this.severity = const [], this.message});
final SessionStatus status;
final String? message;
final List<(String, int)> severity;
_SessionMonitorState copyWith({SessionStatus? status, String? message, List<(String, int)>? severity}) =>
_SessionMonitorState(
status: status ?? this.status,
message: message ?? this.message,
severity: severity ?? this.severity,
);
}
enum SessionStatus { live, upcoming, completed, unknown }
final class _SessionMonitorCubit extends Cubit<_SessionMonitorState> {
_SessionMonitorCubit() : super(const _SessionMonitorState());
final StreamController<String?> _messages = StreamController();
StreamSubscription<void>? _subscription;
Timer? _timer;
void initialize() async {
await _subscription?.cancel();
_timer?.cancel();
_subscription = _messages.stream.listen((data) {
emit(state.copyWith(message: data));
});
_timer = Timer.periodic(const Duration(seconds: 20), (_) async {
_messages.add('Remember to drink water');
await Future.delayed(const Duration(milliseconds: 500));
_messages.add(null);
});
// have this randomised
final nextBool = Random().nextBool();
final status = nextBool ? SessionStatus.live : SessionStatus.upcoming;
emit(state.copyWith(status: status));
}
void collectData(int value, String text) {
final severity = List<(String, int)>.from(state.severity)..add((text, value));
emit(state.copyWith(severity: severity));
}
@override
Future<void> close() async {
_timer?.cancel();
await _subscription?.cancel();
await _messages.close();
return super.close();
}
}
class SessionMonitorWidget extends StatefulWidget {
const SessionMonitorWidget({super.key});
@override
State<SessionMonitorWidget> createState() => _SessionMonitorWidgetState();
}
class _SessionMonitorWidgetState extends State<SessionMonitorWidget> {
final _controller = TextEditingController();
final _severities = List.generate(10, (index) => index);
int? _initialValue;
void _handleCollectData(BuildContext context) {
if (_initialValue case final value?) {
final input = _controller.text.trim();
context.read<_SessionMonitorCubit>().collectData(value, input);
}
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return BlocProvider<_SessionMonitorCubit>(
create: (_) => _SessionMonitorCubit()..initialize(),
child: Scaffold(
body: SafeArea(
child: Column(
children: [
Expanded(child: BlocBuilder<_SessionMonitorCubit, _SessionMonitorState>(
builder: (context, state) {
if (state.message == null) return const SizedBox.shrink();
return Text('${state.message}');
},
)),
Expanded(child: BlocBuilder<_SessionMonitorCubit, _SessionMonitorState>(
builder: (context, state) {
if (state.severity.isEmpty) return const SizedBox.shrink();
return ListView.builder(
itemBuilder: (_, index) {
final result = state.severity[index];
return Column(
children: [Text('${result.$1} --- ${result.$2}')],
);
},
);
},
)),
Expanded(
child: Column(
children: [
TextFormField(
decoration: InputDecoration(hintText: 'Description'),
),
DropdownButtonFormField<int?>(
initialValue: _initialValue,
items: [
..._severities.map((value) => DropdownMenuItem<int>(
child: Text('$value'),
value: value,
))
],
onChanged: (int? value) {},
),
const SizedBox(height: 10),
Builder(
builder: (context) {
return TextButton(
onPressed: () => _handleCollectData(context),
child: Text('Collect Data'),
);
}
)
],
),
)
],
),
),
),
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment