diff --git a/lib/main.dart b/lib/main.dart index eba2e17c..8abd4ff2 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -50,7 +50,6 @@ DiscordRPC? discordRpc; WebViewEnvironment? webViewEnvironment; String? customDns; void main(List args) async { - cfResolutionWebviewServer(); WidgetsFlutterBinding.ensureInitialized(); if (Platform.isLinux && runWebViewTitleBarWidget(args)) return; MediaKit.ensureInitialized(); @@ -93,6 +92,7 @@ Future _postLaunchInit(StorageProvider storage) async { await discordRpc?.initialize(); } await storage.deleteBtDirectory(); + await cfResolutionWebviewServer(); } class MyApp extends ConsumerStatefulWidget { @@ -119,6 +119,8 @@ class _MyAppState extends ConsumerState { WidgetsBinding.instance.addPostFrameCallback((_) { if (ref.read(clearChapterCacheOnAppLaunchStateProvider)) { + // Watch before calling clearcache to keep it alive, so that _getTotalDiskSpace completes safely + ref.watch(totalChapterCacheSizeStateProvider); ref .read(totalChapterCacheSizeStateProvider.notifier) .clearCache(showToast: false); @@ -157,6 +159,7 @@ class _MyAppState extends ConsumerState { void dispose() { _linkSubscription?.cancel(); discordRpc?.destroy(); + stopCfResolutionWebviewServer(); AppLogger.dispose(); super.dispose(); } diff --git a/lib/modules/anime/anime_player_view.dart b/lib/modules/anime/anime_player_view.dart index 6fbfe08a..28cc93f7 100644 --- a/lib/modules/anime/anime_player_view.dart +++ b/lib/modules/anime/anime_player_view.dart @@ -964,30 +964,31 @@ mp.register_script_message('call_button_${button.id}_long', button${button.id}lo @override void dispose() { _currentPosition.removeListener(_updateRpcTimestamp); + _subDelayController.removeListener(_onSubDelayChanged); + _subSpeedController.removeListener(_onSubSpeedChanged); WidgetsBinding.instance.removeObserver(this); _setCurrentPosition(true); - _player.dispose(); + _player.stop(); + _completed.cancel(); _currentPositionSub.cancel(); _currentTotalDurationSub.cancel(); - _completed.cancel(); + _currentPosition.dispose(); + _currentTotalDuration.dispose(); _video.dispose(); _playbackSpeed.dispose(); _isDoubleSpeed.dispose(); - _currentTotalDuration.dispose(); _showFitLabel.dispose(); _isCompleted.dispose(); _tempPosition.dispose(); _fit.dispose(); - if (!_isDesktop) { - _setLandscapeMode(false); - } _skipPhase.dispose(); - discordRpc?.showIdleText(); - discordRpc?.showOriginalTimestamp(); - _currentPosition.dispose(); _subDelayController.dispose(); _subSpeedController.dispose(); + if (!_isDesktop) _setLandscapeMode(false); + discordRpc?.showIdleText(); + discordRpc?.showOriginalTimestamp(); _streamController.keepAliveLink?.close(); + _player.dispose(); super.dispose(); } diff --git a/lib/modules/manga/detail/providers/update_manga_detail_providers.dart b/lib/modules/manga/detail/providers/update_manga_detail_providers.dart index d19d088e..d78ce051 100644 --- a/lib/modules/manga/detail/providers/update_manga_detail_providers.dart +++ b/lib/modules/manga/detail/providers/update_manga_detail_providers.dart @@ -35,7 +35,7 @@ Future updateMangaDetail( final genre = getManga.genre - ?.map((e) => e.toString().trim().trimLeft().trimRight()) + ?.map((e) => e.toString().trim()) .toList() .toSet() .toList() ?? @@ -80,7 +80,7 @@ Future updateMangaDetail( for (var i = 0; i < newChapsIndex; i++) { final chapter = Chapter( name: chaps[i].name!, - url: chaps[i].url!.trim().trimLeft().trimRight(), + url: chaps[i].url!.trim(), dateUpload: chaps[i].dateUpload == null ? DateTime.now().millisecondsSinceEpoch.toString() : chaps[i].dateUpload.toString(), @@ -171,8 +171,8 @@ Future updateMangaDetail( extension DefaultValueExtension on String? { String? trimmedOrDefault(String? defaultValue) { - if (this?.trim().trimLeft().trimRight().isNotEmpty ?? false) { - return this!.trim().trimLeft().trimRight(); + if (this?.trim().isNotEmpty ?? false) { + return this!.trim(); } return defaultValue; } diff --git a/lib/modules/more/data_and_storage/providers/storage_usage.dart b/lib/modules/more/data_and_storage/providers/storage_usage.dart index 663d5b65..fa8fc1eb 100644 --- a/lib/modules/more/data_and_storage/providers/storage_usage.dart +++ b/lib/modules/more/data_and_storage/providers/storage_usage.dart @@ -14,7 +14,10 @@ part 'storage_usage.g.dart'; class TotalChapterCacheSizeState extends _$TotalChapterCacheSizeState { @override String build() { - _getTotalDiskSpace().then((value) => state = _formatBytes(value)); + _getTotalDiskSpace().then((value) { + if (!ref.mounted) return; + state = _formatBytes(value); + }); return "0.00 B"; } diff --git a/lib/services/http/m_client.dart b/lib/services/http/m_client.dart index dd68ca1d..0fb3c1e1 100644 --- a/lib/services/http/m_client.dart +++ b/lib/services/http/m_client.dart @@ -292,20 +292,44 @@ class ResolveCloudFlareChallenge extends RetryPolicy { } int cfPort = 0; -void cfResolutionWebviewServer() async { - final server = await HttpServer.bind(InternetAddress.loopbackIPv4, cfPort); - cfPort = server.port; +HttpServer? _cfServer; - server.listen((HttpRequest request) { - if (request.method == 'POST' && request.uri.path == '/resolve_cf') { - _handleResolveCf(request); - } else { - request.response - ..statusCode = HttpStatus.notFound - ..write('Not Found') - ..close(); - } - }); +/// Cloudflare Resolution Webview Server +Future cfResolutionWebviewServer() async { + try { + _cfServer = await HttpServer.bind(InternetAddress.loopbackIPv4, cfPort); + cfPort = _cfServer!.port; + _cfServer!.listen( + (HttpRequest request) { + if (request.method == 'POST' && request.uri.path == '/resolve_cf') { + _handleResolveCf(request); + } else { + request.response + ..statusCode = HttpStatus.notFound + ..write('Not Found') + ..close(); + } + }, + onError: (e, st) { + debugPrint("CF server listener error: $e\n$st"); + }, + cancelOnError: false, + ); + } catch (e, st) { + debugPrint("Couldn't start Cloudflare Resolution Webview Server: $e\n$st"); + botToast("Couldn't start Cloudflare Resolution Webview Server."); + } +} + +Future stopCfResolutionWebviewServer() async { + final server = _cfServer; + if (server == null) return; + try { + await server.close(force: true); + } finally { + _cfServer = null; + cfPort = 0; + } } void _handleResolveCf(HttpRequest request) async {