Initial (redacted) commit.
This commit is contained in:
commit
655f8a036a
368 changed files with 20949 additions and 0 deletions
|
@ -0,0 +1,465 @@
|
|||
//import 'dart:ffi';
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:habitrack_app/function_widgets/widget_settings_menu/setting_entry.dart';
|
||||
import 'package:habitrack_app/function_widgets/widget_settings_menu/widget_settings.dart';
|
||||
import 'package:habitrack_app/infrastructure/widget_wall/items_controller.dart';
|
||||
import 'package:habitrack_app/infrastructure/widget_wall/items_state.dart';
|
||||
import 'package:habitrack_app/main.dart';
|
||||
import 'package:habitrack_app/sembast/timer.dart';
|
||||
import 'package:logger/logger.dart';
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class CompoundWidgetTimer extends ConsumerStatefulWidget {
|
||||
CompoundWidgetTimer({required this.item, super.key});
|
||||
|
||||
TimerItem item;
|
||||
|
||||
double getProgress() {
|
||||
return (item.current / item.goal) / 60;
|
||||
}
|
||||
|
||||
@override
|
||||
ConsumerState<CompoundWidgetTimer> createState() =>
|
||||
_CompoundWidgetTimerState();
|
||||
}
|
||||
|
||||
class _CompoundWidgetTimerState extends ConsumerState<CompoundWidgetTimer>
|
||||
with WidgetsBindingObserver {
|
||||
_CompoundWidgetTimerState();
|
||||
|
||||
String button1text = '';
|
||||
Timer _timer = Timer(Duration.zero, () => ());
|
||||
|
||||
DateTime calcDue() {
|
||||
final now = DateTime.now();
|
||||
const secondsToAdd = 10;
|
||||
const duration = Duration(seconds: secondsToAdd);
|
||||
final futureTime = now.add(duration);
|
||||
|
||||
Logger().i(futureTime);
|
||||
|
||||
return DateTime.now();
|
||||
}
|
||||
|
||||
void handleButton1() {
|
||||
//start timer from 0
|
||||
const oneSec = Duration(seconds: 1);
|
||||
|
||||
if (widget.item.state == 'initial') {
|
||||
widget.item = widget.item.copyWith(state: 'running');
|
||||
ref.watch(homeControllerProvider).edit(widget.item);
|
||||
_timer = Timer.periodic(
|
||||
oneSec,
|
||||
(Timer funcTimer) {
|
||||
if (widget.item.current == (widget.item.goal * 60)) {
|
||||
setState(() {
|
||||
final now = DateTime.now();
|
||||
widget.item = widget.item.copyWith(
|
||||
state: 'completed',
|
||||
completedOn: now.toString(),
|
||||
);
|
||||
ref.watch(homeControllerProvider).edit(widget.item);
|
||||
|
||||
funcTimer.cancel();
|
||||
});
|
||||
} else {
|
||||
setState(() {
|
||||
widget.item =
|
||||
widget.item.copyWith(current: widget.item.current + 1);
|
||||
ref.watch(homeControllerProvider).edit(widget.item);
|
||||
});
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
// continue timer
|
||||
else if (widget.item.state == 'paused') {
|
||||
widget.item = widget.item.copyWith(state: 'running');
|
||||
ref.watch(homeControllerProvider).edit(widget.item);
|
||||
_timer = Timer.periodic(
|
||||
const Duration(seconds: 1),
|
||||
(Timer funcTimer) {
|
||||
if (widget.item.current == (widget.item.goal * 60)) {
|
||||
setState(() {
|
||||
final now = DateTime.now();
|
||||
widget.item = widget.item.copyWith(
|
||||
state: 'completed',
|
||||
completedOn: now.toString(),
|
||||
);
|
||||
ref.watch(homeControllerProvider).edit(widget.item);
|
||||
|
||||
funcTimer.cancel();
|
||||
});
|
||||
} else {
|
||||
setState(() {
|
||||
widget.item =
|
||||
widget.item.copyWith(current: widget.item.current + 1);
|
||||
ref.watch(homeControllerProvider).edit(widget.item);
|
||||
});
|
||||
}
|
||||
},
|
||||
);
|
||||
} else if (widget.item.state == 'running') {
|
||||
widget.item = widget.item.copyWith(state: 'paused');
|
||||
ref.watch(homeControllerProvider).edit(widget.item);
|
||||
|
||||
_timer.cancel();
|
||||
} else if (widget.item.state == 'completed') {}
|
||||
}
|
||||
|
||||
void stopTimer() {
|
||||
setState(() {
|
||||
if (_timer.isActive) {
|
||||
_timer.cancel();
|
||||
}
|
||||
widget.item = widget.item.copyWith(
|
||||
current: 0,
|
||||
state: 'initial',
|
||||
);
|
||||
|
||||
ref.watch(homeControllerProvider).edit(widget.item);
|
||||
});
|
||||
}
|
||||
|
||||
String _formatCurrent() {
|
||||
final hours = (widget.item.current / 3600).floor();
|
||||
final minutes = ((widget.item.current - (hours * 3600)) / 60).floor();
|
||||
return '$hours hours : $minutes minutes';
|
||||
}
|
||||
|
||||
String _formattedTime() {
|
||||
final minutesTotal = widget.item.goal;
|
||||
|
||||
final hours = (minutesTotal / 60).floor();
|
||||
final minutes = minutesTotal - (hours * 60);
|
||||
return '$hours hours : $minutes minutes';
|
||||
}
|
||||
|
||||
void _toggleExpansion() {
|
||||
setState(() {
|
||||
widget.item = widget.item.copyWith(isExpanded: !widget.item.isExpanded);
|
||||
ref.watch(homeControllerProvider).edit(widget.item);
|
||||
});
|
||||
}
|
||||
|
||||
String _getButton1Text(BuildContext context) {
|
||||
if (widget.item.state == 'initial') {
|
||||
return AppLocalizations.of(context)!.timerWidget_buttonStart;
|
||||
} else if (widget.item.state == 'running') {
|
||||
return AppLocalizations.of(context)!.timerWidget_buttonPause;
|
||||
} else if (widget.item.state == 'paused') {
|
||||
return AppLocalizations.of(context)!.timerWidget_buttonContinue;
|
||||
}
|
||||
return 'Done';
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
ref
|
||||
..watch(homeControllerProvider)
|
||||
..watch(itemsProvider);
|
||||
|
||||
return Container(
|
||||
margin: const EdgeInsets.only(left: 10, top: 10, right: 10, bottom: 10),
|
||||
padding: const EdgeInsets.only(left: 10, top: 15, right: 10, bottom: 15),
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
borderRadius: const BorderRadius.all(Radius.circular(7)),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: const Color(0x00000000).withOpacity(0.25),
|
||||
spreadRadius: 2,
|
||||
blurRadius: 5,
|
||||
// changes position of shadow
|
||||
),
|
||||
],
|
||||
),
|
||||
width: double.infinity,
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
if (!widget.item.isExpanded) ...[
|
||||
Icon(
|
||||
Icons.timer,
|
||||
size: 20,
|
||||
color: Theme.of(context).colorScheme.onPrimary,
|
||||
),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Container(
|
||||
margin: const EdgeInsets.only(left: 10, right: 10),
|
||||
height: 30,
|
||||
child: ClipRRect(
|
||||
borderRadius: const BorderRadius.all(
|
||||
Radius.circular(5),
|
||||
), // Rounded corners
|
||||
child: LinearProgressIndicator(
|
||||
value:
|
||||
widget.getProgress(), // Progress value (0.0 - 1.0)
|
||||
backgroundColor:
|
||||
Colors.grey.withOpacity(0.5), // Background color
|
||||
valueColor: const AlwaysStoppedAnimation<Color>(
|
||||
Color(0xffA4E8FD),
|
||||
), // Progress color
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: Text(
|
||||
widget.item.name,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.onPrimary,
|
||||
// alignment: TextAlign.left,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
if (widget.item.isExpanded) ...[
|
||||
Expanded(
|
||||
child: Text(
|
||||
widget.item.name,
|
||||
textScaler: const TextScaler.linear(2),
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.onPrimary,
|
||||
|
||||
// alignment: TextAlign.left,
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 0,
|
||||
child: IconButton(
|
||||
icon: Icon(
|
||||
Icons.settings,
|
||||
color: Theme.of(context).colorScheme.onPrimary,
|
||||
),
|
||||
onPressed: () => _showSettingsMenu(ref),
|
||||
),
|
||||
),
|
||||
],
|
||||
Expanded(
|
||||
flex: 0,
|
||||
child: IconButton(
|
||||
icon: Icon(
|
||||
widget.item.isExpanded
|
||||
? Icons.arrow_drop_up_outlined
|
||||
: Icons.arrow_drop_down_circle_outlined,
|
||||
color: Theme.of(context).colorScheme.onPrimary,
|
||||
),
|
||||
onPressed: _toggleExpansion,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
if (widget.item.isExpanded) ...[
|
||||
// Additional child elements when expanded
|
||||
SizedBox(
|
||||
height: 300,
|
||||
width: MediaQuery.of(context).size.width,
|
||||
child: Column(
|
||||
children: [
|
||||
Stack(
|
||||
children: <Widget>[
|
||||
Container(
|
||||
alignment: Alignment.center,
|
||||
// color: Colors.blueAccent,
|
||||
width: MediaQuery.of(context).size.width,
|
||||
height: 250,
|
||||
child: SizedBox(
|
||||
height: 150,
|
||||
// color: Colors.greenAccent,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
// ignore: lines_longer_than_80_chars
|
||||
'${AppLocalizations.of(context)!.timerWidget_current}: ${_formatCurrent()} \n ${AppLocalizations.of(context)!.timerWidget_goal}: ${_formattedTime()}',
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodyMedium!
|
||||
.copyWith(
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.onPrimary,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
top: 10,
|
||||
left: MediaQuery.of(context).size.width * 0.15,
|
||||
width: MediaQuery.of(context).size.width * 0.60,
|
||||
height: 220,
|
||||
child: CircularProgressIndicator(
|
||||
color: Theme.of(context).colorScheme.onPrimary,
|
||||
strokeWidth: 7,
|
||||
value: widget.getProgress(),
|
||||
semanticsLabel: 'Circular progress indicator',
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Expanded(
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
TextButton(
|
||||
onPressed: handleButton1,
|
||||
child: Text(
|
||||
_getButton1Text(context),
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodyMedium!
|
||||
.copyWith(
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.onPrimary,
|
||||
),
|
||||
),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: stopTimer,
|
||||
child: Text(
|
||||
AppLocalizations.of(context)!
|
||||
.timerWidget_buttonReset,
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodyMedium!
|
||||
.copyWith(
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.onPrimary,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
// Add more widgets here as needed
|
||||
],
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _showSettingsMenu(WidgetRef ref) async {
|
||||
logger.i('Opening settings');
|
||||
|
||||
final settingEntries = WidgetSettingsData(
|
||||
entries: {
|
||||
'name': SettingEntryText(
|
||||
name: AppLocalizations.of(context)!.widgetSettings_name,
|
||||
defaultValue: widget.item.name,
|
||||
),
|
||||
'duration': SettingEntryDuration(
|
||||
name: AppLocalizations.of(context)!.timerWidgetSettings_duration,
|
||||
defaultValue: widget.item.goal,
|
||||
),
|
||||
},
|
||||
);
|
||||
|
||||
if (widget.item.state == 'running') {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(
|
||||
AppLocalizations.of(context)!.timerWidget_pausedForEdit,
|
||||
),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return showDialog<void>(
|
||||
context: context,
|
||||
barrierDismissible: false,
|
||||
builder: (BuildContext context) {
|
||||
return AlertDialog(
|
||||
backgroundColor: Theme.of(context).colorScheme.primaryContainer,
|
||||
content: WidgetSettings(
|
||||
entries: settingEntries,
|
||||
),
|
||||
actions: [
|
||||
OutlinedButton(
|
||||
style: OutlinedButton.styleFrom(
|
||||
backgroundColor: Colors.red,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
),
|
||||
onPressed: () async {
|
||||
ref.watch(itemsProvider);
|
||||
final items = ref.watch(homeControllerProvider);
|
||||
|
||||
widget.item = widget.item.copyWith(isVisible: false);
|
||||
setState(() {
|
||||
items.edit(widget.item);
|
||||
});
|
||||
|
||||
logger.i('Attempting delete');
|
||||
// ignore: use_build_context_synchronously
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
child: Text(
|
||||
AppLocalizations.of(context)!.widgetSettings_deleteButton,
|
||||
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
|
||||
color: Theme.of(context).colorScheme.onPrimary,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
backgroundColor: Theme.of(context).colorScheme.onPrimary,
|
||||
),
|
||||
onPressed: () {
|
||||
_timer.cancel();
|
||||
ref.watch(homeControllerProvider);
|
||||
|
||||
logger.i('Attempting edit of name and/or duration');
|
||||
|
||||
final name = settingEntries.getValue('name') as String;
|
||||
logger.i('New name: $name');
|
||||
final duration = settingEntries.getValue('duration') as int;
|
||||
widget.item =
|
||||
widget.item.copyWith(goal: duration, name: name);
|
||||
setState(() {
|
||||
ref.watch(homeControllerProvider).edit(widget.item);
|
||||
});
|
||||
logger.i('NAME AND DURATION SUCCESSFULLY UPDATED');
|
||||
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
child: Text(
|
||||
AppLocalizations.of(context)!.widgetSettings_saveButton,
|
||||
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue