Skip to content

Commit 11bdb15

Browse files
committed
DateTime: add datetime page/model/service (#291)
1 parent 36a1167 commit 11bdb15

File tree

11 files changed

+1148
-34
lines changed

11 files changed

+1148
-34
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,6 @@ sudo apt install libhandy-1-dev
8989
- [X] Accessability page
9090
- [ ] Users page
9191
- [ ] Preferred apps page
92-
- [ ] Date and time page
92+
- [X] Date and time page
9393
- [ ] Wacom page
9494
- [X] Info page

lib/l10n/app_de.arb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,5 +120,11 @@
120120
"usersPageTitle": "Benutzer",
121121
"defaultAppsPageTitle": "Vorgabeanwendungen",
122122
"dateAndTimePageTitle": "Datum und Uhrzeit",
123+
"dateAndTimePageAutoDateTime": "Datum und Zeit automatisch setzen",
124+
"dateAndTimePageAutoTimezone": "Zeitzone automatisch setzen ",
125+
"dateAndTimePageTwentyFour": "24-Stunden Format",
126+
"dateAndTimePageSecondsInPanel": "Zeige Sekunden in Leiste",
127+
"dateAndTimePageWeekdayInPanel": "Zeige Wochentag in Leiste",
128+
"dateAndTimePageWeekNumberInCalendar": "Zeige Kalenderwoche in Leiste",
123129
"infoPageTitle": "Info"
124130
}

lib/l10n/app_en.arb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,5 +120,11 @@
120120
"usersPageTitle": "Users",
121121
"defaultAppsPageTitle": "Default Applications",
122122
"dateAndTimePageTitle": "Date and time",
123+
"dateAndTimePageAutoDateTime": "Automatic date and time",
124+
"dateAndTimePageAutoTimezone": "Automatic timezone",
125+
"dateAndTimePageTwentyFour": "24h format",
126+
"dateAndTimePageSecondsInPanel": "Show seconds in panel",
127+
"dateAndTimePageWeekdayInPanel": "Show weekday in panel",
128+
"dateAndTimePageWeekNumberInCalendar": "Show week number in calendar",
123129
"infoPageTitle": "Info"
124130
}

lib/main.dart

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import 'package:provider/provider.dart';
55
import 'package:settings/app.dart';
66
import 'package:settings/schemas/schemas.dart';
77
import 'package:settings/services/bluetooth_service.dart';
8+
import 'package:settings/services/date_time_service.dart';
89
import 'package:settings/services/hostname_service.dart';
910
import 'package:settings/services/house_keeping_service.dart';
1011
import 'package:settings/services/input_source_service.dart';
@@ -68,7 +69,12 @@ void main() async {
6869
),
6970
Provider<HouseKeepingService>(
7071
create: (_) => HouseKeepingService(),
71-
)
72+
dispose: (_, service) => service.dispose(),
73+
),
74+
Provider<DateTimeService>(
75+
create: (_) => DateTimeService(),
76+
dispose: (_, service) => service.dispose(),
77+
),
7278
],
7379
child: const UbuntuSettingsApp(),
7480
),

lib/schemas/schemas.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,5 @@ const schemaPrivacy = 'org.gnome.desktop.privacy';
2626
const schemaLocation = 'org.gnome.system.location';
2727
const schemaScreenSaver = 'org.gnome.desktop.screensaver';
2828
const schemaSession = 'org.gnome.desktop.session';
29+
const schemaDateTime = 'org.gnome.desktop.datetime';
30+
const schemaCalendar = 'org.gnome.desktop.calendar';
Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
import 'dart:async';
2+
3+
import 'package:dbus/dbus.dart';
4+
5+
const _kDateTimeInterface = 'org.freedesktop.timedate1';
6+
const _kDateTimePath = '/org/freedesktop/timedate1';
7+
// const _kListTimezoneMethodName = 'ListTimezones';
8+
// const _kSetLocalRtcMethodName = 'SetLocalRTC';
9+
const _kSetNtpMethodName = 'SetNTP';
10+
const _kSetTimeMethodName = 'SetTime';
11+
const _kSetTimezoneMethodName = 'SetTimezone';
12+
// const _kCanNTPPropertyName = 'CanNTP';
13+
// const _kLocalRTCPropertyName = 'LocalRTC';
14+
const _kNTPPropertyName = 'NTP';
15+
// const _kNTPSynchronizedPropertyName = 'NTPSynchronized';
16+
// const _kRTCTimeUSecPropertyName = 'RTCTimeUSec';
17+
const _kTimeUSecPropertyName = 'TimeUSec';
18+
const _kTimezonePropertyName = 'Timezone';
19+
20+
class DateTimeService {
21+
DateTimeService() : _object = _createObject();
22+
23+
final DBusRemoteObject _object;
24+
StreamSubscription<DBusPropertiesChangedSignal>? _propertyListener;
25+
26+
static DBusRemoteObject _createObject() =>
27+
DBusRemoteObject(DBusClient.system(),
28+
name: _kDateTimeInterface, path: DBusObjectPath(_kDateTimePath));
29+
30+
Future<void> init() async {
31+
await _initTimezone();
32+
await _initNtp();
33+
_dateTime = await getDateTime();
34+
_propertyListener ??= _object.propertiesChanged.listen(_updateProperties);
35+
}
36+
37+
void _updateProperties(DBusPropertiesChangedSignal signal) {
38+
if (signal.hasChangedTimeZone()) {
39+
_object.getTimezone().then(_updateTimezone);
40+
_object.getDateTime().then(_updateDateTime);
41+
}
42+
if (signal.hasChangedDateTime()) {
43+
_object.getDateTime().then(_updateDateTime);
44+
}
45+
if (signal.hasChangedNtp()) {
46+
_object.getNtp().then(_updateNtp);
47+
}
48+
}
49+
50+
Future<void> dispose() async {
51+
await _propertyListener?.cancel();
52+
await _object.client.close();
53+
_propertyListener = null;
54+
}
55+
56+
// Timezone
57+
String? _timezone;
58+
String? get timezone => _timezone;
59+
set timezone(String? value) {
60+
if (value == null) return;
61+
_object.setTimeZone(value);
62+
}
63+
64+
Stream<String?> get timezoneChanged => _timezoneController.stream;
65+
final _timezoneController = StreamController<String?>.broadcast();
66+
67+
void _updateTimezone(String? value) {
68+
if (_timezone == value) return;
69+
_timezone = value;
70+
if (!_timezoneController.isClosed) {
71+
_timezoneController.add(_timezone);
72+
}
73+
}
74+
75+
Future<void> _initTimezone() async {
76+
_updateTimezone(await _object.getTimezone());
77+
}
78+
79+
// Date and time
80+
DateTime? _dateTime;
81+
DateTime? get dateTime => _dateTime;
82+
set dateTime(DateTime? dateTime) {
83+
if (dateTime == null) return;
84+
_object.setTime(dateTime.microsecondsSinceEpoch);
85+
}
86+
87+
void _updateDateTime(DateTime? value) {
88+
if (_dateTime?.second == value?.second) return;
89+
getDateTime().then((value) => _dateTime = value);
90+
}
91+
92+
Future<DateTime?> getDateTime() async {
93+
return await _object.getDateTime();
94+
}
95+
96+
// NTP
97+
bool? _ntp;
98+
bool? get ntp => _ntp;
99+
set ntp(bool? value) {
100+
if (value == null) return;
101+
_object.setNtp(value);
102+
}
103+
104+
Stream<bool?> get ntpChanged => _ntpController.stream;
105+
final _ntpController = StreamController<bool?>.broadcast();
106+
107+
void _updateNtp(bool? value) {
108+
if (_ntp == value) return;
109+
_ntp = value;
110+
if (!_ntpController.isClosed) {
111+
_ntpController.add(_ntp);
112+
}
113+
}
114+
115+
Future<void> _initNtp() async {
116+
_updateNtp(await _object.getNtp());
117+
}
118+
}
119+
120+
extension _DateTimeRemoteObject on DBusRemoteObject {
121+
Future<String?> getTimezone() async {
122+
final timeZone =
123+
await getProperty(_kDateTimeInterface, _kTimezonePropertyName);
124+
return (timeZone as DBusString).value;
125+
}
126+
127+
Future<void> setTimeZone(String timezone) async {
128+
final args = [DBusString(timezone), const DBusBoolean(false)];
129+
callMethod(_kDateTimeInterface, _kSetTimezoneMethodName, args);
130+
}
131+
132+
Future<void> setTime(int time) async {
133+
bool? ntp = await getNtp();
134+
if (ntp == null || ntp == true) return;
135+
final args = [
136+
DBusInt64(time),
137+
const DBusBoolean(false),
138+
const DBusBoolean(false)
139+
];
140+
callMethod(_kDateTimeInterface, _kSetTimeMethodName, args);
141+
}
142+
143+
Future<DateTime?> getDateTime() async {
144+
final timeUSec =
145+
await getProperty(_kDateTimeInterface, _kTimeUSecPropertyName);
146+
return DateTime.fromMicrosecondsSinceEpoch((timeUSec as DBusUint64).value);
147+
}
148+
149+
Future<bool?> getNtp() async {
150+
final ntpSync = await getProperty(_kDateTimeInterface, _kNTPPropertyName);
151+
return (ntpSync as DBusBoolean).value;
152+
}
153+
154+
Future<void> setNtp(bool? value) async {
155+
if (value == null) return;
156+
final args = [DBusBoolean(value), const DBusBoolean(false)];
157+
callMethod(_kDateTimeInterface, _kSetNtpMethodName, args);
158+
}
159+
}
160+
161+
extension _ChangedDateTime on DBusPropertiesChangedSignal {
162+
bool hasChangedTimeZone() {
163+
return changedProperties.containsKey(_kTimezonePropertyName);
164+
}
165+
166+
bool hasChangedDateTime() {
167+
return changedProperties.containsKey(_kTimeUSecPropertyName);
168+
}
169+
170+
bool hasChangedNtp() {
171+
return changedProperties.containsKey(_kNTPPropertyName);
172+
}
173+
}

lib/view/pages/date_and_time/date_and_time_page.dart

Lines changed: 0 additions & 28 deletions
This file was deleted.

0 commit comments

Comments
 (0)