Add automatic Google calendar sync
This commit is contained in:
@@ -28,21 +28,30 @@ class AccountsPage extends StatefulWidget {
|
|||||||
|
|
||||||
class _AccountsPageState extends State<AccountsPage>
|
class _AccountsPageState extends State<AccountsPage>
|
||||||
with WidgetsBindingObserver {
|
with WidgetsBindingObserver {
|
||||||
|
static const googleAutoSyncInterval = Duration(minutes: 5);
|
||||||
|
static const googleResumeSyncInterval = Duration(minutes: 2);
|
||||||
|
|
||||||
List<GoogleCalendarInfo> googleCalendars = [];
|
List<GoogleCalendarInfo> googleCalendars = [];
|
||||||
bool loadingCalendars = false;
|
bool loadingCalendars = false;
|
||||||
bool syncing = false;
|
bool syncing = false;
|
||||||
bool waitingForGoogleAuthReturn = false;
|
bool waitingForGoogleAuthReturn = false;
|
||||||
|
Timer? googleAutoSyncTimer;
|
||||||
String? statusMessage;
|
String? statusMessage;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
WidgetsBinding.instance.addObserver(this);
|
WidgetsBinding.instance.addObserver(this);
|
||||||
|
googleAutoSyncTimer = Timer.periodic(
|
||||||
|
googleAutoSyncInterval,
|
||||||
|
(_) => _autoSyncSelectedCalendars(),
|
||||||
|
);
|
||||||
_loadGoogleConnectionStatus();
|
_loadGoogleConnectionStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
|
googleAutoSyncTimer?.cancel();
|
||||||
WidgetsBinding.instance.removeObserver(this);
|
WidgetsBinding.instance.removeObserver(this);
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
@@ -66,6 +75,10 @@ class _AccountsPageState extends State<AccountsPage>
|
|||||||
if (state == AppLifecycleState.resumed && waitingForGoogleAuthReturn) {
|
if (state == AppLifecycleState.resumed && waitingForGoogleAuthReturn) {
|
||||||
waitingForGoogleAuthReturn = false;
|
waitingForGoogleAuthReturn = false;
|
||||||
_loadGoogleConnectionStatus();
|
_loadGoogleConnectionStatus();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (state == AppLifecycleState.resumed) {
|
||||||
|
_autoSyncSelectedCalendars(minAge: googleResumeSyncInterval);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,6 +119,30 @@ class _AccountsPageState extends State<AccountsPage>
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool _canAutoSync() {
|
||||||
|
final current = connection;
|
||||||
|
return current != null &&
|
||||||
|
current.accountEmail.isNotEmpty &&
|
||||||
|
current.enabledCalendarIds.isNotEmpty &&
|
||||||
|
!syncing &&
|
||||||
|
!loadingCalendars &&
|
||||||
|
_jarvisConfigError() == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _autoSyncSelectedCalendars({
|
||||||
|
Duration minAge = googleAutoSyncInterval,
|
||||||
|
}) async {
|
||||||
|
final current = connection;
|
||||||
|
if (!_canAutoSync() || current == null) return;
|
||||||
|
|
||||||
|
final lastSync = current.lastSync;
|
||||||
|
if (lastSync != null && DateTime.now().difference(lastSync) < minAge) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await _syncSelectedCalendars(automatic: true);
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> _loadGoogleConnectionStatus() async {
|
Future<void> _loadGoogleConnectionStatus() async {
|
||||||
setState(() {
|
setState(() {
|
||||||
loadingCalendars = true;
|
loadingCalendars = true;
|
||||||
@@ -287,9 +324,10 @@ class _AccountsPageState extends State<AccountsPage>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _syncSelectedCalendars() async {
|
Future<void> _syncSelectedCalendars({bool automatic = false}) async {
|
||||||
final current = connection;
|
final current = connection;
|
||||||
if (current == null || current.enabledCalendarIds.isEmpty) {
|
if (current == null || current.enabledCalendarIds.isEmpty) {
|
||||||
|
if (automatic) return;
|
||||||
setState(
|
setState(
|
||||||
() => statusMessage =
|
() => statusMessage =
|
||||||
'V\u00e1lassz ki legal\u00e1bb egy Google napt\u00e1rat.',
|
'V\u00e1lassz ki legal\u00e1bb egy Google napt\u00e1rat.',
|
||||||
@@ -299,7 +337,9 @@ class _AccountsPageState extends State<AccountsPage>
|
|||||||
|
|
||||||
setState(() {
|
setState(() {
|
||||||
syncing = true;
|
syncing = true;
|
||||||
statusMessage = 'Google esem\u00e9nyek beolvas\u00e1sa...';
|
statusMessage = automatic
|
||||||
|
? 'Automatikus Google szinkron fut...'
|
||||||
|
: 'Google esem\u00e9nyek beolvas\u00e1sa...';
|
||||||
});
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -377,14 +417,17 @@ class _AccountsPageState extends State<AccountsPage>
|
|||||||
]);
|
]);
|
||||||
setState(() {
|
setState(() {
|
||||||
syncing = false;
|
syncing = false;
|
||||||
statusMessage =
|
statusMessage = automatic
|
||||||
'${synced.length} Google esem\u00e9ny szinkroniz\u00e1lva \u00e9s JSON cache-be mentve.'
|
? '${synced.length} Google esem\u00e9ny automatikusan friss\u00edtve.'
|
||||||
|
: '${synced.length} Google esem\u00e9ny szinkroniz\u00e1lva \u00e9s JSON cache-be mentve.'
|
||||||
'${syncDetails.isEmpty ? '' : ' R\u00e9szletek: ${syncDetails.join('; ')}.'}';
|
'${syncDetails.isEmpty ? '' : ' R\u00e9szletek: ${syncDetails.join('; ')}.'}';
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setState(() {
|
setState(() {
|
||||||
syncing = false;
|
syncing = false;
|
||||||
statusMessage = 'A Google szinkron nem siker\u00fclt: $error';
|
statusMessage = automatic
|
||||||
|
? 'Az automatikus Google szinkron most nem siker\u00fclt, a kor\u00e1bbi cache marad: $error'
|
||||||
|
: 'A Google szinkron nem siker\u00fclt: $error';
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user