mirror of
https://github.com/kodjodevf/mangayomi.git
synced 2026-03-11 17:25:32 +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.dart';
|
||||||
import 'package:dart_eval/dart_eval_bridge.dart';
|
import 'package:dart_eval/dart_eval_bridge.dart';
|
||||||
import 'package:dart_eval/stdlib/core.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/document.dart';
|
||||||
import 'package:mangayomi/eval/dart/bridge/filter.dart';
|
import 'package:mangayomi/eval/dart/bridge/filter.dart';
|
||||||
import 'package:mangayomi/eval/dart/bridge/m_manga.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/eval/dart/model/m_provider.dart';
|
||||||
import 'package:mangayomi/models/video.dart';
|
import 'package:mangayomi/models/video.dart';
|
||||||
import 'package:mangayomi/modules/browse/extension/providers/extension_preferences_providers.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> {
|
class $MProvider extends MProvider with $Bridge<MProvider> {
|
||||||
static $MProvider $construct(
|
static $MProvider $construct(
|
||||||
|
|
@ -748,8 +748,10 @@ class $MProvider extends MProvider with $Bridge<MProvider> {
|
||||||
$Value? $bridgeGet(String identifier) {
|
$Value? $bridgeGet(String identifier) {
|
||||||
return switch (identifier) {
|
return switch (identifier) {
|
||||||
'evalJs' => $Function((_, __, List<$Value?> args) {
|
'evalJs' => $Function((_, __, List<$Value?> args) {
|
||||||
return $Future
|
final runtime = getJavascriptRuntime();
|
||||||
.wrap(evalJs(args[0]!.$reified).then((value) => $String(value)));
|
return $Future.wrap(runtime
|
||||||
|
.evaluateAsync(args[0]!.$reified)
|
||||||
|
.then((value) => $String(value.stringResult)));
|
||||||
}),
|
}),
|
||||||
'getUrlWithoutDomain' => $Function((_, __, List<$Value?> args) {
|
'getUrlWithoutDomain' => $Function((_, __, List<$Value?> args) {
|
||||||
final uri = Uri.parse(args[0]!.$value.replaceAll(' ', '%20'));
|
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:flex_color_scheme/flex_color_scheme.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.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:google_fonts/google_fonts.dart';
|
||||||
import 'package:intl/date_symbol_data_local.dart';
|
import 'package:intl/date_symbol_data_local.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
|
|
@ -25,6 +27,9 @@ import 'package:window_manager/window_manager.dart';
|
||||||
// Global instance of the Isar database.
|
// Global instance of the Isar database.
|
||||||
late Isar isar;
|
late Isar isar;
|
||||||
|
|
||||||
|
GooglePlayServicesAvailability playStoreAvailability =
|
||||||
|
GooglePlayServicesAvailability.unknown;
|
||||||
|
|
||||||
/// Overrides the default HTTP client to allow all certificates
|
/// Overrides the default HTTP client to allow all certificates
|
||||||
class MyHttpoverrides extends HttpOverrides {
|
class MyHttpoverrides extends HttpOverrides {
|
||||||
@override
|
@override
|
||||||
|
|
@ -57,6 +62,14 @@ void main(List<String> args) async {
|
||||||
isar = await StorageProvider().initDB(null, inspector: kDebugMode);
|
isar = await StorageProvider().initDB(null, inspector: kDebugMode);
|
||||||
await StorageProvider().requestPermission();
|
await StorageProvider().requestPermission();
|
||||||
GoogleFonts.aBeeZee();
|
GoogleFonts.aBeeZee();
|
||||||
|
if (Platform.isAndroid) {
|
||||||
|
try {
|
||||||
|
playStoreAvailability = await GoogleApiAvailability.instance
|
||||||
|
.checkGooglePlayServicesAvailability();
|
||||||
|
} on PlatformException {
|
||||||
|
playStoreAvailability = GooglePlayServicesAvailability.unknown;
|
||||||
|
}
|
||||||
|
}
|
||||||
// Start the app.
|
// Start the app.
|
||||||
runApp(const ProviderScope(child: MyApp()));
|
runApp(const ProviderScope(child: MyApp()));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -107,7 +107,8 @@ class Source {
|
||||||
version = json['version'];
|
version = json['version'];
|
||||||
versionLast = json['versionLast'];
|
versionLast = json['versionLast'];
|
||||||
additionalParams = json['additionalParams'] ?? "";
|
additionalParams = json['additionalParams'] ?? "";
|
||||||
sourceCodeLanguage = SourceCodeLanguage.values[json['sourceCodeLanguage']];
|
sourceCodeLanguage =
|
||||||
|
SourceCodeLanguage.values[json['sourceCodeLanguage'] ?? 0];
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
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/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.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/eval/dart/model/source_preference.dart';
|
||||||
import 'package:mangayomi/main.dart';
|
import 'package:mangayomi/main.dart';
|
||||||
import 'package:mangayomi/models/source.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/modules/browse/extension/widgets/source_preference_widget.dart';
|
||||||
import 'package:mangayomi/providers/l10n_providers.dart';
|
import 'package:mangayomi/providers/l10n_providers.dart';
|
||||||
import 'package:mangayomi/services/get_source_preference.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/extensions/build_context_extensions.dart';
|
||||||
import 'package:mangayomi/utils/language.dart';
|
import 'package:mangayomi/utils/language.dart';
|
||||||
|
|
||||||
|
|
@ -22,6 +24,7 @@ class ExtensionDetail extends ConsumerStatefulWidget {
|
||||||
class _ExtensionDetailState extends ConsumerState<ExtensionDetail> {
|
class _ExtensionDetailState extends ConsumerState<ExtensionDetail> {
|
||||||
late Source source = widget.source;
|
late Source source = widget.source;
|
||||||
List<SourcePreference> sourcePreference = [];
|
List<SourcePreference> sourcePreference = [];
|
||||||
|
bool _isLoading = true;
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
getSourcePreferenceAsync(source: source).then((value) {
|
getSourcePreferenceAsync(source: source).then((value) {
|
||||||
|
|
@ -30,10 +33,11 @@ class _ExtensionDetailState extends ConsumerState<ExtensionDetail> {
|
||||||
sourcePreference = value
|
sourcePreference = value
|
||||||
.map((e) => getSourcePreferenceEntry(e.key!, source.id!))
|
.map((e) => getSourcePreferenceEntry(e.key!, source.id!))
|
||||||
.toList();
|
.toList();
|
||||||
|
_isLoading = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
print(source.id);
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -56,20 +60,19 @@ class _ExtensionDetailState extends ConsumerState<ExtensionDetail> {
|
||||||
borderRadius: BorderRadius.circular(10)),
|
borderRadius: BorderRadius.circular(10)),
|
||||||
child: widget.source.iconUrl!.isEmpty
|
child: widget.source.iconUrl!.isEmpty
|
||||||
? const Icon(Icons.source_outlined, size: 140)
|
? const Icon(Icons.source_outlined, size: 140)
|
||||||
: CachedNetworkImage(
|
: cachedNetworkImage(
|
||||||
imageUrl: widget.source.iconUrl!,
|
imageUrl: widget.source.iconUrl!,
|
||||||
fit: BoxFit.contain,
|
fit: BoxFit.contain,
|
||||||
width: 140,
|
width: 140,
|
||||||
height: 140,
|
height: 140,
|
||||||
errorWidget: (context, url, error) {
|
errorWidget: const SizedBox(
|
||||||
return const SizedBox(
|
width: 140,
|
||||||
width: 140,
|
height: 140,
|
||||||
height: 140,
|
child: Center(
|
||||||
child: Center(
|
child: Icon(Icons.source_outlined, size: 140),
|
||||||
child: Icon(Icons.source_outlined, size: 140),
|
),
|
||||||
),
|
),
|
||||||
);
|
headers: {},
|
||||||
},
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -176,11 +179,34 @@ class _ExtensionDetailState extends ConsumerState<ExtensionDetail> {
|
||||||
),
|
),
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () {
|
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
|
isar.sources.putSync(widget.source
|
||||||
..sourceCode = ""
|
..sourceCode = ""
|
||||||
..isAdded = false
|
..isAdded = false
|
||||||
..isPinned = false));
|
..isPinned = false);
|
||||||
|
}
|
||||||
|
isar.sourcePreferences
|
||||||
|
.deleteAllSync(sourcePrefsIds);
|
||||||
|
isar.sourcePreferenceStringValues
|
||||||
|
.deleteAllSync(
|
||||||
|
sourcePrefsStringIds);
|
||||||
|
});
|
||||||
|
|
||||||
Navigator.pop(ctx);
|
Navigator.pop(ctx);
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
},
|
},
|
||||||
|
|
@ -198,8 +224,9 @@ class _ExtensionDetailState extends ConsumerState<ExtensionDetail> {
|
||||||
)),
|
)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SourcePreferenceWidget(
|
if (!_isLoading)
|
||||||
sourcePreference: sourcePreference, source: source)
|
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/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:go_router/go_router.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_anime_sources.dart';
|
||||||
import 'package:mangayomi/modules/browse/extension/providers/fetch_manga_sources.dart';
|
import 'package:mangayomi/modules/browse/extension/providers/fetch_manga_sources.dart';
|
||||||
import 'package:mangayomi/providers/l10n_providers.dart';
|
import 'package:mangayomi/providers/l10n_providers.dart';
|
||||||
|
import 'package:mangayomi/utils/cached_network.dart';
|
||||||
import 'package:mangayomi/utils/language.dart';
|
import 'package:mangayomi/utils/language.dart';
|
||||||
|
|
||||||
class ExtensionListTileWidget extends ConsumerStatefulWidget {
|
class ExtensionListTileWidget extends ConsumerStatefulWidget {
|
||||||
|
|
@ -68,20 +68,19 @@ class _ExtensionListTileWidgetState
|
||||||
borderRadius: BorderRadius.circular(5)),
|
borderRadius: BorderRadius.circular(5)),
|
||||||
child: widget.source.iconUrl!.isEmpty
|
child: widget.source.iconUrl!.isEmpty
|
||||||
? const Icon(Icons.source_outlined)
|
? const Icon(Icons.source_outlined)
|
||||||
: CachedNetworkImage(
|
: cachedNetworkImage(
|
||||||
imageUrl: widget.source.iconUrl!,
|
imageUrl: widget.source.iconUrl!,
|
||||||
fit: BoxFit.contain,
|
fit: BoxFit.contain,
|
||||||
width: 37,
|
width: 37,
|
||||||
height: 37,
|
height: 37,
|
||||||
errorWidget: (context, url, error) {
|
errorWidget: const SizedBox(
|
||||||
return const SizedBox(
|
width: 37,
|
||||||
width: 37,
|
height: 37,
|
||||||
height: 37,
|
child: Center(
|
||||||
child: Center(
|
child: Icon(Icons.source_outlined),
|
||||||
child: Icon(Icons.source_outlined),
|
),
|
||||||
),
|
),
|
||||||
);
|
headers: {},
|
||||||
},
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
title: Text(widget.source.name!),
|
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/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:grouped_list/grouped_list.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/models/source.dart';
|
||||||
import 'package:mangayomi/modules/more/settings/browse/providers/browse_state_provider.dart';
|
import 'package:mangayomi/modules/more/settings/browse/providers/browse_state_provider.dart';
|
||||||
import 'package:mangayomi/providers/l10n_providers.dart';
|
import 'package:mangayomi/providers/l10n_providers.dart';
|
||||||
|
import 'package:mangayomi/utils/cached_network.dart';
|
||||||
import 'package:mangayomi/utils/language.dart';
|
import 'package:mangayomi/utils/language.dart';
|
||||||
|
|
||||||
class SourcesFilterScreen extends ConsumerWidget {
|
class SourcesFilterScreen extends ConsumerWidget {
|
||||||
|
|
@ -86,20 +86,18 @@ class SourcesFilterScreen extends ConsumerWidget {
|
||||||
borderRadius: BorderRadius.circular(5)),
|
borderRadius: BorderRadius.circular(5)),
|
||||||
child: element.iconUrl!.isEmpty
|
child: element.iconUrl!.isEmpty
|
||||||
? const Icon(Icons.source_outlined)
|
? const Icon(Icons.source_outlined)
|
||||||
: CachedNetworkImage(
|
: cachedNetworkImage(
|
||||||
imageUrl: element.iconUrl!,
|
imageUrl: element.iconUrl!,
|
||||||
fit: BoxFit.contain,
|
fit: BoxFit.contain,
|
||||||
width: 37,
|
width: 37,
|
||||||
height: 37,
|
height: 37,
|
||||||
errorWidget: (context, url, error) {
|
errorWidget: const SizedBox(
|
||||||
return const SizedBox(
|
width: 37,
|
||||||
width: 37,
|
height: 37,
|
||||||
height: 37,
|
child: Center(
|
||||||
child: Center(
|
child: Icon(Icons.source_outlined),
|
||||||
child: Icon(Icons.source_outlined),
|
),
|
||||||
),
|
),
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
onChanged: (bool? value) {
|
onChanged: (bool? value) {
|
||||||
|
|
|
||||||
|
|
@ -6,9 +6,9 @@ import 'package:mangayomi/main.dart';
|
||||||
import 'package:mangayomi/models/source.dart';
|
import 'package:mangayomi/models/source.dart';
|
||||||
import 'package:mangayomi/providers/l10n_providers.dart';
|
import 'package:mangayomi/providers/l10n_providers.dart';
|
||||||
import 'package:mangayomi/sources/source_test.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/extensions/build_context_extensions.dart';
|
||||||
import 'package:mangayomi/utils/language.dart';
|
import 'package:mangayomi/utils/language.dart';
|
||||||
import 'package:cached_network_image/cached_network_image.dart';
|
|
||||||
|
|
||||||
class SourceListTile extends StatelessWidget {
|
class SourceListTile extends StatelessWidget {
|
||||||
final bool isManga;
|
final bool isManga;
|
||||||
|
|
@ -46,20 +46,18 @@ class SourceListTile extends StatelessWidget {
|
||||||
borderRadius: BorderRadius.circular(5)),
|
borderRadius: BorderRadius.circular(5)),
|
||||||
child: source.iconUrl!.isEmpty
|
child: source.iconUrl!.isEmpty
|
||||||
? const Icon(Icons.source_outlined)
|
? const Icon(Icons.source_outlined)
|
||||||
: CachedNetworkImage(
|
: cachedNetworkImage(
|
||||||
imageUrl: source.iconUrl!,
|
imageUrl: source.iconUrl!,
|
||||||
fit: BoxFit.contain,
|
fit: BoxFit.contain,
|
||||||
width: 37,
|
width: 37,
|
||||||
height: 37,
|
height: 37,
|
||||||
errorWidget: (context, url, error) {
|
errorWidget: const SizedBox(
|
||||||
return const SizedBox(
|
width: 37,
|
||||||
width: 37,
|
height: 37,
|
||||||
height: 37,
|
child: Center(
|
||||||
child: Center(
|
child: Icon(Icons.source_outlined),
|
||||||
child: Icon(Icons.source_outlined),
|
),
|
||||||
),
|
),
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
subtitle: Row(
|
subtitle: Row(
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
import 'package:cached_network_image/cached_network_image.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:isar/isar.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/library/widgets/measure_widget_sync.dart';
|
||||||
import 'package:mangayomi/modules/manga/reader/providers/push_router.dart';
|
import 'package:mangayomi/modules/manga/reader/providers/push_router.dart';
|
||||||
import 'package:mangayomi/models/manga.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/extensions/build_context_extensions.dart';
|
||||||
import 'package:mangayomi/utils/constant.dart';
|
import 'package:mangayomi/utils/constant.dart';
|
||||||
import 'package:mangayomi/utils/headers.dart';
|
import 'package:mangayomi/utils/headers.dart';
|
||||||
|
|
@ -103,7 +103,7 @@ class _LibraryGridViewWidgetState extends State<LibraryGridViewWidget> {
|
||||||
image: entry.customCoverImage != null
|
image: entry.customCoverImage != null
|
||||||
? MemoryImage(entry.customCoverImage as Uint8List)
|
? MemoryImage(entry.customCoverImage as Uint8List)
|
||||||
as ImageProvider
|
as ImageProvider
|
||||||
: CachedNetworkImageProvider(
|
: CustomExtendedNetworkImageProvider(
|
||||||
toImgUrl(entry.customCoverFromTracker ??
|
toImgUrl(entry.customCoverFromTracker ??
|
||||||
entry.imageUrl!),
|
entry.imageUrl!),
|
||||||
headers: entry.isLocalArchive!
|
headers: entry.isLocalArchive!
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
import 'package:cached_network_image/cached_network_image.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:isar/isar.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/library/providers/library_state_provider.dart';
|
||||||
import 'package:mangayomi/modules/manga/reader/providers/push_router.dart';
|
import 'package:mangayomi/modules/manga/reader/providers/push_router.dart';
|
||||||
import 'package:mangayomi/models/manga.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/extensions/build_context_extensions.dart';
|
||||||
import 'package:mangayomi/utils/constant.dart';
|
import 'package:mangayomi/utils/constant.dart';
|
||||||
import 'package:mangayomi/utils/headers.dart';
|
import 'package:mangayomi/utils/headers.dart';
|
||||||
|
|
@ -98,7 +98,7 @@ class LibraryListViewWidget extends StatelessWidget {
|
||||||
image: entry.customCoverImage != null
|
image: entry.customCoverImage != null
|
||||||
? MemoryImage(entry.customCoverImage
|
? MemoryImage(entry.customCoverImage
|
||||||
as Uint8List) as ImageProvider
|
as Uint8List) as ImageProvider
|
||||||
: CachedNetworkImageProvider(
|
: CustomExtendedNetworkImageProvider(
|
||||||
toImgUrl(
|
toImgUrl(
|
||||||
entry.customCoverFromTracker ??
|
entry.customCoverFromTracker ??
|
||||||
entry.imageUrl!),
|
entry.imageUrl!),
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
import 'package:cached_network_image/cached_network_image.dart';
|
|
||||||
import 'package:draggable_menu/draggable_menu.dart';
|
import 'package:draggable_menu/draggable_menu.dart';
|
||||||
import 'package:file_picker/file_picker.dart';
|
import 'package:file_picker/file_picker.dart';
|
||||||
import 'package:flutter/material.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/appearance/providers/pure_black_dark_mode_state_provider.dart';
|
||||||
import 'package:mangayomi/modules/more/settings/track/widgets/track_listile.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_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/modules/widgets/draggable_scroll_bar.dart';
|
||||||
import 'package:mangayomi/providers/l10n_providers.dart';
|
import 'package:mangayomi/providers/l10n_providers.dart';
|
||||||
import 'package:mangayomi/providers/storage_provider.dart';
|
import 'package:mangayomi/providers/storage_provider.dart';
|
||||||
|
|
@ -1366,7 +1366,7 @@ class _MangaDetailViewState extends ConsumerState<MangaDetailView>
|
||||||
final imageProvider = widget.manga!.customCoverImage != null
|
final imageProvider = widget.manga!.customCoverImage != null
|
||||||
? MemoryImage(widget.manga!.customCoverImage as Uint8List)
|
? MemoryImage(widget.manga!.customCoverImage as Uint8List)
|
||||||
as ImageProvider
|
as ImageProvider
|
||||||
: CachedNetworkImageProvider(
|
: CustomExtendedNetworkImageProvider(
|
||||||
toImgUrl(widget.manga!.customCoverFromTracker ??
|
toImgUrl(widget.manga!.customCoverFromTracker ??
|
||||||
widget.manga!.imageUrl!),
|
widget.manga!.imageUrl!),
|
||||||
headers: widget.manga!.isLocalArchive!
|
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:draggable_menu/draggable_menu.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:mangayomi/models/track.dart';
|
import 'package:mangayomi/models/track.dart';
|
||||||
import 'package:mangayomi/models/track_search.dart';
|
import 'package:mangayomi/models/track_search.dart';
|
||||||
import 'package:mangayomi/modules/manga/detail/providers/track_state_providers.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/modules/widgets/progress_center.dart';
|
||||||
import 'package:mangayomi/utils/extensions/build_context_extensions.dart';
|
import 'package:mangayomi/utils/extensions/build_context_extensions.dart';
|
||||||
|
|
||||||
|
|
@ -84,8 +84,9 @@ class _TrackerWidgetSearchState extends ConsumerState<TrackerWidgetSearch> {
|
||||||
height: 120,
|
height: 120,
|
||||||
width: 80,
|
width: 80,
|
||||||
fit: BoxFit.cover,
|
fit: BoxFit.cover,
|
||||||
image: CachedNetworkImageProvider(
|
image:
|
||||||
tracks![index].coverUrl!),
|
CustomExtendedNetworkImageProvider(
|
||||||
|
tracks![index].coverUrl!),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(
|
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/reader_view.dart';
|
||||||
import 'package:mangayomi/modules/manga/reader/widgets/color_filter_widget.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/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/headers.dart';
|
||||||
import 'package:mangayomi/utils/reg_exp_matcher.dart';
|
import 'package:mangayomi/utils/reg_exp_matcher.dart';
|
||||||
|
|
||||||
|
|
@ -43,7 +44,7 @@ class ImageViewCenter extends ConsumerWidget {
|
||||||
? ExtendedMemoryImageProvider(archiveImage)
|
? ExtendedMemoryImageProvider(archiveImage)
|
||||||
: ExtendedFileImageProvider(
|
: ExtendedFileImageProvider(
|
||||||
File('${datas.path!.path}${padIndex(datas.index! + 1)}.jpg'))
|
File('${datas.path!.path}${padIndex(datas.index! + 1)}.jpg'))
|
||||||
: ExtendedNetworkImageProvider(datas.url!.trim().trimLeft().trimRight(),
|
: CustomExtendedNetworkImageProvider(datas.url!.trim().trimLeft().trimRight(),
|
||||||
cache: true,
|
cache: true,
|
||||||
cacheMaxAge: const Duration(days: 7),
|
cacheMaxAge: const Duration(days: 7),
|
||||||
headers: ref.watch(headersProvider(
|
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/reader_view.dart';
|
||||||
import 'package:mangayomi/modules/manga/reader/widgets/color_filter_widget.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/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/providers/l10n_providers.dart';
|
||||||
import 'package:mangayomi/utils/extensions/build_context_extensions.dart';
|
import 'package:mangayomi/utils/extensions/build_context_extensions.dart';
|
||||||
import 'package:mangayomi/utils/headers.dart';
|
import 'package:mangayomi/utils/headers.dart';
|
||||||
|
|
@ -42,7 +43,7 @@ class ImageViewVertical extends ConsumerWidget {
|
||||||
? ExtendedMemoryImageProvider(archiveImage)
|
? ExtendedMemoryImageProvider(archiveImage)
|
||||||
: ExtendedFileImageProvider(
|
: ExtendedFileImageProvider(
|
||||||
File('${datas.path!.path}${padIndex(datas.index! + 1)}.jpg'))
|
File('${datas.path!.path}${padIndex(datas.index! + 1)}.jpg'))
|
||||||
: ExtendedNetworkImageProvider(datas.url!.trim().trimLeft().trimRight(),
|
: CustomExtendedNetworkImageProvider(datas.url!.trim().trimLeft().trimRight(),
|
||||||
cache: true,
|
cache: true,
|
||||||
cacheMaxAge: const Duration(days: 7),
|
cacheMaxAge: const Duration(days: 7),
|
||||||
headers: ref.watch(headersProvider(
|
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 'dart:typed_data';
|
||||||
import 'package:cached_network_image/cached_network_image.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:go_router/go_router.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/settings.dart';
|
||||||
import 'package:mangayomi/models/source.dart';
|
import 'package:mangayomi/models/source.dart';
|
||||||
import 'package:mangayomi/modules/manga/detail/manga_detail_main.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/router/router.dart';
|
||||||
import 'package:mangayomi/utils/extensions/build_context_extensions.dart';
|
import 'package:mangayomi/utils/extensions/build_context_extensions.dart';
|
||||||
import 'package:mangayomi/utils/constant.dart';
|
import 'package:mangayomi/utils/constant.dart';
|
||||||
|
|
@ -52,7 +52,7 @@ class MangaImageCardWidget extends ConsumerWidget {
|
||||||
? MemoryImage(
|
? MemoryImage(
|
||||||
snapshot.data!.first.customCoverImage as Uint8List)
|
snapshot.data!.first.customCoverImage as Uint8List)
|
||||||
as ImageProvider
|
as ImageProvider
|
||||||
: CachedNetworkImageProvider(
|
: CustomExtendedNetworkImageProvider(
|
||||||
toImgUrl(hasData
|
toImgUrl(hasData
|
||||||
? snapshot.data!.first.customCoverFromTracker ??
|
? snapshot.data!.first.customCoverFromTracker ??
|
||||||
snapshot.data!.first.imageUrl ??
|
snapshot.data!.first.imageUrl ??
|
||||||
|
|
@ -60,7 +60,8 @@ class MangaImageCardWidget extends ConsumerWidget {
|
||||||
: getMangaDetail!.imageUrl!),
|
: getMangaDetail!.imageUrl!),
|
||||||
headers: ref.watch(headersProvider(
|
headers: ref.watch(headersProvider(
|
||||||
source: source.name!, lang: source.lang!)),
|
source: source.name!, lang: source.lang!)),
|
||||||
),
|
cache: true,
|
||||||
|
cacheMaxAge: const Duration(days: 7)),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
pushToMangaReaderDetail(
|
pushToMangaReaderDetail(
|
||||||
context: context,
|
context: context,
|
||||||
|
|
@ -125,7 +126,7 @@ class MangaImageCardListTileWidget extends ConsumerWidget {
|
||||||
final image = hasData && snapshot.data!.first.customCoverImage != null
|
final image = hasData && snapshot.data!.first.customCoverImage != null
|
||||||
? MemoryImage(snapshot.data!.first.customCoverImage as Uint8List)
|
? MemoryImage(snapshot.data!.first.customCoverImage as Uint8List)
|
||||||
as ImageProvider
|
as ImageProvider
|
||||||
: CachedNetworkImageProvider(
|
: CustomExtendedNetworkImageProvider(
|
||||||
toImgUrl(hasData
|
toImgUrl(hasData
|
||||||
? snapshot.data!.first.customCoverFromTracker ??
|
? snapshot.data!.first.customCoverFromTracker ??
|
||||||
snapshot.data!.first.imageUrl ??
|
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:flutter/foundation.dart';
|
||||||
|
import 'package:google_api_availability/google_api_availability.dart';
|
||||||
import 'package:http_interceptor/http_interceptor.dart';
|
import 'package:http_interceptor/http_interceptor.dart';
|
||||||
import 'package:mangayomi/eval/dart/model/m_bridge.dart';
|
import 'package:mangayomi/eval/dart/model/m_bridge.dart';
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
@ -8,16 +10,39 @@ import 'package:mangayomi/main.dart';
|
||||||
import 'package:flutter_inappwebview/flutter_inappwebview.dart'
|
import 'package:flutter_inappwebview/flutter_inappwebview.dart'
|
||||||
as flutter_inappwebview;
|
as flutter_inappwebview;
|
||||||
import 'package:mangayomi/models/settings.dart';
|
import 'package:mangayomi/models/settings.dart';
|
||||||
|
import 'package:cronet_http/cronet_http.dart';
|
||||||
|
import 'package:http/io_client.dart';
|
||||||
|
|
||||||
class MInterceptor {
|
class MInterceptor {
|
||||||
static final flutter_inappwebview.CookieManager _cookieManager =
|
static final flutter_inappwebview.CookieManager _cookieManager =
|
||||||
flutter_inappwebview.CookieManager.instance();
|
flutter_inappwebview.CookieManager.instance();
|
||||||
|
|
||||||
MInterceptor();
|
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(
|
static InterceptedClient init(
|
||||||
{MSource? source, Map<String, dynamic>? reqcopyWith}) {
|
{MSource? source, Map<String, dynamic>? reqcopyWith}) {
|
||||||
return InterceptedClient.build(
|
return InterceptedClient.build(
|
||||||
|
client: httpClient(),
|
||||||
interceptors: [MCookieManager(reqcopyWith), LoggerInterceptor()]);
|
interceptors: [MCookieManager(reqcopyWith), LoggerInterceptor()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||||
part 'torrent_server.g.dart';
|
part 'torrent_server.g.dart';
|
||||||
|
|
||||||
class MTorrentServer {
|
class MTorrentServer {
|
||||||
final http = MInterceptor.init();
|
final http = Client();
|
||||||
Future<bool> removeTorrent(String? inforHash) async {
|
Future<bool> removeTorrent(String? inforHash) async {
|
||||||
if (inforHash == null || inforHash.isEmpty) return false;
|
if (inforHash == null || inforHash.isEmpty) return false;
|
||||||
try {
|
try {
|
||||||
|
|
@ -44,7 +44,8 @@ class MTorrentServer {
|
||||||
|
|
||||||
Future<String> getInfohash(String url) async {
|
Future<String> getInfohash(String url) async {
|
||||||
try {
|
try {
|
||||||
final torrentByte = (await http.get(Uri.parse(url))).bodyBytes;
|
final torrentByte =
|
||||||
|
(await MInterceptor.init().get(Uri.parse(url))).bodyBytes;
|
||||||
var request =
|
var request =
|
||||||
MultipartRequest('POST', Uri.parse('$_baseUrl/torrent/add'));
|
MultipartRequest('POST', Uri.parse('$_baseUrl/torrent/add'));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,33 +1,29 @@
|
||||||
import 'package:cached_network_image/cached_network_image.dart';
|
import 'package:extended_image/extended_image.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:mangayomi/modules/widgets/custom_extended_image_provider.dart';
|
||||||
|
|
||||||
Widget cachedNetworkImage(
|
Widget cachedNetworkImage(
|
||||||
{required Map<String, String>? headers,
|
{Map<String, String>? headers,
|
||||||
required String imageUrl,
|
required String imageUrl,
|
||||||
required double? width,
|
required double? width,
|
||||||
required double? height,
|
required double? height,
|
||||||
required BoxFit? fit,
|
required BoxFit? fit,
|
||||||
AlignmentGeometry? alignment}) {
|
AlignmentGeometry? alignment,
|
||||||
if (kIsWeb) {
|
Widget errorWidget = const Icon(Icons.error, size: 50)}) {
|
||||||
return Image.network(
|
return ExtendedImage(
|
||||||
imageUrl,
|
image: CustomExtendedNetworkImageProvider(imageUrl, headers: headers),
|
||||||
width: width,
|
width: width,
|
||||||
height: height,
|
height: height,
|
||||||
fit: fit,
|
fit: fit,
|
||||||
alignment: alignment ?? Alignment.center,
|
filterQuality: FilterQuality.medium,
|
||||||
);
|
enableMemoryCache: true,
|
||||||
} else {
|
mode: ExtendedImageMode.gesture,
|
||||||
return CachedNetworkImage(
|
handleLoadingProgress: true,
|
||||||
httpHeaders: headers ?? {},
|
loadStateChanged: (state) {
|
||||||
imageUrl: imageUrl,
|
if (state.extendedImageLoadState == LoadState.failed) {
|
||||||
fit: fit,
|
return errorWidget;
|
||||||
width: width,
|
}
|
||||||
height: height,
|
return null;
|
||||||
errorWidget: (context, url, error) => const Icon(
|
},
|
||||||
Icons.error,
|
);
|
||||||
size: 50,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ list(APPEND FLUTTER_PLUGIN_LIST
|
||||||
)
|
)
|
||||||
|
|
||||||
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
||||||
|
jni
|
||||||
media_kit_native_event_loop
|
media_kit_native_event_loop
|
||||||
rinf
|
rinf
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,6 @@ import path_provider_foundation
|
||||||
import screen_brightness_macos
|
import screen_brightness_macos
|
||||||
import screen_retriever
|
import screen_retriever
|
||||||
import share_plus
|
import share_plus
|
||||||
import sqflite
|
|
||||||
import url_launcher_macos
|
import url_launcher_macos
|
||||||
import wakelock_plus
|
import wakelock_plus
|
||||||
import window_manager
|
import window_manager
|
||||||
|
|
@ -34,7 +33,6 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||||
ScreenBrightnessMacosPlugin.register(with: registry.registrar(forPlugin: "ScreenBrightnessMacosPlugin"))
|
ScreenBrightnessMacosPlugin.register(with: registry.registrar(forPlugin: "ScreenBrightnessMacosPlugin"))
|
||||||
ScreenRetrieverPlugin.register(with: registry.registrar(forPlugin: "ScreenRetrieverPlugin"))
|
ScreenRetrieverPlugin.register(with: registry.registrar(forPlugin: "ScreenRetrieverPlugin"))
|
||||||
SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin"))
|
SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin"))
|
||||||
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
|
|
||||||
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
|
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
|
||||||
WakelockPlusMacosPlugin.register(with: registry.registrar(forPlugin: "WakelockPlusMacosPlugin"))
|
WakelockPlusMacosPlugin.register(with: registry.registrar(forPlugin: "WakelockPlusMacosPlugin"))
|
||||||
WindowManagerPlugin.register(with: registry.registrar(forPlugin: "WindowManagerPlugin"))
|
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"]
|
crate-type = ["lib", "cdylib", "staticlib"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
rinf = "6.4.0"
|
rinf = "6.6.3"
|
||||||
allo-isolate = "0.1.24"
|
allo-isolate = "0.1.24"
|
||||||
wasm-bindgen = "0.2.90"
|
wasm-bindgen = "0.2.90"
|
||||||
prost = "0.12.3"
|
prost = "0.12.3"
|
||||||
tokio_with_wasm = "0.4.0"
|
tokio_with_wasm = "0.4.3"
|
||||||
image = "0.24.8"
|
image = "0.25.0"
|
||||||
boa_engine = "0.17.3"
|
|
||||||
|
|
|
||||||
|
|
@ -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.*/
|
SOFTWARE.*/
|
||||||
|
|
||||||
use crate::messages;
|
use crate::messages;
|
||||||
use image::{DynamicImage, GenericImageView, ImageOutputFormat, ImageResult, Rgba};
|
use image::{DynamicImage, GenericImageView, ImageResult, Rgba};
|
||||||
use std::io::Cursor;
|
use std::io::Cursor;
|
||||||
|
|
||||||
pub struct Point {
|
pub struct Point {
|
||||||
|
|
@ -145,7 +145,7 @@ pub async fn start_croping() {
|
||||||
let image = dart_signal.blob.unwrap();
|
let image = dart_signal.blob.unwrap();
|
||||||
let res = crop_image(image);
|
let res = crop_image(image);
|
||||||
let mut image_data: Vec<u8> = Vec::new();
|
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();
|
.unwrap();
|
||||||
CropBordersOutput {
|
CropBordersOutput {
|
||||||
interaction_id: dart_signal.message.interaction_id,
|
interaction_id: dart_signal.message.interaction_id,
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
use tokio_with_wasm::tokio;
|
use tokio_with_wasm::tokio;
|
||||||
|
|
||||||
mod boa_js;
|
|
||||||
mod imagecrop;
|
mod imagecrop;
|
||||||
mod messages;
|
mod messages;
|
||||||
|
|
||||||
|
|
@ -11,6 +10,5 @@ rinf::write_interface!();
|
||||||
async fn main() {
|
async fn main() {
|
||||||
// Repeat `crate::spawn` anywhere in your code
|
// Repeat `crate::spawn` anywhere in your code
|
||||||
// if more concurrent tasks are needed.
|
// if more concurrent tasks are needed.
|
||||||
tokio::spawn(boa_js::eval_js());
|
|
||||||
tokio::spawn(imagecrop::start_croping());
|
tokio::spawn(imagecrop::start_croping());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
106
pubspec.lock
106
pubspec.lock
|
|
@ -146,30 +146,6 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "8.9.0"
|
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:
|
characters:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -234,6 +210,14 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.1"
|
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:
|
cross_file:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -258,6 +242,14 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.0"
|
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:
|
cupertino_icons:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|
@ -462,14 +454,6 @@ packages:
|
||||||
description: flutter
|
description: flutter
|
||||||
source: sdk
|
source: sdk
|
||||||
version: "0.0.0"
|
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:
|
flutter_inappwebview:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|
@ -599,6 +583,30 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "12.1.3"
|
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:
|
google_fonts:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|
@ -632,7 +640,7 @@ packages:
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.15.4"
|
version: "0.15.4"
|
||||||
http:
|
http:
|
||||||
dependency: "direct overridden"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: http
|
name: http
|
||||||
sha256: a2bbf9d017fcced29139daa8ed2bba4ece450ab222871df93ca9eec6f80c34ba
|
sha256: a2bbf9d017fcced29139daa8ed2bba4ece450ab222871df93ca9eec6f80c34ba
|
||||||
|
|
@ -735,6 +743,14 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.0+1"
|
version: "3.1.0+1"
|
||||||
|
jni:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: jni
|
||||||
|
sha256: "0d88790bdf7e298aa65a9094c62b58ea231169a2deb84f23defc7d7955885b43"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.7.2"
|
||||||
js:
|
js:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -936,14 +952,6 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.2"
|
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:
|
package_config:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -1349,22 +1357,6 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "7.0.0"
|
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:
|
stack_trace:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,6 @@ dependencies:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
go_router: ^12.1.3
|
go_router: ^12.1.3
|
||||||
flutter_riverpod: ^2.4.10
|
flutter_riverpod: ^2.4.10
|
||||||
cached_network_image: ^3.3.1
|
|
||||||
riverpod_annotation: ^2.3.3
|
riverpod_annotation: ^2.3.3
|
||||||
html: ^0.15.4
|
html: ^0.15.4
|
||||||
font_awesome_flutter: ^10.6.0
|
font_awesome_flutter: ^10.6.0
|
||||||
|
|
@ -75,6 +74,10 @@ dependencies:
|
||||||
git:
|
git:
|
||||||
url: https://github.com/kodjodevf/flutter_qjs.git
|
url: https://github.com/kodjodevf/flutter_qjs.git
|
||||||
ref: main
|
ref: main
|
||||||
|
cronet_http: ^1.1.1
|
||||||
|
cupertino_http: ^1.3.0
|
||||||
|
http: ^1.2.0
|
||||||
|
google_api_availability: ^5.0.0
|
||||||
|
|
||||||
|
|
||||||
dependency_overrides:
|
dependency_overrides:
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ list(APPEND FLUTTER_PLUGIN_LIST
|
||||||
)
|
)
|
||||||
|
|
||||||
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
||||||
|
jni
|
||||||
media_kit_native_event_loop
|
media_kit_native_event_loop
|
||||||
rinf
|
rinf
|
||||||
)
|
)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue