119 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			Dart
		
	
	
	
	
	
			
		
		
	
	
			119 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			Dart
		
	
	
	
	
	
import 'dart:async';
 | 
						|
import 'package:app_links/app_links.dart';
 | 
						|
import 'package:flutter/material.dart';
 | 
						|
import 'package:flutter_hooks/flutter_hooks.dart';
 | 
						|
import 'package:hooks_riverpod/hooks_riverpod.dart';
 | 
						|
import 'package:island/pods/activity/activity_rpc.dart';
 | 
						|
import 'package:island/pods/websocket.dart';
 | 
						|
import 'package:island/route.dart';
 | 
						|
import 'package:island/screens/tray_manager.dart';
 | 
						|
import 'package:island/services/notify.dart';
 | 
						|
import 'package:island/services/sharing_intent.dart';
 | 
						|
import 'package:island/services/update_service.dart';
 | 
						|
import 'package:island/widgets/content/network_status_sheet.dart';
 | 
						|
import 'package:island/widgets/tour/tour.dart';
 | 
						|
import 'package:tray_manager/tray_manager.dart';
 | 
						|
import 'package:window_manager/window_manager.dart';
 | 
						|
 | 
						|
class AppWrapper extends HookConsumerWidget with TrayListener {
 | 
						|
  final Widget child;
 | 
						|
  const AppWrapper({super.key, required this.child});
 | 
						|
 | 
						|
  @override
 | 
						|
  Widget build(BuildContext context, WidgetRef ref) {
 | 
						|
    useEffect(() {
 | 
						|
      StreamSubscription? ntySubs;
 | 
						|
      StreamSubscription? appLinksSubs;
 | 
						|
      Future(() async {
 | 
						|
        final appLinks = AppLinks();
 | 
						|
 | 
						|
        if (context.mounted) ntySubs = setupNotificationListener(context, ref);
 | 
						|
 | 
						|
        final sharingService = SharingIntentService();
 | 
						|
        if (context.mounted) sharingService.initialize(context);
 | 
						|
        if (context.mounted) UpdateService().checkForUpdates(context);
 | 
						|
 | 
						|
        TrayService.instance.initialize(this);
 | 
						|
 | 
						|
        ref.read(rpcServerStateProvider.notifier).start();
 | 
						|
 | 
						|
        final initialUri = await appLinks.getLatestLink();
 | 
						|
        if (initialUri != null && context.mounted) {
 | 
						|
          WidgetsBinding.instance.addPostFrameCallback((_) {
 | 
						|
            _handleDeepLink(initialUri, ref);
 | 
						|
          });
 | 
						|
        }
 | 
						|
 | 
						|
        appLinksSubs = appLinks.uriLinkStream.listen((uri) {
 | 
						|
          _handleDeepLink(uri, ref);
 | 
						|
        });
 | 
						|
      });
 | 
						|
 | 
						|
      return () {
 | 
						|
        ref.read(rpcServerProvider).stop();
 | 
						|
        TrayService.instance.dispose(this);
 | 
						|
        ntySubs?.cancel();
 | 
						|
        appLinksSubs?.cancel();
 | 
						|
      };
 | 
						|
    }, const []);
 | 
						|
 | 
						|
    final wsNotifier = ref.watch(websocketStateProvider.notifier);
 | 
						|
    final websocketState = ref.watch(websocketStateProvider);
 | 
						|
 | 
						|
    final networkStateShowing = useState(false);
 | 
						|
 | 
						|
    if (websocketState == WebSocketState.duplicateDevice()) {
 | 
						|
      if (!networkStateShowing.value) {
 | 
						|
        WidgetsBinding.instance.addPostFrameCallback((_) {
 | 
						|
          networkStateShowing.value = true;
 | 
						|
          showModalBottomSheet(
 | 
						|
            context: context,
 | 
						|
            isScrollControlled: true,
 | 
						|
            isDismissible: false,
 | 
						|
            builder:
 | 
						|
                (context) =>
 | 
						|
                    NetworkStatusSheet(onReconnect: () => wsNotifier.connect()),
 | 
						|
          ).then((_) => networkStateShowing.value = false);
 | 
						|
        });
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    return TourTriggerWidget(key: UniqueKey(), child: child);
 | 
						|
  }
 | 
						|
 | 
						|
  void _trayIconPrimaryAction() {
 | 
						|
    windowManager.show();
 | 
						|
  }
 | 
						|
 | 
						|
  void _trayIconSecondaryAction() {
 | 
						|
    trayManager.popUpContextMenu();
 | 
						|
  }
 | 
						|
 | 
						|
  @override
 | 
						|
  void onTrayIconMouseUp() {
 | 
						|
    _trayIconPrimaryAction();
 | 
						|
  }
 | 
						|
 | 
						|
  @override
 | 
						|
  void onTrayIconRightMouseDown() {
 | 
						|
    _trayIconSecondaryAction();
 | 
						|
  }
 | 
						|
 | 
						|
  @override
 | 
						|
  void onTrayMenuItemClick(MenuItem menuItem) {
 | 
						|
    TrayService.instance.handleAction(menuItem);
 | 
						|
  }
 | 
						|
 | 
						|
  void _handleDeepLink(Uri uri, WidgetRef ref) {
 | 
						|
    final router = ref.read(routerProvider);
 | 
						|
    String path = '/${uri.path}';
 | 
						|
    if (uri.queryParameters.isNotEmpty) {
 | 
						|
      path =
 | 
						|
          Uri.parse(
 | 
						|
            path,
 | 
						|
          ).replace(queryParameters: uri.queryParameters).toString();
 | 
						|
    }
 | 
						|
    router.go(path);
 | 
						|
  }
 | 
						|
}
 |