| 1 | import 'dart:async'; |
| 2 | import 'dart:io'; |
| 3 | |
| 4 | import 'package:cw_core/utils/proxy_wrapper.dart'; |
| 5 | import 'package:cw_core/utils/print_verbose.dart'; |
| 6 | import 'package:cw_core/utils/tor/disabled.dart'; |
| 7 | import 'package:flutter/material.dart'; |
| 8 | |
| 9 | bool didTorStart = false; |
| 10 | Future<void> ensureTorStopped({required BuildContext? context}) async { |
| 11 | if (!didTorStart || CakeTor.instance is CakeTorDisabled) { |
| 12 | printV("Tor hasn't been initialized yet, so it can't be stopped."); |
| 13 | return; |
| 14 | } |
| 15 | BuildContext? dialogContext; |
| 16 | if (context != null) dialogContext = await showFullscreenDialog(context); |
| 17 | didTorStart = false; |
| 18 | printV("Stopping tor"); |
| 19 | await CakeTor.instance!.stop(); |
| 20 | printV("Tor stopped"); |
| 21 | if (context != null) dismissFullscreenDialog(dialogContext!); |
| 22 | } |
| 23 | |
| 24 | Future<void> ensureTorStarted({required BuildContext? context}) async { |
| 25 | if (didTorStart) { |
| 26 | printV("Tor has already started"); |
| 27 | return; |
| 28 | } |
| 29 | BuildContext? dialogContext; |
| 30 | if (context != null) dialogContext = await showFullscreenDialog(context); |
| 31 | didTorStart = true; |
| 32 | printV("Starting tor"); |
| 33 | // var rootToken = RootIsolateToken.instance!; |
| 34 | // await Isolate.run(() async { |
| 35 | // BackgroundIsolateBinaryMessenger.ensureInitialized(rootToken); |
| 36 | // await CakeTor.instance!.start(); |
| 37 | // }); |
| 38 | // second start is fast but populates the values on current thread |
| 39 | await CakeTor.instance!.start(); |
| 40 | printV("Tor started"); |
| 41 | while (!CakeTor.instance!.started) { |
| 42 | printV("Waiting for tor to start (part 1)"); |
| 43 | await Future.delayed(const Duration(seconds: 1)); |
| 44 | } |
| 45 | while (CakeTor.instance!.port == -1) { |
| 46 | printV("Waiting for tor to start (listening on port)"); |
| 47 | await Future.delayed(const Duration(seconds: 1)); |
| 48 | } |
| 49 | printV("Tor started on port ${CakeTor.instance!.port}"); |
| 50 | if (context != null) dismissFullscreenDialog(dialogContext!); |
| 51 | } |
| 52 | |
| 53 | Future<BuildContext> showFullscreenDialog(BuildContext context) async { |
| 54 | BuildContext? dialogContext; |
| 55 | unawaited( |
| 56 | showDialog( |
| 57 | context: context, |
| 58 | barrierDismissible: false, |
| 59 | builder: (context) { |
| 60 | dialogContext = context; |
| 61 | return PopScope( |
| 62 | canPop: false, |
| 63 | child: Container( |
| 64 | color: Colors.transparent, |
| 65 | child: Center( |
| 66 | child: CircularProgressIndicator( |
| 67 | color: Colors.white, |
| 68 | ), |
| 69 | ), |
| 70 | ), |
| 71 | ); |
| 72 | }, |
| 73 | ), |
| 74 | ); |
| 75 | await Future.delayed(const Duration(seconds: 1)); |
| 76 | return dialogContext!; |
| 77 | } |
| 78 | |
| 79 | Future<void> dismissFullscreenDialog(BuildContext context) async { |
| 80 | await Future.delayed(const Duration(seconds: 1)); |
| 81 | Navigator.of(context).pop(); |
| 82 | } |