Skip to content

Commit

Permalink
precache the timetable background when app was resumed
Browse files Browse the repository at this point in the history
  • Loading branch information
liplum committed Sep 23, 2024
1 parent a6806f7 commit 7a451dc
Showing 1 changed file with 104 additions and 85 deletions.
189 changes: 104 additions & 85 deletions lib/app.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:mimir/agreements/entity/agreements.dart';
import 'package:mimir/agreements/page/privacy_policy.dart';
import 'package:mimir/credentials/init.dart';
import 'package:mimir/files.dart';
import 'package:mimir/intent/file_type/handle.dart';
import 'package:mimir/lifecycle.dart';
Expand Down Expand Up @@ -45,6 +46,8 @@ class _MimirAppState extends ConsumerState<MimirApp> {
Settings.timetable.focusTimetable ? buildTimetableFocusRouter() : buildCommonRoutingConfig(),
);
late final router = buildRouter($routingConfig);
StreamSubscription? intentSub;
StreamSubscription? $appLink;

@override
void initState() {
Expand All @@ -55,6 +58,47 @@ class _MimirAppState extends ConsumerState<MimirApp> {
);
SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge);
}
if (!kIsWeb) {
fitSystemScreenshot.init();
}

WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
$appLink = AppLinks().uriLinkStream.listen(handleUriLink);
});
if (UniversalPlatform.isIOS || UniversalPlatform.isAndroid) {
// Listen to media sharing coming from outside the app while the app is in the memory.
intentSub = ReceiveSharingIntent.instance.getMediaStream().listen((list) async {
ref.read($intentFiles.notifier).state = [
...ref.read($intentFiles),
...list,
];
await handleFileIntents(list);
}, onError: (error) {
debugPrintError(error);
});

// Get the media sharing coming from outside the app while the app is closed.
ReceiveSharingIntent.instance.getInitialMedia().then((list) async {
ref.read($intentFiles.notifier).state = [
...ref.read($intentFiles),
...list,
];
await handleFileIntents(list);
if (UniversalPlatform.isIOS) {
await Future.wait(list.map((file) => File(file.path).delete(recursive: false)));
}
// Tell the library that we are done processing the intent.
ReceiveSharingIntent.instance.reset();
});
}
}

@override
void dispose() {
$appLink?.cancel();
fitSystemScreenshot.release();
intentSub?.cancel();
super.dispose();
}

@override
Expand Down Expand Up @@ -123,6 +167,28 @@ class _MimirAppState extends ConsumerState<MimirApp> {
),
);
}

Future<void> handleUriLink(Uri uri) async {
ref.read($appLinks.notifier).state = [...ref.read($appLinks), (uri: uri, ts: DateTime.now())];
final navigateCtx = $key.currentContext;
if (navigateCtx == null) return;
if (!kIsWeb) {
final maybePath = Uri.decodeFull(uri.toString());
if (uri.scheme == "file") {
await onHandleFilePath(context: navigateCtx, path: maybePath);
return;
} else {
final isFile = await File(maybePath).exists();
if (isFile) {
if (!navigateCtx.mounted) return;
await onHandleFilePath(context: navigateCtx, path: maybePath);
return;
}
}
}
if (!navigateCtx.mounted) return;
await onHandleDeepLink(context: navigateCtx, deepLink: uri);
}
}

class _PostServiceRunner extends ConsumerStatefulWidget {
Expand All @@ -138,122 +204,66 @@ class _PostServiceRunner extends ConsumerStatefulWidget {
}

class _PostServiceRunnerState extends ConsumerState<_PostServiceRunner> {
StreamSubscription? intentSub;
StreamSubscription? $appLink;
late final AppLifecycleListener _listener;

@override
void initState() {
super.initState();
_listener = AppLifecycleListener(
onResume: onResume,
);
if (!kIsWeb) {
fitSystemScreenshot.init();
}
if (!kIsWeb) {
Future.delayed(Duration.zero).then((value) async {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
await checkAppUpdate(
context: $key.currentContext!,
delayAtLeast: const Duration(milliseconds: 3000),
manually: false,
);
});
}
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
$appLink = AppLinks().uriLinkStream.listen(handleUriLink);
});
if (UniversalPlatform.isIOS || UniversalPlatform.isAndroid) {
initQuickActions();
// Listen to media sharing coming from outside the app while the app is in the memory.
intentSub = ReceiveSharingIntent.instance.getMediaStream().listen((list) async {
ref.read($intentFiles.notifier).state = [
...ref.read($intentFiles),
...list,
];
await handleFileIntents(list);
}, onError: (error) {
debugPrintError(error);
});

// Get the media sharing coming from outside the app while the app is closed.
ReceiveSharingIntent.instance.getInitialMedia().then((list) async {
ref.read($intentFiles.notifier).state = [
...ref.read($intentFiles),
...list,
];
await handleFileIntents(list);
if (UniversalPlatform.isIOS) {
await Future.wait(list.map((file) => File(file.path).delete(recursive: false)));
}
// Tell the library that we are done processing the intent.
ReceiveSharingIntent.instance.reset();
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
await tryAutoSyncTimetable();
});
}
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
await tryAutoSyncTimetable();
});
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
final navigateCtx = $key.currentContext;
if (navigateCtx == null) return;
final accepted = ref.read(Settings.agreements.$basicAcceptanceOf(AgreementVersion.current));
if (accepted == true) return;
await AgreementsAcceptanceSheet.show(navigateCtx);
});
}

Future<void> handleFileIntents(List<SharedMediaFile> files) async {
final navigateCtx = $key.currentContext;
if (navigateCtx == null) return;
for (final file in files) {
// ignore the url intent from the this app
if (file.type == SharedMediaType.url) {
final uri = Uri.tryParse(file.path);
if (uri != null && canHandleDeepLink(deepLink: uri)) continue;
}
if (!navigateCtx.mounted) return;
await onHandleFilePath(context: navigateCtx, path: file.path);
if (UniversalPlatform.isIOS || UniversalPlatform.isAndroid) {
initQuickActions();
}
}

@override
void didChangeDependencies() {
void dispose() {
_listener.dispose();
super.dispose();
}

Future<void> onResume() async {
await precacheTimetableBackground();
}

Future<void> precacheTimetableBackground() async {
// precache timetable background file
final timetableBk = Settings.timetable.backgroundImage;
if (timetableBk != null && timetableBk.enabled) {
if (kIsWeb) {
precacheImage(NetworkImage(timetableBk.path), context);
await precacheImage(NetworkImage(timetableBk.path), context);
} else {
precacheImage(FileImage(Files.timetable.backgroundFile), context);
await precacheImage(FileImage(Files.timetable.backgroundFile), context);
}
}
super.didChangeDependencies();
}

@override
void dispose() {
$appLink?.cancel();
fitSystemScreenshot.release();
intentSub?.cancel();
super.dispose();
}

Future<void> handleUriLink(Uri uri) async {
ref.read($appLinks.notifier).state = [...ref.read($appLinks), (uri: uri, ts: DateTime.now())];
final navigateCtx = $key.currentContext;
if (navigateCtx == null) return;
if (!kIsWeb) {
final maybePath = Uri.decodeFull(uri.toString());
if (uri.scheme == "file") {
await onHandleFilePath(context: navigateCtx, path: maybePath);
return;
} else {
final isFile = await File(maybePath).exists();
if (isFile) {
if (!navigateCtx.mounted) return;
await onHandleFilePath(context: navigateCtx, path: maybePath);
return;
}
}
}
if (!navigateCtx.mounted) return;
await onHandleDeepLink(context: navigateCtx, deepLink: uri);
Widget build(BuildContext context) {
ref.listen(CredentialsInit.storage.oa.$credentials, (pre, next) async {
await initQuickActions();
});
return widget.child;
}

Future<void> tryAutoSyncTimetable() async {
Expand All @@ -271,9 +281,18 @@ class _PostServiceRunnerState extends ConsumerState<_PostServiceRunner> {
}
}
}
}

@override
Widget build(BuildContext context) {
return widget.child;
Future<void> handleFileIntents(List<SharedMediaFile> files) async {
final navigateCtx = $key.currentContext;
if (navigateCtx == null) return;
for (final file in files) {
// ignore the url intent from the this app
if (file.type == SharedMediaType.url) {
final uri = Uri.tryParse(file.path);
if (uri != null && canHandleDeepLink(deepLink: uri)) continue;
}
if (!navigateCtx.mounted) return;
await onHandleFilePath(context: navigateCtx, path: file.path);
}
}

0 comments on commit 7a451dc

Please sign in to comment.