mirror of
https://github.com/kodjodevf/mangayomi.git
synced 2026-01-11 22:40:36 +00:00
Added cronet_http & cupertino_http, remove unnecessary packages
This commit is contained in:
parent
6fa0e8a89f
commit
d168b6ddcd
30 changed files with 1148 additions and 971 deletions
1315
Cargo.lock
generated
1315
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
|
@ -2,6 +2,7 @@ import 'dart:convert';
|
|||
import 'package:dart_eval/dart_eval.dart';
|
||||
import 'package:dart_eval/dart_eval_bridge.dart';
|
||||
import 'package:dart_eval/stdlib/core.dart';
|
||||
import 'package:flutter_qjs/flutter_qjs.dart';
|
||||
import 'package:mangayomi/eval/dart/bridge/document.dart';
|
||||
import 'package:mangayomi/eval/dart/bridge/filter.dart';
|
||||
import 'package:mangayomi/eval/dart/bridge/m_manga.dart';
|
||||
|
|
@ -16,7 +17,6 @@ import 'package:mangayomi/eval/dart/model/m_manga.dart';
|
|||
import 'package:mangayomi/eval/dart/model/m_provider.dart';
|
||||
import 'package:mangayomi/models/video.dart';
|
||||
import 'package:mangayomi/modules/browse/extension/providers/extension_preferences_providers.dart';
|
||||
import 'package:mangayomi/services/boa_js.dart';
|
||||
|
||||
class $MProvider extends MProvider with $Bridge<MProvider> {
|
||||
static $MProvider $construct(
|
||||
|
|
@ -748,8 +748,10 @@ class $MProvider extends MProvider with $Bridge<MProvider> {
|
|||
$Value? $bridgeGet(String identifier) {
|
||||
return switch (identifier) {
|
||||
'evalJs' => $Function((_, __, List<$Value?> args) {
|
||||
return $Future
|
||||
.wrap(evalJs(args[0]!.$reified).then((value) => $String(value)));
|
||||
final runtime = getJavascriptRuntime();
|
||||
return $Future.wrap(runtime
|
||||
.evaluateAsync(args[0]!.$reified)
|
||||
.then((value) => $String(value.stringResult)));
|
||||
}),
|
||||
'getUrlWithoutDomain' => $Function((_, __, List<$Value?> args) {
|
||||
final uri = Uri.parse(args[0]!.$value.replaceAll(' ', '%20'));
|
||||
|
|
|
|||
|
|
@ -4,7 +4,9 @@ import 'package:desktop_webview_window/desktop_webview_window.dart';
|
|||
import 'package:flex_color_scheme/flex_color_scheme.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:google_api_availability/google_api_availability.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:intl/date_symbol_data_local.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
|
@ -25,6 +27,9 @@ import 'package:window_manager/window_manager.dart';
|
|||
// Global instance of the Isar database.
|
||||
late Isar isar;
|
||||
|
||||
GooglePlayServicesAvailability playStoreAvailability =
|
||||
GooglePlayServicesAvailability.unknown;
|
||||
|
||||
/// Overrides the default HTTP client to allow all certificates
|
||||
class MyHttpoverrides extends HttpOverrides {
|
||||
@override
|
||||
|
|
@ -57,6 +62,14 @@ void main(List<String> args) async {
|
|||
isar = await StorageProvider().initDB(null, inspector: kDebugMode);
|
||||
await StorageProvider().requestPermission();
|
||||
GoogleFonts.aBeeZee();
|
||||
if (Platform.isAndroid) {
|
||||
try {
|
||||
playStoreAvailability = await GoogleApiAvailability.instance
|
||||
.checkGooglePlayServicesAvailability();
|
||||
} on PlatformException {
|
||||
playStoreAvailability = GooglePlayServicesAvailability.unknown;
|
||||
}
|
||||
}
|
||||
// Start the app.
|
||||
runApp(const ProviderScope(child: MyApp()));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -107,7 +107,8 @@ class Source {
|
|||
version = json['version'];
|
||||
versionLast = json['versionLast'];
|
||||
additionalParams = json['additionalParams'] ?? "";
|
||||
sourceCodeLanguage = SourceCodeLanguage.values[json['sourceCodeLanguage']];
|
||||
sourceCodeLanguage =
|
||||
SourceCodeLanguage.values[json['sourceCodeLanguage'] ?? 0];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:isar/isar.dart';
|
||||
import 'package:mangayomi/eval/dart/model/source_preference.dart';
|
||||
import 'package:mangayomi/main.dart';
|
||||
import 'package:mangayomi/models/source.dart';
|
||||
|
|
@ -8,6 +8,8 @@ import 'package:mangayomi/modules/browse/extension/providers/extension_preferenc
|
|||
import 'package:mangayomi/modules/browse/extension/widgets/source_preference_widget.dart';
|
||||
import 'package:mangayomi/providers/l10n_providers.dart';
|
||||
import 'package:mangayomi/services/get_source_preference.dart';
|
||||
import 'package:mangayomi/sources/source_test.dart';
|
||||
import 'package:mangayomi/utils/cached_network.dart';
|
||||
import 'package:mangayomi/utils/extensions/build_context_extensions.dart';
|
||||
import 'package:mangayomi/utils/language.dart';
|
||||
|
||||
|
|
@ -22,6 +24,7 @@ class ExtensionDetail extends ConsumerStatefulWidget {
|
|||
class _ExtensionDetailState extends ConsumerState<ExtensionDetail> {
|
||||
late Source source = widget.source;
|
||||
List<SourcePreference> sourcePreference = [];
|
||||
bool _isLoading = true;
|
||||
@override
|
||||
void initState() {
|
||||
getSourcePreferenceAsync(source: source).then((value) {
|
||||
|
|
@ -30,10 +33,11 @@ class _ExtensionDetailState extends ConsumerState<ExtensionDetail> {
|
|||
sourcePreference = value
|
||||
.map((e) => getSourcePreferenceEntry(e.key!, source.id!))
|
||||
.toList();
|
||||
_isLoading = false;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
print(source.id);
|
||||
super.initState();
|
||||
}
|
||||
|
||||
|
|
@ -56,20 +60,19 @@ class _ExtensionDetailState extends ConsumerState<ExtensionDetail> {
|
|||
borderRadius: BorderRadius.circular(10)),
|
||||
child: widget.source.iconUrl!.isEmpty
|
||||
? const Icon(Icons.source_outlined, size: 140)
|
||||
: CachedNetworkImage(
|
||||
: cachedNetworkImage(
|
||||
imageUrl: widget.source.iconUrl!,
|
||||
fit: BoxFit.contain,
|
||||
width: 140,
|
||||
height: 140,
|
||||
errorWidget: (context, url, error) {
|
||||
return const SizedBox(
|
||||
width: 140,
|
||||
height: 140,
|
||||
child: Center(
|
||||
child: Icon(Icons.source_outlined, size: 140),
|
||||
),
|
||||
);
|
||||
},
|
||||
errorWidget: const SizedBox(
|
||||
width: 140,
|
||||
height: 140,
|
||||
child: Center(
|
||||
child: Icon(Icons.source_outlined, size: 140),
|
||||
),
|
||||
),
|
||||
headers: {},
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
@ -176,11 +179,34 @@ class _ExtensionDetailState extends ConsumerState<ExtensionDetail> {
|
|||
),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
isar.writeTxnSync(() =>
|
||||
final sourcePrefsIds = isar
|
||||
.sourcePreferences
|
||||
.filter()
|
||||
.sourceIdEqualTo(source.id!)
|
||||
.findAllSync()
|
||||
.map((e) => e.id!)
|
||||
.toList();
|
||||
final sourcePrefsStringIds = isar
|
||||
.sourcePreferenceStringValues
|
||||
.filter()
|
||||
.sourceIdEqualTo(source.id!)
|
||||
.findAllSync()
|
||||
.map((e) => e.id)
|
||||
.toList();
|
||||
isar.writeTxnSync(() {
|
||||
if (!useTestSourceCode) {
|
||||
isar.sources.putSync(widget.source
|
||||
..sourceCode = ""
|
||||
..isAdded = false
|
||||
..isPinned = false));
|
||||
..isPinned = false);
|
||||
}
|
||||
isar.sourcePreferences
|
||||
.deleteAllSync(sourcePrefsIds);
|
||||
isar.sourcePreferenceStringValues
|
||||
.deleteAllSync(
|
||||
sourcePrefsStringIds);
|
||||
});
|
||||
|
||||
Navigator.pop(ctx);
|
||||
Navigator.pop(context);
|
||||
},
|
||||
|
|
@ -198,8 +224,9 @@ class _ExtensionDetailState extends ConsumerState<ExtensionDetail> {
|
|||
)),
|
||||
),
|
||||
),
|
||||
SourcePreferenceWidget(
|
||||
sourcePreference: sourcePreference, source: source)
|
||||
if (!_isLoading)
|
||||
SourcePreferenceWidget(
|
||||
sourcePreference: sourcePreference, source: source)
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
|
@ -7,6 +6,7 @@ import 'package:mangayomi/models/source.dart';
|
|||
import 'package:mangayomi/modules/browse/extension/providers/fetch_anime_sources.dart';
|
||||
import 'package:mangayomi/modules/browse/extension/providers/fetch_manga_sources.dart';
|
||||
import 'package:mangayomi/providers/l10n_providers.dart';
|
||||
import 'package:mangayomi/utils/cached_network.dart';
|
||||
import 'package:mangayomi/utils/language.dart';
|
||||
|
||||
class ExtensionListTileWidget extends ConsumerStatefulWidget {
|
||||
|
|
@ -68,20 +68,19 @@ class _ExtensionListTileWidgetState
|
|||
borderRadius: BorderRadius.circular(5)),
|
||||
child: widget.source.iconUrl!.isEmpty
|
||||
? const Icon(Icons.source_outlined)
|
||||
: CachedNetworkImage(
|
||||
: cachedNetworkImage(
|
||||
imageUrl: widget.source.iconUrl!,
|
||||
fit: BoxFit.contain,
|
||||
width: 37,
|
||||
height: 37,
|
||||
errorWidget: (context, url, error) {
|
||||
return const SizedBox(
|
||||
width: 37,
|
||||
height: 37,
|
||||
child: Center(
|
||||
child: Icon(Icons.source_outlined),
|
||||
),
|
||||
);
|
||||
},
|
||||
errorWidget: const SizedBox(
|
||||
width: 37,
|
||||
height: 37,
|
||||
child: Center(
|
||||
child: Icon(Icons.source_outlined),
|
||||
),
|
||||
),
|
||||
headers: {},
|
||||
),
|
||||
),
|
||||
title: Text(widget.source.name!),
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:grouped_list/grouped_list.dart';
|
||||
|
|
@ -7,6 +6,7 @@ import 'package:mangayomi/main.dart';
|
|||
import 'package:mangayomi/models/source.dart';
|
||||
import 'package:mangayomi/modules/more/settings/browse/providers/browse_state_provider.dart';
|
||||
import 'package:mangayomi/providers/l10n_providers.dart';
|
||||
import 'package:mangayomi/utils/cached_network.dart';
|
||||
import 'package:mangayomi/utils/language.dart';
|
||||
|
||||
class SourcesFilterScreen extends ConsumerWidget {
|
||||
|
|
@ -86,20 +86,18 @@ class SourcesFilterScreen extends ConsumerWidget {
|
|||
borderRadius: BorderRadius.circular(5)),
|
||||
child: element.iconUrl!.isEmpty
|
||||
? const Icon(Icons.source_outlined)
|
||||
: CachedNetworkImage(
|
||||
: cachedNetworkImage(
|
||||
imageUrl: element.iconUrl!,
|
||||
fit: BoxFit.contain,
|
||||
width: 37,
|
||||
height: 37,
|
||||
errorWidget: (context, url, error) {
|
||||
return const SizedBox(
|
||||
width: 37,
|
||||
height: 37,
|
||||
child: Center(
|
||||
child: Icon(Icons.source_outlined),
|
||||
),
|
||||
);
|
||||
},
|
||||
errorWidget: const SizedBox(
|
||||
width: 37,
|
||||
height: 37,
|
||||
child: Center(
|
||||
child: Icon(Icons.source_outlined),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
onChanged: (bool? value) {
|
||||
|
|
|
|||
|
|
@ -6,9 +6,9 @@ import 'package:mangayomi/main.dart';
|
|||
import 'package:mangayomi/models/source.dart';
|
||||
import 'package:mangayomi/providers/l10n_providers.dart';
|
||||
import 'package:mangayomi/sources/source_test.dart';
|
||||
import 'package:mangayomi/utils/cached_network.dart';
|
||||
import 'package:mangayomi/utils/extensions/build_context_extensions.dart';
|
||||
import 'package:mangayomi/utils/language.dart';
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
|
||||
class SourceListTile extends StatelessWidget {
|
||||
final bool isManga;
|
||||
|
|
@ -46,20 +46,18 @@ class SourceListTile extends StatelessWidget {
|
|||
borderRadius: BorderRadius.circular(5)),
|
||||
child: source.iconUrl!.isEmpty
|
||||
? const Icon(Icons.source_outlined)
|
||||
: CachedNetworkImage(
|
||||
: cachedNetworkImage(
|
||||
imageUrl: source.iconUrl!,
|
||||
fit: BoxFit.contain,
|
||||
width: 37,
|
||||
height: 37,
|
||||
errorWidget: (context, url, error) {
|
||||
return const SizedBox(
|
||||
width: 37,
|
||||
height: 37,
|
||||
child: Center(
|
||||
child: Icon(Icons.source_outlined),
|
||||
),
|
||||
);
|
||||
},
|
||||
errorWidget: const SizedBox(
|
||||
width: 37,
|
||||
height: 37,
|
||||
child: Center(
|
||||
child: Icon(Icons.source_outlined),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
subtitle: Row(
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import 'dart:typed_data';
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:isar/isar.dart';
|
||||
|
|
@ -10,6 +9,7 @@ import 'package:mangayomi/modules/library/providers/library_state_provider.dart'
|
|||
import 'package:mangayomi/modules/library/widgets/measure_widget_sync.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/providers/push_router.dart';
|
||||
import 'package:mangayomi/models/manga.dart';
|
||||
import 'package:mangayomi/modules/widgets/custom_extended_image_provider.dart';
|
||||
import 'package:mangayomi/utils/extensions/build_context_extensions.dart';
|
||||
import 'package:mangayomi/utils/constant.dart';
|
||||
import 'package:mangayomi/utils/headers.dart';
|
||||
|
|
@ -103,7 +103,7 @@ class _LibraryGridViewWidgetState extends State<LibraryGridViewWidget> {
|
|||
image: entry.customCoverImage != null
|
||||
? MemoryImage(entry.customCoverImage as Uint8List)
|
||||
as ImageProvider
|
||||
: CachedNetworkImageProvider(
|
||||
: CustomExtendedNetworkImageProvider(
|
||||
toImgUrl(entry.customCoverFromTracker ??
|
||||
entry.imageUrl!),
|
||||
headers: entry.isLocalArchive!
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import 'dart:typed_data';
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:isar/isar.dart';
|
||||
|
|
@ -9,6 +8,7 @@ import 'package:mangayomi/modules/history/providers/isar_providers.dart';
|
|||
import 'package:mangayomi/modules/library/providers/library_state_provider.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/providers/push_router.dart';
|
||||
import 'package:mangayomi/models/manga.dart';
|
||||
import 'package:mangayomi/modules/widgets/custom_extended_image_provider.dart';
|
||||
import 'package:mangayomi/utils/extensions/build_context_extensions.dart';
|
||||
import 'package:mangayomi/utils/constant.dart';
|
||||
import 'package:mangayomi/utils/headers.dart';
|
||||
|
|
@ -98,7 +98,7 @@ class LibraryListViewWidget extends StatelessWidget {
|
|||
image: entry.customCoverImage != null
|
||||
? MemoryImage(entry.customCoverImage
|
||||
as Uint8List) as ImageProvider
|
||||
: CachedNetworkImageProvider(
|
||||
: CustomExtendedNetworkImageProvider(
|
||||
toImgUrl(
|
||||
entry.customCoverFromTracker ??
|
||||
entry.imageUrl!),
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import 'dart:io';
|
||||
import 'dart:typed_data';
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:draggable_menu/draggable_menu.dart';
|
||||
import 'package:file_picker/file_picker.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
|
@ -24,6 +23,7 @@ import 'package:mangayomi/modules/manga/reader/providers/reader_controller_provi
|
|||
import 'package:mangayomi/modules/more/settings/appearance/providers/pure_black_dark_mode_state_provider.dart';
|
||||
import 'package:mangayomi/modules/more/settings/track/widgets/track_listile.dart';
|
||||
import 'package:mangayomi/modules/widgets/custom_draggable_tabbar.dart';
|
||||
import 'package:mangayomi/modules/widgets/custom_extended_image_provider.dart';
|
||||
import 'package:mangayomi/modules/widgets/draggable_scroll_bar.dart';
|
||||
import 'package:mangayomi/providers/l10n_providers.dart';
|
||||
import 'package:mangayomi/providers/storage_provider.dart';
|
||||
|
|
@ -1366,7 +1366,7 @@ class _MangaDetailViewState extends ConsumerState<MangaDetailView>
|
|||
final imageProvider = widget.manga!.customCoverImage != null
|
||||
? MemoryImage(widget.manga!.customCoverImage as Uint8List)
|
||||
as ImageProvider
|
||||
: CachedNetworkImageProvider(
|
||||
: CustomExtendedNetworkImageProvider(
|
||||
toImgUrl(widget.manga!.customCoverFromTracker ??
|
||||
widget.manga!.imageUrl!),
|
||||
headers: widget.manga!.isLocalArchive!
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:draggable_menu/draggable_menu.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:mangayomi/models/track.dart';
|
||||
import 'package:mangayomi/models/track_search.dart';
|
||||
import 'package:mangayomi/modules/manga/detail/providers/track_state_providers.dart';
|
||||
import 'package:mangayomi/modules/widgets/custom_extended_image_provider.dart';
|
||||
import 'package:mangayomi/modules/widgets/progress_center.dart';
|
||||
import 'package:mangayomi/utils/extensions/build_context_extensions.dart';
|
||||
|
||||
|
|
@ -84,8 +84,9 @@ class _TrackerWidgetSearchState extends ConsumerState<TrackerWidgetSearch> {
|
|||
height: 120,
|
||||
width: 80,
|
||||
fit: BoxFit.cover,
|
||||
image: CachedNetworkImageProvider(
|
||||
tracks![index].coverUrl!),
|
||||
image:
|
||||
CustomExtendedNetworkImageProvider(
|
||||
tracks![index].coverUrl!),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import 'package:mangayomi/modules/manga/reader/providers/reader_controller_provi
|
|||
import 'package:mangayomi/modules/manga/reader/reader_view.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/widgets/color_filter_widget.dart';
|
||||
import 'package:mangayomi/modules/more/settings/reader/providers/reader_state_provider.dart';
|
||||
import 'package:mangayomi/modules/widgets/custom_extended_image_provider.dart';
|
||||
import 'package:mangayomi/utils/headers.dart';
|
||||
import 'package:mangayomi/utils/reg_exp_matcher.dart';
|
||||
|
||||
|
|
@ -43,7 +44,7 @@ class ImageViewCenter extends ConsumerWidget {
|
|||
? ExtendedMemoryImageProvider(archiveImage)
|
||||
: ExtendedFileImageProvider(
|
||||
File('${datas.path!.path}${padIndex(datas.index! + 1)}.jpg'))
|
||||
: ExtendedNetworkImageProvider(datas.url!.trim().trimLeft().trimRight(),
|
||||
: CustomExtendedNetworkImageProvider(datas.url!.trim().trimLeft().trimRight(),
|
||||
cache: true,
|
||||
cacheMaxAge: const Duration(days: 7),
|
||||
headers: ref.watch(headersProvider(
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import 'package:mangayomi/modules/manga/reader/providers/reader_controller_provi
|
|||
import 'package:mangayomi/modules/manga/reader/reader_view.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/widgets/color_filter_widget.dart';
|
||||
import 'package:mangayomi/modules/more/settings/reader/providers/reader_state_provider.dart';
|
||||
import 'package:mangayomi/modules/widgets/custom_extended_image_provider.dart';
|
||||
import 'package:mangayomi/providers/l10n_providers.dart';
|
||||
import 'package:mangayomi/utils/extensions/build_context_extensions.dart';
|
||||
import 'package:mangayomi/utils/headers.dart';
|
||||
|
|
@ -42,7 +43,7 @@ class ImageViewVertical extends ConsumerWidget {
|
|||
? ExtendedMemoryImageProvider(archiveImage)
|
||||
: ExtendedFileImageProvider(
|
||||
File('${datas.path!.path}${padIndex(datas.index! + 1)}.jpg'))
|
||||
: ExtendedNetworkImageProvider(datas.url!.trim().trimLeft().trimRight(),
|
||||
: CustomExtendedNetworkImageProvider(datas.url!.trim().trimLeft().trimRight(),
|
||||
cache: true,
|
||||
cacheMaxAge: const Duration(days: 7),
|
||||
headers: ref.watch(headersProvider(
|
||||
|
|
|
|||
364
lib/modules/widgets/custom_extended_image_provider.dart
Normal file
364
lib/modules/widgets/custom_extended_image_provider.dart
Normal file
|
|
@ -0,0 +1,364 @@
|
|||
// ignore_for_file: non_nullable_equals_parameter, depend_on_referenced_packages, implementation_imports
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
import 'dart:ui' as ui show Codec;
|
||||
import 'package:extended_image_library/src/extended_image_provider.dart';
|
||||
import 'package:extended_image_library/src/platform.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:http_client_helper/http_client_helper.dart';
|
||||
import 'package:mangayomi/services/http/interceptor.dart';
|
||||
import 'package:path/path.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:extended_image_library/src/network/extended_network_image_provider.dart'
|
||||
as image_provider;
|
||||
|
||||
class CustomExtendedNetworkImageProvider
|
||||
extends ImageProvider<image_provider.ExtendedNetworkImageProvider>
|
||||
with ExtendedImageProvider<image_provider.ExtendedNetworkImageProvider>
|
||||
implements image_provider.ExtendedNetworkImageProvider {
|
||||
/// Creates an object that fetches the image at the given URL.
|
||||
///
|
||||
/// The arguments must not be null.
|
||||
CustomExtendedNetworkImageProvider(
|
||||
this.url, {
|
||||
this.scale = 1.0,
|
||||
this.headers,
|
||||
this.cache = true,
|
||||
this.retries = 3,
|
||||
this.timeLimit,
|
||||
this.timeRetry = const Duration(milliseconds: 100),
|
||||
this.cacheKey,
|
||||
this.printError = true,
|
||||
this.cacheRawData = false,
|
||||
this.cancelToken,
|
||||
this.imageCacheName,
|
||||
this.cacheMaxAge = const Duration(days: 30),
|
||||
});
|
||||
|
||||
/// The name of [ImageCache], you can define custom [ImageCache] to store this provider.
|
||||
@override
|
||||
final String? imageCacheName;
|
||||
|
||||
/// Whether cache raw data if you need to get raw data directly.
|
||||
/// For example, we need raw image data to edit,
|
||||
/// but [ui.Image.toByteData()] is very slow. So we cache the image
|
||||
/// data here.
|
||||
@override
|
||||
final bool cacheRawData;
|
||||
|
||||
/// The time limit to request image
|
||||
@override
|
||||
final Duration? timeLimit;
|
||||
|
||||
/// The time to retry to request
|
||||
@override
|
||||
final int retries;
|
||||
|
||||
/// The time duration to retry to request
|
||||
@override
|
||||
final Duration timeRetry;
|
||||
|
||||
/// Whether cache image to local
|
||||
@override
|
||||
final bool cache;
|
||||
|
||||
/// The URL from which the image will be fetched.
|
||||
@override
|
||||
final String url;
|
||||
|
||||
/// The scale to place in the [ImageInfo] object of the image.
|
||||
@override
|
||||
final double scale;
|
||||
|
||||
/// The HTTP headers that will be used with [HttpClient.get] to fetch image from network.
|
||||
@override
|
||||
final Map<String, String>? headers;
|
||||
|
||||
/// The token to cancel network request
|
||||
@override
|
||||
final CancellationToken? cancelToken;
|
||||
|
||||
/// Custom cache key
|
||||
@override
|
||||
final String? cacheKey;
|
||||
|
||||
/// print error
|
||||
@override
|
||||
final bool printError;
|
||||
|
||||
/// The max duration to cahce image.
|
||||
/// After this time the cache is expired and the image is reloaded.
|
||||
@override
|
||||
final Duration? cacheMaxAge;
|
||||
|
||||
@override
|
||||
ImageStreamCompleter loadImage(
|
||||
image_provider.ExtendedNetworkImageProvider key,
|
||||
ImageDecoderCallback decode,
|
||||
) {
|
||||
// Ownership of this controller is handed off to [_loadAsync]; it is that
|
||||
// method's responsibility to close the controller's stream when the image
|
||||
// has been loaded or an error is thrown.
|
||||
final StreamController<ImageChunkEvent> chunkEvents =
|
||||
StreamController<ImageChunkEvent>();
|
||||
|
||||
return MultiFrameImageStreamCompleter(
|
||||
codec: _loadAsync(
|
||||
key as CustomExtendedNetworkImageProvider,
|
||||
chunkEvents,
|
||||
decode,
|
||||
),
|
||||
scale: key.scale,
|
||||
chunkEvents: chunkEvents.stream,
|
||||
debugLabel: key.url,
|
||||
informationCollector: () {
|
||||
return <DiagnosticsNode>[
|
||||
DiagnosticsProperty<ImageProvider>('Image provider', this),
|
||||
DiagnosticsProperty<image_provider.ExtendedNetworkImageProvider>(
|
||||
'Image key', key),
|
||||
];
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<CustomExtendedNetworkImageProvider> obtainKey(
|
||||
ImageConfiguration configuration) {
|
||||
return SynchronousFuture<CustomExtendedNetworkImageProvider>(this);
|
||||
}
|
||||
|
||||
Future<ui.Codec> _loadAsync(
|
||||
CustomExtendedNetworkImageProvider key,
|
||||
StreamController<ImageChunkEvent> chunkEvents,
|
||||
ImageDecoderCallback decode,
|
||||
) async {
|
||||
assert(key == this);
|
||||
final String md5Key = cacheKey ?? keyToMd5(key.url);
|
||||
ui.Codec? result;
|
||||
if (cache) {
|
||||
try {
|
||||
final Uint8List? data = await _loadCache(
|
||||
key,
|
||||
chunkEvents,
|
||||
md5Key,
|
||||
);
|
||||
if (data != null) {
|
||||
result = await instantiateImageCodec(data, decode);
|
||||
}
|
||||
} catch (e) {
|
||||
if (kDebugMode) {
|
||||
print(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (result == null) {
|
||||
try {
|
||||
final Uint8List? data = await _loadNetwork(
|
||||
key,
|
||||
chunkEvents,
|
||||
);
|
||||
if (data != null) {
|
||||
result = await instantiateImageCodec(data, decode);
|
||||
}
|
||||
} catch (e) {
|
||||
if (kDebugMode) {
|
||||
print(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Failed to load
|
||||
if (result == null) {
|
||||
//result = await ui.instantiateImageCodec(kTransparentImage);
|
||||
return Future<ui.Codec>.error(StateError('Failed to load $url.'));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// Get the image from cache folder.
|
||||
Future<Uint8List?> _loadCache(
|
||||
CustomExtendedNetworkImageProvider key,
|
||||
StreamController<ImageChunkEvent>? chunkEvents,
|
||||
String md5Key,
|
||||
) async {
|
||||
final Directory cacheImagesDirectory = Directory(
|
||||
join((await getTemporaryDirectory()).path, cacheImageFolderName));
|
||||
Uint8List? data;
|
||||
// exist, try to find cache image file
|
||||
if (cacheImagesDirectory.existsSync()) {
|
||||
final File cacheFlie = File(join(cacheImagesDirectory.path, md5Key));
|
||||
if (cacheFlie.existsSync()) {
|
||||
if (key.cacheMaxAge != null) {
|
||||
final DateTime now = DateTime.now();
|
||||
final FileStat fs = cacheFlie.statSync();
|
||||
if (now.subtract(key.cacheMaxAge!).isAfter(fs.changed)) {
|
||||
cacheFlie.deleteSync(recursive: true);
|
||||
} else {
|
||||
data = await cacheFlie.readAsBytes();
|
||||
}
|
||||
} else {
|
||||
data = await cacheFlie.readAsBytes();
|
||||
}
|
||||
}
|
||||
}
|
||||
// create folder
|
||||
else {
|
||||
await cacheImagesDirectory.create();
|
||||
}
|
||||
// load from network
|
||||
if (data == null) {
|
||||
data = await _loadNetwork(
|
||||
key,
|
||||
chunkEvents,
|
||||
);
|
||||
if (data != null) {
|
||||
// cache image file
|
||||
await File(join(cacheImagesDirectory.path, md5Key)).writeAsBytes(data);
|
||||
}
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/// Get the image from network.
|
||||
Future<Uint8List?> _loadNetwork(
|
||||
CustomExtendedNetworkImageProvider key,
|
||||
StreamController<ImageChunkEvent>? chunkEvents,
|
||||
) async {
|
||||
try {
|
||||
final Uri resolved = Uri.base.resolve(key.url);
|
||||
final StreamedResponse? response = await _tryGetResponse(resolved);
|
||||
List<int> bytes = [];
|
||||
final int total = response!.contentLength ?? 0;
|
||||
if (response.statusCode == HttpStatus.ok) {
|
||||
int received = 0;
|
||||
response.stream.asBroadcastStream();
|
||||
await for (var chunk in response.stream) {
|
||||
bytes.addAll(chunk);
|
||||
try {
|
||||
received += chunk.length;
|
||||
if (chunkEvents != null) {}
|
||||
chunkEvents!.add(ImageChunkEvent(
|
||||
cumulativeBytesLoaded: received, expectedTotalBytes: total));
|
||||
} catch (e) {
|
||||
if (kDebugMode) {
|
||||
print(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (bytes.isEmpty) {
|
||||
return Future<Uint8List>.error(
|
||||
StateError('NetworkImage is an empty file: $resolved'));
|
||||
}
|
||||
|
||||
return Uint8List.fromList(bytes);
|
||||
} on OperationCanceledError catch (_) {
|
||||
if (kDebugMode) {
|
||||
print('User cancel request $url.');
|
||||
}
|
||||
return Future<Uint8List>.error(StateError('User cancel request $url.'));
|
||||
} catch (e) {
|
||||
if (kDebugMode) {
|
||||
print(e);
|
||||
}
|
||||
} finally {
|
||||
await chunkEvents?.close();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
Future<StreamedResponse> _getResponse(Uri resolved) async {
|
||||
var request = Request('GET', resolved);
|
||||
request.headers.addAll(headers ?? {});
|
||||
|
||||
StreamedResponse response = await MInterceptor.init().send(request);
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
// Http get with cancel, delay try again
|
||||
Future<StreamedResponse?> _tryGetResponse(
|
||||
Uri resolved,
|
||||
) async {
|
||||
cancelToken?.throwIfCancellationRequested();
|
||||
return await RetryHelper.tryRun<StreamedResponse>(
|
||||
() {
|
||||
return CancellationTokenSource.register(
|
||||
cancelToken,
|
||||
_getResponse(resolved),
|
||||
);
|
||||
},
|
||||
cancelToken: cancelToken,
|
||||
timeRetry: timeRetry,
|
||||
retries: retries,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(dynamic other) {
|
||||
if (other.runtimeType != runtimeType) {
|
||||
return false;
|
||||
}
|
||||
return other is CustomExtendedNetworkImageProvider &&
|
||||
url == other.url &&
|
||||
scale == other.scale &&
|
||||
cacheRawData == other.cacheRawData &&
|
||||
timeLimit == other.timeLimit &&
|
||||
cancelToken == other.cancelToken &&
|
||||
timeRetry == other.timeRetry &&
|
||||
cache == other.cache &&
|
||||
cacheKey == other.cacheKey &&
|
||||
//headers == other.headers &&
|
||||
retries == other.retries &&
|
||||
imageCacheName == other.imageCacheName &&
|
||||
cacheMaxAge == other.cacheMaxAge;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(
|
||||
url,
|
||||
scale,
|
||||
cacheRawData,
|
||||
timeLimit,
|
||||
cancelToken,
|
||||
timeRetry,
|
||||
cache,
|
||||
cacheKey,
|
||||
//headers,
|
||||
retries,
|
||||
imageCacheName,
|
||||
cacheMaxAge,
|
||||
);
|
||||
|
||||
@override
|
||||
String toString() => '$runtimeType("$url", scale: $scale)';
|
||||
|
||||
@override
|
||||
|
||||
/// Get network image data from cached
|
||||
Future<Uint8List?> getNetworkImageData({
|
||||
StreamController<ImageChunkEvent>? chunkEvents,
|
||||
}) async {
|
||||
final String uId = cacheKey ?? keyToMd5(url);
|
||||
|
||||
if (cache) {
|
||||
return await _loadCache(
|
||||
this,
|
||||
chunkEvents,
|
||||
uId,
|
||||
);
|
||||
}
|
||||
|
||||
return await _loadNetwork(
|
||||
this,
|
||||
chunkEvents,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
import 'dart:typed_data';
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
|
@ -10,6 +9,7 @@ import 'package:mangayomi/models/manga.dart';
|
|||
import 'package:mangayomi/models/settings.dart';
|
||||
import 'package:mangayomi/models/source.dart';
|
||||
import 'package:mangayomi/modules/manga/detail/manga_detail_main.dart';
|
||||
import 'package:mangayomi/modules/widgets/custom_extended_image_provider.dart';
|
||||
import 'package:mangayomi/router/router.dart';
|
||||
import 'package:mangayomi/utils/extensions/build_context_extensions.dart';
|
||||
import 'package:mangayomi/utils/constant.dart';
|
||||
|
|
@ -52,7 +52,7 @@ class MangaImageCardWidget extends ConsumerWidget {
|
|||
? MemoryImage(
|
||||
snapshot.data!.first.customCoverImage as Uint8List)
|
||||
as ImageProvider
|
||||
: CachedNetworkImageProvider(
|
||||
: CustomExtendedNetworkImageProvider(
|
||||
toImgUrl(hasData
|
||||
? snapshot.data!.first.customCoverFromTracker ??
|
||||
snapshot.data!.first.imageUrl ??
|
||||
|
|
@ -60,7 +60,8 @@ class MangaImageCardWidget extends ConsumerWidget {
|
|||
: getMangaDetail!.imageUrl!),
|
||||
headers: ref.watch(headersProvider(
|
||||
source: source.name!, lang: source.lang!)),
|
||||
),
|
||||
cache: true,
|
||||
cacheMaxAge: const Duration(days: 7)),
|
||||
onTap: () {
|
||||
pushToMangaReaderDetail(
|
||||
context: context,
|
||||
|
|
@ -125,7 +126,7 @@ class MangaImageCardListTileWidget extends ConsumerWidget {
|
|||
final image = hasData && snapshot.data!.first.customCoverImage != null
|
||||
? MemoryImage(snapshot.data!.first.customCoverImage as Uint8List)
|
||||
as ImageProvider
|
||||
: CachedNetworkImageProvider(
|
||||
: CustomExtendedNetworkImageProvider(
|
||||
toImgUrl(hasData
|
||||
? snapshot.data!.first.customCoverFromTracker ??
|
||||
snapshot.data!.first.imageUrl ??
|
||||
|
|
|
|||
|
|
@ -1,24 +0,0 @@
|
|||
import 'package:mangayomi/messages/boa_js.pb.dart';
|
||||
import 'dart:async';
|
||||
|
||||
int nextId = 0;
|
||||
|
||||
Future<String> evalJs(String script) async {
|
||||
final currentId = nextId;
|
||||
nextId++;
|
||||
final completer = Completer<String>();
|
||||
BoaInput(
|
||||
interactionId: currentId,
|
||||
codeScript: script,
|
||||
).sendSignalToRust(null);
|
||||
final stream = BoaOutput.rustSignalStream;
|
||||
final subscription = stream.listen((rustSignal) {
|
||||
if (rustSignal.message.interactionId == currentId) {
|
||||
completer.complete(rustSignal.message.response);
|
||||
}
|
||||
});
|
||||
final response = await completer.future;
|
||||
subscription.cancel();
|
||||
|
||||
return response;
|
||||
}
|
||||
|
|
@ -1,4 +1,6 @@
|
|||
import 'package:cupertino_http/cupertino_http.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:google_api_availability/google_api_availability.dart';
|
||||
import 'package:http_interceptor/http_interceptor.dart';
|
||||
import 'package:mangayomi/eval/dart/model/m_bridge.dart';
|
||||
import 'dart:async';
|
||||
|
|
@ -8,16 +10,39 @@ import 'package:mangayomi/main.dart';
|
|||
import 'package:flutter_inappwebview/flutter_inappwebview.dart'
|
||||
as flutter_inappwebview;
|
||||
import 'package:mangayomi/models/settings.dart';
|
||||
import 'package:cronet_http/cronet_http.dart';
|
||||
import 'package:http/io_client.dart';
|
||||
|
||||
class MInterceptor {
|
||||
static final flutter_inappwebview.CookieManager _cookieManager =
|
||||
flutter_inappwebview.CookieManager.instance();
|
||||
|
||||
MInterceptor();
|
||||
static Client httpClient() {
|
||||
if (Platform.isAndroid) {
|
||||
if (playStoreAvailability == GooglePlayServicesAvailability.unknown) {
|
||||
return IOClient(HttpClient());
|
||||
}
|
||||
final engine = CronetEngine.build(
|
||||
enablePublicKeyPinningBypassForLocalTrustAnchors: true,
|
||||
enableHttp2: true,
|
||||
enableBrotli: true,
|
||||
cacheMode: CacheMode.memory,
|
||||
cacheMaxSize: 5 * 1024 * 1024);
|
||||
return CronetClient.fromCronetEngine(engine);
|
||||
}
|
||||
if (Platform.isIOS || Platform.isMacOS) {
|
||||
final config = URLSessionConfiguration.ephemeralSessionConfiguration()
|
||||
..cache = URLCache.withCapacity(memoryCapacity: 5 * 1024 * 1024);
|
||||
return CupertinoClient.fromSessionConfiguration(config);
|
||||
}
|
||||
return IOClient(HttpClient());
|
||||
}
|
||||
|
||||
static InterceptedClient init(
|
||||
{MSource? source, Map<String, dynamic>? reqcopyWith}) {
|
||||
return InterceptedClient.build(
|
||||
client: httpClient(),
|
||||
interceptors: [MCookieManager(reqcopyWith), LoggerInterceptor()]);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import 'package:riverpod_annotation/riverpod_annotation.dart';
|
|||
part 'torrent_server.g.dart';
|
||||
|
||||
class MTorrentServer {
|
||||
final http = MInterceptor.init();
|
||||
final http = Client();
|
||||
Future<bool> removeTorrent(String? inforHash) async {
|
||||
if (inforHash == null || inforHash.isEmpty) return false;
|
||||
try {
|
||||
|
|
@ -44,7 +44,8 @@ class MTorrentServer {
|
|||
|
||||
Future<String> getInfohash(String url) async {
|
||||
try {
|
||||
final torrentByte = (await http.get(Uri.parse(url))).bodyBytes;
|
||||
final torrentByte =
|
||||
(await MInterceptor.init().get(Uri.parse(url))).bodyBytes;
|
||||
var request =
|
||||
MultipartRequest('POST', Uri.parse('$_baseUrl/torrent/add'));
|
||||
|
||||
|
|
|
|||
|
|
@ -1,33 +1,29 @@
|
|||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:extended_image/extended_image.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:mangayomi/modules/widgets/custom_extended_image_provider.dart';
|
||||
|
||||
Widget cachedNetworkImage(
|
||||
{required Map<String, String>? headers,
|
||||
{Map<String, String>? headers,
|
||||
required String imageUrl,
|
||||
required double? width,
|
||||
required double? height,
|
||||
required BoxFit? fit,
|
||||
AlignmentGeometry? alignment}) {
|
||||
if (kIsWeb) {
|
||||
return Image.network(
|
||||
imageUrl,
|
||||
width: width,
|
||||
height: height,
|
||||
fit: fit,
|
||||
alignment: alignment ?? Alignment.center,
|
||||
);
|
||||
} else {
|
||||
return CachedNetworkImage(
|
||||
httpHeaders: headers ?? {},
|
||||
imageUrl: imageUrl,
|
||||
fit: fit,
|
||||
width: width,
|
||||
height: height,
|
||||
errorWidget: (context, url, error) => const Icon(
|
||||
Icons.error,
|
||||
size: 50,
|
||||
),
|
||||
);
|
||||
}
|
||||
AlignmentGeometry? alignment,
|
||||
Widget errorWidget = const Icon(Icons.error, size: 50)}) {
|
||||
return ExtendedImage(
|
||||
image: CustomExtendedNetworkImageProvider(imageUrl, headers: headers),
|
||||
width: width,
|
||||
height: height,
|
||||
fit: fit,
|
||||
filterQuality: FilterQuality.medium,
|
||||
enableMemoryCache: true,
|
||||
mode: ExtendedImageMode.gesture,
|
||||
handleLoadingProgress: true,
|
||||
loadStateChanged: (state) {
|
||||
if (state.extendedImageLoadState == LoadState.failed) {
|
||||
return errorWidget;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ list(APPEND FLUTTER_PLUGIN_LIST
|
|||
)
|
||||
|
||||
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
||||
jni
|
||||
media_kit_native_event_loop
|
||||
rinf
|
||||
)
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ import path_provider_foundation
|
|||
import screen_brightness_macos
|
||||
import screen_retriever
|
||||
import share_plus
|
||||
import sqflite
|
||||
import url_launcher_macos
|
||||
import wakelock_plus
|
||||
import window_manager
|
||||
|
|
@ -34,7 +33,6 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
|||
ScreenBrightnessMacosPlugin.register(with: registry.registrar(forPlugin: "ScreenBrightnessMacosPlugin"))
|
||||
ScreenRetrieverPlugin.register(with: registry.registrar(forPlugin: "ScreenRetrieverPlugin"))
|
||||
SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin"))
|
||||
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
|
||||
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
|
||||
WakelockPlusMacosPlugin.register(with: registry.registrar(forPlugin: "WakelockPlusMacosPlugin"))
|
||||
WindowManagerPlugin.register(with: registry.registrar(forPlugin: "WindowManagerPlugin"))
|
||||
|
|
|
|||
|
|
@ -1,14 +0,0 @@
|
|||
syntax = "proto3";
|
||||
package boa_js;
|
||||
|
||||
// [RINF:DART-SIGNAL]
|
||||
message BoaInput {
|
||||
int32 interaction_id = 1;
|
||||
string code_script = 2;
|
||||
}
|
||||
|
||||
// [RINF:RUST-SIGNAL]
|
||||
message BoaOutput {
|
||||
int32 interaction_id = 1;
|
||||
string response = 2;
|
||||
}
|
||||
|
|
@ -12,10 +12,9 @@ edition = "2021"
|
|||
crate-type = ["lib", "cdylib", "staticlib"]
|
||||
|
||||
[dependencies]
|
||||
rinf = "6.4.0"
|
||||
rinf = "6.6.3"
|
||||
allo-isolate = "0.1.24"
|
||||
wasm-bindgen = "0.2.90"
|
||||
prost = "0.12.3"
|
||||
tokio_with_wasm = "0.4.0"
|
||||
image = "0.24.8"
|
||||
boa_engine = "0.17.3"
|
||||
tokio_with_wasm = "0.4.3"
|
||||
image = "0.25.0"
|
||||
|
|
|
|||
|
|
@ -1,20 +0,0 @@
|
|||
use crate::messages;
|
||||
use boa_engine::{Context, Source};
|
||||
|
||||
pub async fn eval_js() {
|
||||
use messages::boa_js::*;
|
||||
|
||||
let mut receiver = BoaInput::get_dart_signal_receiver();
|
||||
while let Some(dart_signal) = receiver.recv().await {
|
||||
let mut context = Context::default();
|
||||
let code_script = dart_signal.message.code_script;
|
||||
BoaOutput {
|
||||
interaction_id: dart_signal.message.interaction_id,
|
||||
response: match context.eval(Source::from_bytes(code_script.as_bytes())) {
|
||||
Ok(res) => res.to_string(&mut context).unwrap().to_std_string_escaped(),
|
||||
Err(_e) => "error".to_string(),
|
||||
},
|
||||
}
|
||||
.send_signal_to_dart(None);
|
||||
}
|
||||
}
|
||||
|
|
@ -20,7 +20,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|||
SOFTWARE.*/
|
||||
|
||||
use crate::messages;
|
||||
use image::{DynamicImage, GenericImageView, ImageOutputFormat, ImageResult, Rgba};
|
||||
use image::{DynamicImage, GenericImageView, ImageResult, Rgba};
|
||||
use std::io::Cursor;
|
||||
|
||||
pub struct Point {
|
||||
|
|
@ -145,7 +145,7 @@ pub async fn start_croping() {
|
|||
let image = dart_signal.blob.unwrap();
|
||||
let res = crop_image(image);
|
||||
let mut image_data: Vec<u8> = Vec::new();
|
||||
res.write_to(&mut Cursor::new(&mut image_data), ImageOutputFormat::Png)
|
||||
res.write_to(&mut Cursor::new(&mut image_data), image::ImageFormat::Png)
|
||||
.unwrap();
|
||||
CropBordersOutput {
|
||||
interaction_id: dart_signal.message.interaction_id,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
use tokio_with_wasm::tokio;
|
||||
|
||||
mod boa_js;
|
||||
mod imagecrop;
|
||||
mod messages;
|
||||
|
||||
|
|
@ -11,6 +10,5 @@ rinf::write_interface!();
|
|||
async fn main() {
|
||||
// Repeat `crate::spawn` anywhere in your code
|
||||
// if more concurrent tasks are needed.
|
||||
tokio::spawn(boa_js::eval_js());
|
||||
tokio::spawn(imagecrop::start_croping());
|
||||
}
|
||||
|
|
|
|||
106
pubspec.lock
106
pubspec.lock
|
|
@ -146,30 +146,6 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "8.9.0"
|
||||
cached_network_image:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: cached_network_image
|
||||
sha256: "28ea9690a8207179c319965c13cd8df184d5ee721ae2ce60f398ced1219cea1f"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.3.1"
|
||||
cached_network_image_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: cached_network_image_platform_interface
|
||||
sha256: "9e90e78ae72caa874a323d78fa6301b3fb8fa7ea76a8f96dc5b5bf79f283bf2f"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.0.0"
|
||||
cached_network_image_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: cached_network_image_web
|
||||
sha256: "42a835caa27c220d1294311ac409a43361088625a4f23c820b006dd9bffb3316"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.1"
|
||||
characters:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -234,6 +210,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.1"
|
||||
cronet_http:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: cronet_http
|
||||
sha256: a38ffbb49797ae1e0f774fc884d128a7023986b14a3165e1e39841f9f7e22137
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.1"
|
||||
cross_file:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -258,6 +242,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.0"
|
||||
cupertino_http:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: cupertino_http
|
||||
sha256: "0e3ed481280ad41d42d4881d4b6f89c083c17aa010205c9381ecb4c7ea7bdf1f"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.3.0"
|
||||
cupertino_icons:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
@ -462,14 +454,6 @@ packages:
|
|||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
flutter_cache_manager:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_cache_manager
|
||||
sha256: "8207f27539deb83732fdda03e259349046a39a4c767269285f449ade355d54ba"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.3.1"
|
||||
flutter_inappwebview:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
@ -599,6 +583,30 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "12.1.3"
|
||||
google_api_availability:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: google_api_availability
|
||||
sha256: "3e9548cfd991d983d11425a2436d5bd957d048c279cc9e145ffe3f36fd847385"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.0.0"
|
||||
google_api_availability_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: google_api_availability_android
|
||||
sha256: d95429ae78083585c312de2c6578085e7d53d100a94656d691bce0bb0ce435be
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
google_api_availability_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: google_api_availability_platform_interface
|
||||
sha256: "65b7da62fe5b582bb3d508628ad827d36d890710ea274766a992a56fa5420da6"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
google_fonts:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
@ -632,7 +640,7 @@ packages:
|
|||
source: hosted
|
||||
version: "0.15.4"
|
||||
http:
|
||||
dependency: "direct overridden"
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: http
|
||||
sha256: a2bbf9d017fcced29139daa8ed2bba4ece450ab222871df93ca9eec6f80c34ba
|
||||
|
|
@ -735,6 +743,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.0+1"
|
||||
jni:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: jni
|
||||
sha256: "0d88790bdf7e298aa65a9094c62b58ea231169a2deb84f23defc7d7955885b43"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.7.2"
|
||||
js:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -936,14 +952,6 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.2"
|
||||
octo_image:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: octo_image
|
||||
sha256: "45b40f99622f11901238e18d48f5f12ea36426d8eced9f4cbf58479c7aa2430d"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
package_config:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -1349,22 +1357,6 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "7.0.0"
|
||||
sqflite:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: sqflite
|
||||
sha256: a9016f495c927cb90557c909ff26a6d92d9bd54fc42ba92e19d4e79d61e798c6
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.2"
|
||||
sqflite_common:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: sqflite_common
|
||||
sha256: "28d8c66baee4968519fb8bd6cdbedad982d6e53359091f0b74544a9f32ec72d5"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.5.3"
|
||||
stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ dependencies:
|
|||
sdk: flutter
|
||||
go_router: ^12.1.3
|
||||
flutter_riverpod: ^2.4.10
|
||||
cached_network_image: ^3.3.1
|
||||
riverpod_annotation: ^2.3.3
|
||||
html: ^0.15.4
|
||||
font_awesome_flutter: ^10.6.0
|
||||
|
|
@ -75,6 +74,10 @@ dependencies:
|
|||
git:
|
||||
url: https://github.com/kodjodevf/flutter_qjs.git
|
||||
ref: main
|
||||
cronet_http: ^1.1.1
|
||||
cupertino_http: ^1.3.0
|
||||
http: ^1.2.0
|
||||
google_api_availability: ^5.0.0
|
||||
|
||||
|
||||
dependency_overrides:
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ list(APPEND FLUTTER_PLUGIN_LIST
|
|||
)
|
||||
|
||||
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
||||
jni
|
||||
media_kit_native_event_loop
|
||||
rinf
|
||||
)
|
||||
|
|
|
|||
Loading…
Reference in a new issue