Skip to content

Commit

Permalink
new package for timer, and bit ui change (#11)
Browse files Browse the repository at this point in the history
  • Loading branch information
byonicku authored Oct 2, 2023
1 parent 0a23d77 commit 834f3e9
Show file tree
Hide file tree
Showing 5 changed files with 148 additions and 51 deletions.
44 changes: 32 additions & 12 deletions lib/displayLayers/OverlayLayer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@ class OverlayLayer extends ConsumerWidget {
final displayStateWatcher = ref.watch(displayStateProvider);
return Animate(
effects: const [
SlideEffect(duration: Duration(milliseconds: 450), curve: Curves.easeOutCubic, begin: Offset(-1, 0), end: Offset(0, 0))
SlideEffect(
duration: Duration(milliseconds: 450),
curve: Curves.easeOutCubic,
begin: Offset(-1, 0),
end: Offset(0, 0))
],
target: (displayStateWatcher.settingsExpanded == true) ? 1 : 0,
child: ClipRect(
Expand Down Expand Up @@ -49,7 +53,10 @@ class SettingsPanelInside extends ConsumerWidget {
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
TextButton(onPressed: () => ref.read(displayStateProvider).toggleSettingsExpanded(), child: const Icon(Icons.arrow_back)),
TextButton(
onPressed: () =>
ref.read(displayStateProvider).toggleSettingsExpanded(),
child: const Icon(Icons.arrow_back)),
const Text(
"Settings",
style: TextStyle(fontSize: 32),
Expand Down Expand Up @@ -104,11 +111,13 @@ class TimerControlSection extends ConsumerWidget {
)
: IconButton(
icon: const Icon(Icons.play_arrow),
onPressed: () => ref.read(timerProvider.notifier).startTimer(),
onPressed: () =>
ref.read(timerProvider.notifier).startTimer(),
),
IconButton(
icon: const Icon(Icons.replay),
onPressed: () => ref.read(timerProvider.notifier).stopAndResetTimer(),
onPressed: () =>
ref.read(timerProvider.notifier).stopAndResetTimer(),
),
],
),
Expand Down Expand Up @@ -158,7 +167,9 @@ class MainTimerSection extends ConsumerWidget {
"${ref.watch(timerProvider).mainTimer.inMinutes} minutes",
style: const TextStyle(fontSize: 20),
),
onTap: () async => ref.read(timerProvider).setMainTimer(timeFromPicker: await ShowTimePickerDialog(context)),
onTap: () async => ref
.read(timerProvider)
.setMainTimer(timeFromPicker: await ShowTimePickerDialog(context)),
),
);
}
Expand All @@ -177,7 +188,8 @@ class AssistTimerSection extends ConsumerWidget {
"${ref.watch(timerProvider).assistTimer.inMinutes} minutes",
style: const TextStyle(fontSize: 20),
),
onTap: () async => ref.read(timerProvider).setAssistTimer(timeFromPicker: await ShowTimePickerDialog(context)),
onTap: () async => ref.read(timerProvider).setAssistTimer(
timeFromPicker: await ShowTimePickerDialog(context)),
),
);
}
Expand All @@ -196,7 +208,9 @@ class BonusTimerSection extends ConsumerWidget {
"${ref.watch(timerProvider).bonusTimer.inMinutes} minutes",
style: const TextStyle(fontSize: 20),
),
onTap: () async => ref.read(timerProvider).setBonusTimer(timeFromPicker: await ShowTimePickerDialog(context)),
onTap: () async => ref
.read(timerProvider)
.setBonusTimer(timeFromPicker: await ShowTimePickerDialog(context)),
),
);
}
Expand All @@ -215,7 +229,8 @@ class TextScaleFactorSection extends ConsumerWidget {
min: 0.8,
max: 1.8,
divisions: 11,
onChanged: (value) => ref.read(displayStateProvider).setDisplayFontScale(value),
onChanged: (value) =>
ref.read(displayStateProvider).setDisplayFontScale(value),
),
trailing: Text(
ref.watch(displayStateProvider).displayFontScale.toStringAsFixed(1),
Expand All @@ -236,9 +251,11 @@ class ThemeModeSection extends ConsumerWidget {
title: const Text("Application Theme"),
subtitle: const Text("Select application theme"),
trailing: DropdownButton<String>(
value: ref.watch(timerProvider).dispEtc.currentThemeMode == ThemeMode.light
value: ref.watch(timerProvider).dispEtc.currentThemeMode ==
ThemeMode.light
? "Light"
: ref.watch(timerProvider).dispEtc.currentThemeMode == ThemeMode.dark
: ref.watch(timerProvider).dispEtc.currentThemeMode ==
ThemeMode.dark
? "Dark"
: "System",
items: themeModeNames.map<DropdownMenuItem<String>>((String value) {
Expand Down Expand Up @@ -300,7 +317,9 @@ class AboutUs extends StatelessWidget {

Future<void> _launchURL() async {
final url = Uri.parse('https://www.github.com/bootloopmaster636/ugd_timer');
await canLaunchUrl(url) ? await launchUrl(url) : throw 'Could not launch $url';
await canLaunchUrl(url)
? await launchUrl(url)
: throw 'Could not launch $url';
}
}

Expand All @@ -324,7 +343,8 @@ Future<TimeOfDay?> ShowTimePickerDialog(BuildContext context) async {
initialTime: const TimeOfDay(hour: 0, minute: 0),
builder: (BuildContext context, Widget? child) {
return MediaQuery(
data: MediaQuery.of(context).copyWith(alwaysUse24HourFormat: true, textScaleFactor: 1.2),
data: MediaQuery.of(context)
.copyWith(alwaysUse24HourFormat: true, textScaleFactor: 1.2),
child: child!,
);
});
Expand Down
92 changes: 69 additions & 23 deletions lib/displayLayers/TopLayer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,16 @@ class TopLayer extends ConsumerWidget {
final displayStateWatcher = ref.watch(displayStateProvider);
return Animate(
effects: const [
SlideEffect(duration: Duration(milliseconds: 450), curve: Curves.easeOutCubic, begin: Offset(0, 0), end: Offset(0.06, 0)),
FadeEffect(duration: Duration(milliseconds: 450), curve: Curves.easeOutCubic, begin: 1.0, end: 0.6),
SlideEffect(
duration: Duration(milliseconds: 450),
curve: Curves.easeOutCubic,
begin: Offset(0, 0),
end: Offset(0.06, 0)),
FadeEffect(
duration: Duration(milliseconds: 450),
curve: Curves.easeOutCubic,
begin: 1.0,
end: 0.6),
],
target: (displayStateWatcher.settingsExpanded == true) ? 1 : 0,
child: Column(
Expand Down Expand Up @@ -47,7 +55,8 @@ class TopBar extends ConsumerWidget {
final timerWatcher = ref.watch(timerProvider);
return Container(
height: 50 * scaleFactor,
decoration: BoxDecoration(color: Theme.of(context).colorScheme.background.withAlpha(180)),
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.background.withAlpha(180)),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
Expand Down Expand Up @@ -138,10 +147,23 @@ class InfoCard extends ConsumerWidget {
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
"Pengumpulan pada pukul ${ref.watch(timerProvider).endAt.hour.toString().padLeft(2, '0')}:${ref.watch(timerProvider).endAt.minute. toString().padLeft(2, '0')}",
style: const TextStyle(fontSize: 28, fontWeight: FontWeight.w600),
"Pengumpulan pada pukul",
style: TextStyle(
fontSize: 28 * scaleFactor,
fontWeight: FontWeight.w600,
),
),
Text(
"${ref.watch(timerProvider).endAt.hour.toString().padLeft(2, '0')}:${ref.watch(timerProvider).endAt.minute.toString().padLeft(2, '0')}",
style: TextStyle(
fontSize: 48 * scaleFactor,
fontWeight: FontWeight.bold,
color: Theme.of(context).colorScheme.onSecondaryContainer,
),
),
SizedBox(
height: 56 * scaleFactor,
),
SizedBox(height: 56 * scaleFactor,),
Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
Expand All @@ -151,17 +173,29 @@ class InfoCard extends ConsumerWidget {
size: 64 * scaleFactor,
color: Theme.of(context).colorScheme.onPrimaryContainer,
),
SizedBox(width: 24 * scaleFactor,),
SizedBox(
width: 24 * scaleFactor,
),
RichText(
text: TextSpan(text: "Dapat bertanya asisten setelah\n",
style: TextStyle(fontSize: 24 * scaleFactor, color: Theme.of(context).colorScheme.onTertiaryContainer),
children: [TextSpan(
text: "${ref.watch(timerProvider).assistTimer.inMinutes.toString().padLeft(2, '0')} menit "
text: TextSpan(
text: "Dapat bertanya asisten setelah\n",
style: TextStyle(
fontSize: 24 * scaleFactor,
color: Theme.of(context).colorScheme.onTertiaryContainer),
children: [
TextSpan(
text:
"${ref.watch(timerProvider).assistTimer.inMinutes.toString().padLeft(2, '0')} menit "
"${ref.watch(timerProvider).assistTimer.inSeconds.remainder(60).toString().padLeft(2, '0')} detik",
style: TextStyle(fontSize: 32 * scaleFactor, fontWeight: FontWeight.bold, color: Theme.of(context).colorScheme.onSecondaryContainer),
),
],
),
style: TextStyle(
fontSize: 32 * scaleFactor,
fontWeight: FontWeight.bold,
color: Theme.of(context)
.colorScheme
.onSecondaryContainer),
),
],
),
),
Container(
padding: EdgeInsets.symmetric(horizontal: 40 * scaleFactor),
Expand All @@ -176,15 +210,27 @@ class InfoCard extends ConsumerWidget {
size: 64 * scaleFactor,
color: Theme.of(context).colorScheme.onPrimaryContainer,
),
SizedBox(width: 12 * scaleFactor,),
SizedBox(
width: 12 * scaleFactor,
),
RichText(
text: TextSpan(text: "Sisa waktu bonus\n",
style: TextStyle(fontSize: 24 * scaleFactor, color: Theme.of(context).colorScheme.onTertiaryContainer),
children: [TextSpan(
text: "${ref.watch(timerProvider).bonusTimer.inMinutes.toString().padLeft(2, '0')} menit "
"${ref.watch(timerProvider).bonusTimer.inSeconds.remainder(60).toString().padLeft(2, '0')} detik",
style: TextStyle(fontSize: 32 * scaleFactor, fontWeight: FontWeight.bold, color: Theme.of(context).colorScheme.onSecondaryContainer),
),
text: TextSpan(
text: "Sisa waktu bonus\n",
style: TextStyle(
fontSize: 24 * scaleFactor,
color: Theme.of(context).colorScheme.onTertiaryContainer),
children: [
TextSpan(
text:
"${ref.watch(timerProvider).bonusTimer.inMinutes.toString().padLeft(2, '0')} menit "
"${ref.watch(timerProvider).bonusTimer.inSeconds.remainder(60).toString().padLeft(2, '0')} detik",
style: TextStyle(
fontSize: 32 * scaleFactor,
fontWeight: FontWeight.bold,
color: Theme.of(context)
.colorScheme
.onSecondaryContainer),
),
],
),
)
Expand Down
54 changes: 38 additions & 16 deletions lib/logic/mainLogic.dart
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:ugd_timer/logic/themeAndInfo.dart';
import 'package:pausable_timer/pausable_timer.dart';

class TimerController extends ChangeNotifier {
bool _isRunning = false;
bool _isSet = false;
Duration _mainTimerFreezed = const Duration(hours: 0, minutes: 0, seconds: 0);
Duration _mainTimer = const Duration(hours: 0, minutes: 0, seconds: 0);
Duration _assistTimer = const Duration(minutes: 0, seconds: 0);
Duration _bonusTimer = const Duration(minutes: 0, seconds: 0);
TimeOfDay _endAt = const TimeOfDay(hour: 0, minute: 0);
final DisplayEtc _dispEtc =
DisplayEtc("", Colors.lightBlue, ThemeMode.system);
late PausableTimer timer;

// ============== Time getter =============
bool get isRunning => _isRunning;
Expand Down Expand Up @@ -41,6 +43,8 @@ class TimerController extends ChangeNotifier {
} else {
_mainTimer = const Duration(hours: 0, minutes: 0, seconds: 0);
}

makeEndAt();
notifyListeners();
}

Expand Down Expand Up @@ -111,41 +115,59 @@ class TimerController extends ChangeNotifier {
return;
}

if (_isSet) {
// if timer is already set, then just resume it.
makeEndAt();
timer.start();
} else {
// if timer is not set, then set it and start the countdown.
_isSet = true;
startCountdown();
}

_isRunning = true;
startCountdown();
notifyListeners();
}

void pauseTimer() async {
_isRunning = false;
timer.pause();
notifyListeners();
}

void stopAndResetTimer() {
timer.cancel();
_isRunning = false;
_isSet = false;
setMainTimer(reset: true);
setAssistTimer(reset: true);
setBonusTimer(reset: true);
_endAt = const TimeOfDay(hour: 0, minute: 0);
notifyListeners();
}

void startCountdown() async {
makeEndAt();

Timer.periodic(const Duration(seconds: 1), (timer) {
if (_isRunning && _mainTimer.inSeconds > 0) {
decrementTimer("main");
decrementTimer("assist");
decrementTimer("bonus");
_dispEtc.dynamicAccentChanger(_mainTimer, _mainTimerFreezed);
} else if (!_isRunning && _mainTimer.inSeconds > 0) {
timer.cancel();
} else {
stopAndResetTimer();
}
notifyListeners();
});
timer = PausableTimer(
const Duration(seconds: 1),
() {
if (_isRunning && _mainTimer.inSeconds > 0) {
_dispEtc.dynamicAccentChanger(_mainTimer, _mainTimerFreezed);

decrementTimer("main");
decrementTimer("assist");
decrementTimer("bonus");

// To continously repeat this timer till end.
timer
..reset()
..start();
} else {
stopAndResetTimer();
}
notifyListeners();
},
)..start();
}

// ============= App config interface =============
Expand Down
8 changes: 8 additions & 0 deletions pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.8.3"
pausable_timer:
dependency: "direct main"
description:
name: pausable_timer
sha256: "35b1f77eb2fb0f42e823360321fbed9b9a8b1c7043a07a58aeda17d01f84659a"
url: "https://pub.dev"
source: hosted
version: "2.0.0+1"
plugin_platform_interface:
dependency: transitive
description:
Expand Down
1 change: 1 addition & 0 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ dependencies:
window_manager: ^0.3.6
override_text_scale_factor: ^1.0.2
url_launcher: ^6.1.14
pausable_timer: ^2.0.0+1

dev_dependencies:
flutter_test:
Expand Down

0 comments on commit 834f3e9

Please sign in to comment.