Skip to content

Commit d4fed33

Browse files
inderjeet20Inderjeet Singh
andauthored
added full world clock functionality (#876)
Co-authored-by: Inderjeet Singh <inderjet05@gmail.com>
1 parent 6a2856c commit d4fed33

19 files changed

Lines changed: 738 additions & 2 deletions

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,4 +57,7 @@ app.*.map.json
5757
/.fvm
5858
/.tmp
5959
/caches
60-
/.fvmrc
60+
/.fvmrc
61+
62+
# FVM Version Cache
63+
.fvm/

.vscode/settings.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
{
2-
"cmake.sourceDirectory": "E:/ultimate_alarm_clock/linux"
2+
"cmake.sourceDirectory": "E:/ultimate_alarm_clock/linux",
3+
"dart.flutterSdkPath": ".fvm/versions/3.22.2"
34
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
class WorldClockModel {
2+
final String ianaTimezone;
3+
final String cityName;
4+
5+
WorldClockModel({required this.ianaTimezone, required this.cityName});
6+
7+
Map<String, dynamic> toJson() => {
8+
'ianaTimezone': ianaTimezone,
9+
'cityName': cityName,
10+
};
11+
12+
factory WorldClockModel.fromJson(Map<String, dynamic> json) => WorldClockModel(
13+
ianaTimezone: json['ianaTimezone'] as String,
14+
cityName: json['cityName'] as String,
15+
);
16+
}

lib/app/data/providers/get_storage_provider.dart

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import 'dart:ui';
22
import 'package:get/get.dart';
33
import 'package:get_storage/get_storage.dart';
44
import 'package:shared_preferences/shared_preferences.dart';
5+
import 'package:ultimate_alarm_clock/app/data/models/world_clock_model.dart';
56

67
class GetStorageProvider {
78
late final GetStorage _getStorage;
@@ -52,4 +53,16 @@ class GetStorageProvider {
5253
String profile = await _getStorage.read('profile') ?? 'Default';
5354
return profile;
5455
}
56+
57+
List<WorldClockModel> readWorldClocks() {
58+
final List<dynamic>? raw = _getStorage.read<List>('worldClocks');
59+
if (raw == null) return [];
60+
return raw
61+
.map((e) => WorldClockModel.fromJson(Map<String, dynamic>.from(e)))
62+
.toList();
63+
}
64+
65+
void writeWorldClocks(List<WorldClockModel> clocks) {
66+
_getStorage.write('worldClocks', clocks.map((e) => e.toJson()).toList());
67+
}
5568
}

lib/app/modules/bottomNavigationBar/bindings/bottom_navigation_bar_binding.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import 'package:get/get.dart';
22
import 'package:ultimate_alarm_clock/app/modules/bottomNavigationBar/controllers/bottom_navigation_bar_controller.dart';
33
import 'package:ultimate_alarm_clock/app/modules/settings/controllers/settings_controller.dart';
44
import 'package:ultimate_alarm_clock/app/modules/stopwatch/controllers/stopwatch_controller.dart';
5+
import 'package:ultimate_alarm_clock/app/modules/worldClock/controllers/world_clock_controller.dart';
56

67
class BottomNavigationBarBinding extends Bindings {
78
@override
@@ -14,5 +15,6 @@ class BottomNavigationBarBinding extends Bindings {
1415
() => StopwatchController(),
1516
);
1617
Get.lazyPut<SettingsController>(() => SettingsController(), fenix: true);
18+
Get.lazyPut<WorldClockController>(() => WorldClockController());
1719
}
1820
}

lib/app/modules/bottomNavigationBar/controllers/bottom_navigation_bar_controller.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import 'package:ultimate_alarm_clock/app/data/providers/secure_storage_provider.
44
import 'package:ultimate_alarm_clock/app/modules/home/views/home_view.dart';
55
import 'package:ultimate_alarm_clock/app/modules/stopwatch/views/stopwatch_view.dart';
66
import 'package:ultimate_alarm_clock/app/modules/timer/views/timer_view.dart';
7+
import 'package:ultimate_alarm_clock/app/modules/worldClock/views/world_clock_view.dart';
78

89
class BottomNavigationBarController extends GetxController
910
with WidgetsBindingObserver {
@@ -16,6 +17,7 @@ class BottomNavigationBarController extends GetxController
1617
HomeView(),
1718
StopwatchView(),
1819
TimerView(),
20+
WorldClockView(),
1921
];
2022

2123
@override

lib/app/modules/bottomNavigationBar/views/bottom_navigation_bar_view.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ class BottomNavigationBarView extends GetView<BottomNavigationBarController> {
5656
icon: const Icon(Icons.timelapse_outlined),
5757
label: 'Timer'.tr,
5858
),
59+
BottomNavigationBarItem(
60+
icon: const Icon(Icons.public_outlined),
61+
label: 'World Clock'.tr,
62+
),
5963
],
6064
onTap: (index) {
6165
Utils.hapticFeedback();
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import 'package:get/get.dart';
2+
import 'package:ultimate_alarm_clock/app/modules/worldClock/controllers/world_clock_controller.dart';
3+
4+
class WorldClockBinding extends Bindings {
5+
@override
6+
void dependencies() {
7+
Get.lazyPut<WorldClockController>(() => WorldClockController());
8+
}
9+
}
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import 'dart:async';
2+
3+
import 'package:get/get.dart';
4+
import 'package:intl/intl.dart';
5+
import 'package:timezone/timezone.dart' as tz;
6+
import 'package:ultimate_alarm_clock/app/data/models/world_clock_model.dart';
7+
import 'package:ultimate_alarm_clock/app/data/providers/get_storage_provider.dart';
8+
9+
class WorldClockController extends GetxController {
10+
final RxList<WorldClockModel> clocks = <WorldClockModel>[].obs;
11+
final RxInt tick = 0.obs;
12+
late final Timer _timer;
13+
14+
final GetStorageProvider _storage = Get.find<GetStorageProvider>();
15+
16+
@override
17+
void onInit() {
18+
super.onInit();
19+
clocks.assignAll(_storage.readWorldClocks());
20+
_timer = Timer.periodic(
21+
const Duration(seconds: 1),
22+
(_) => tick.value++,
23+
);
24+
}
25+
26+
@override
27+
void onClose() {
28+
_timer.cancel();
29+
super.onClose();
30+
}
31+
32+
void addClock(WorldClockModel clock) {
33+
clocks.add(clock);
34+
_storage.writeWorldClocks(clocks.toList());
35+
}
36+
37+
void removeClock(int index) {
38+
clocks.removeAt(index);
39+
_storage.writeWorldClocks(clocks.toList());
40+
}
41+
42+
String getCityTime(WorldClockModel clock, bool is24Hour) {
43+
final location = tz.getLocation(clock.ianaTimezone);
44+
final now = tz.TZDateTime.now(location);
45+
return is24Hour
46+
? DateFormat('HH:mm').format(now)
47+
: DateFormat('h:mm').format(now);
48+
}
49+
50+
String getCityTimePeriod(WorldClockModel clock) {
51+
final location = tz.getLocation(clock.ianaTimezone);
52+
final now = tz.TZDateTime.now(location);
53+
return DateFormat('a').format(now);
54+
}
55+
56+
String getCityDate(WorldClockModel clock) {
57+
final location = tz.getLocation(clock.ianaTimezone);
58+
final now = tz.TZDateTime.now(location);
59+
return DateFormat('EEE, MMM d').format(now);
60+
}
61+
62+
String getUtcOffset(WorldClockModel clock) {
63+
final location = tz.getLocation(clock.ianaTimezone);
64+
final now = tz.TZDateTime.now(location);
65+
final offset = now.timeZoneOffset;
66+
final sign = offset.isNegative ? '-' : '+';
67+
final hours = offset.inHours.abs();
68+
final minutes = offset.inMinutes.abs() % 60;
69+
return minutes == 0
70+
? 'UTC$sign$hours'
71+
: 'UTC$sign$hours:${minutes.toString().padLeft(2, '0')}';
72+
}
73+
74+
String getTimeDiff(WorldClockModel clock) {
75+
final location = tz.getLocation(clock.ianaTimezone);
76+
final now = tz.TZDateTime.now(location);
77+
final localOffset = DateTime.now().timeZoneOffset;
78+
final diff = now.timeZoneOffset - localOffset;
79+
if (diff == Duration.zero) return 'Local time';
80+
final sign = diff.isNegative ? '-' : '+';
81+
final h = diff.inHours.abs();
82+
final m = diff.inMinutes.abs() % 60;
83+
return m == 0
84+
? '${sign}${h}h from you'
85+
: '${sign}${h}h ${m}m from you';
86+
}
87+
}

0 commit comments

Comments
 (0)