Refactor
This commit is contained in:
parent
7afafc11e4
commit
243962c6bb
32 changed files with 1347 additions and 1665 deletions
File diff suppressed because it is too large
Load diff
|
|
@ -1,164 +1,19 @@
|
|||
import 'package:dart_eval/dart_eval.dart';
|
||||
import 'package:dart_eval/dart_eval_bridge.dart';
|
||||
import 'package:dart_eval/stdlib/core.dart';
|
||||
import 'package:mangayomi/eval/bridge_class/model.dart';
|
||||
import 'package:mangayomi/eval/model/m_manga.dart';
|
||||
|
||||
class $MangaModel implements MangaModel, $Instance {
|
||||
$MangaModel.wrap(this.$value) : _superclass = $Object($value);
|
||||
class $MManga implements MManga, $Instance {
|
||||
$MManga.wrap(this.$value) : _superclass = $Object($value);
|
||||
|
||||
static const $type = BridgeTypeRef(
|
||||
BridgeTypeSpec('package:bridge_lib/bridge_lib.dart', 'MangaModel'));
|
||||
BridgeTypeSpec('package:bridge_lib/bridge_lib.dart', 'MManga'));
|
||||
|
||||
static const $declaration = BridgeClassDef(BridgeClassType($type),
|
||||
constructors: {
|
||||
'': BridgeConstructorDef(BridgeFunctionDef(
|
||||
returns: BridgeTypeAnnotation($type),
|
||||
params: [],
|
||||
namedParams: [
|
||||
BridgeParameter(
|
||||
'source',
|
||||
BridgeTypeAnnotation(
|
||||
BridgeTypeRef.type(RuntimeTypes.stringType)),
|
||||
false),
|
||||
BridgeParameter(
|
||||
'author',
|
||||
BridgeTypeAnnotation(
|
||||
BridgeTypeRef.type(RuntimeTypes.stringType)),
|
||||
false),
|
||||
BridgeParameter(
|
||||
'status',
|
||||
BridgeTypeAnnotation(
|
||||
BridgeTypeRef.type(RuntimeTypes.intType)),
|
||||
false),
|
||||
BridgeParameter(
|
||||
'genre',
|
||||
BridgeTypeAnnotation(
|
||||
BridgeTypeRef(CoreTypes.list,
|
||||
[BridgeTypeRef.type(RuntimeTypes.stringType)]),
|
||||
),
|
||||
false),
|
||||
BridgeParameter(
|
||||
'imageUrl',
|
||||
BridgeTypeAnnotation(
|
||||
BridgeTypeRef.type(RuntimeTypes.stringType)),
|
||||
false),
|
||||
BridgeParameter(
|
||||
'lang',
|
||||
BridgeTypeAnnotation(
|
||||
BridgeTypeRef.type(RuntimeTypes.stringType)),
|
||||
false),
|
||||
BridgeParameter(
|
||||
'name',
|
||||
BridgeTypeAnnotation(
|
||||
BridgeTypeRef.type(RuntimeTypes.stringType)),
|
||||
false),
|
||||
BridgeParameter(
|
||||
'link',
|
||||
BridgeTypeAnnotation(
|
||||
BridgeTypeRef.type(RuntimeTypes.stringType)),
|
||||
false),
|
||||
BridgeParameter(
|
||||
'description',
|
||||
BridgeTypeAnnotation(
|
||||
BridgeTypeRef.type(RuntimeTypes.stringType)),
|
||||
false),
|
||||
BridgeParameter(
|
||||
'baseUrl',
|
||||
BridgeTypeAnnotation(
|
||||
BridgeTypeRef.type(RuntimeTypes.stringType)),
|
||||
false),
|
||||
BridgeParameter(
|
||||
'dateFormat',
|
||||
BridgeTypeAnnotation(
|
||||
BridgeTypeRef.type(RuntimeTypes.stringType)),
|
||||
false),
|
||||
BridgeParameter(
|
||||
'dateFormatLocale',
|
||||
BridgeTypeAnnotation(
|
||||
BridgeTypeRef.type(RuntimeTypes.stringType)),
|
||||
false),
|
||||
BridgeParameter(
|
||||
'apiUrl',
|
||||
BridgeTypeAnnotation(
|
||||
BridgeTypeRef.type(RuntimeTypes.stringType)),
|
||||
false),
|
||||
BridgeParameter(
|
||||
'page',
|
||||
BridgeTypeAnnotation(
|
||||
BridgeTypeRef.type(RuntimeTypes.intType)),
|
||||
false),
|
||||
BridgeParameter(
|
||||
'query',
|
||||
BridgeTypeAnnotation(
|
||||
BridgeTypeRef.type(RuntimeTypes.stringType)),
|
||||
false),
|
||||
BridgeParameter(
|
||||
'sourceId',
|
||||
BridgeTypeAnnotation(
|
||||
BridgeTypeRef.type(RuntimeTypes.intType)),
|
||||
false),
|
||||
BridgeParameter(
|
||||
'names',
|
||||
BridgeTypeAnnotation(
|
||||
BridgeTypeRef(CoreTypes.list,
|
||||
[BridgeTypeRef.type(RuntimeTypes.dynamicType)]),
|
||||
),
|
||||
false),
|
||||
BridgeParameter(
|
||||
'urls',
|
||||
BridgeTypeAnnotation(
|
||||
BridgeTypeRef(CoreTypes.list,
|
||||
[BridgeTypeRef.type(RuntimeTypes.dynamicType)]),
|
||||
),
|
||||
false),
|
||||
BridgeParameter(
|
||||
'chaptersScanlators',
|
||||
BridgeTypeAnnotation(
|
||||
BridgeTypeRef(CoreTypes.list,
|
||||
[BridgeTypeRef.type(RuntimeTypes.dynamicType)]),
|
||||
),
|
||||
false),
|
||||
BridgeParameter(
|
||||
'chaptersDateUploads',
|
||||
BridgeTypeAnnotation(
|
||||
BridgeTypeRef(CoreTypes.list,
|
||||
[BridgeTypeRef.type(RuntimeTypes.dynamicType)]),
|
||||
),
|
||||
false),
|
||||
BridgeParameter(
|
||||
'chaptersVolumes',
|
||||
BridgeTypeAnnotation(
|
||||
BridgeTypeRef(CoreTypes.list,
|
||||
[BridgeTypeRef.type(RuntimeTypes.dynamicType)]),
|
||||
),
|
||||
false),
|
||||
BridgeParameter(
|
||||
'chaptersChaps',
|
||||
BridgeTypeAnnotation(
|
||||
BridgeTypeRef(CoreTypes.list,
|
||||
[BridgeTypeRef.type(RuntimeTypes.dynamicType)]),
|
||||
),
|
||||
false),
|
||||
BridgeParameter(
|
||||
'images',
|
||||
BridgeTypeAnnotation(
|
||||
BridgeTypeRef(CoreTypes.list,
|
||||
[BridgeTypeRef.type(RuntimeTypes.dynamicType)]),
|
||||
),
|
||||
false),
|
||||
BridgeParameter(
|
||||
'statusList',
|
||||
BridgeTypeAnnotation(
|
||||
BridgeTypeRef(CoreTypes.list,
|
||||
[BridgeTypeRef.type(RuntimeTypes.dynamicType)]),
|
||||
),
|
||||
false),
|
||||
BridgeParameter(
|
||||
'hasNextPage',
|
||||
BridgeTypeAnnotation(
|
||||
BridgeTypeRef.type(RuntimeTypes.boolType)),
|
||||
false),
|
||||
]))
|
||||
returns: BridgeTypeAnnotation($type),
|
||||
))
|
||||
},
|
||||
// Specify class fields
|
||||
fields: {
|
||||
|
|
@ -201,49 +56,43 @@ class $MangaModel implements MangaModel, $Instance {
|
|||
'names': BridgeFieldDef(
|
||||
BridgeTypeAnnotation(
|
||||
BridgeTypeRef(
|
||||
CoreTypes.list, [BridgeTypeRef.type(RuntimeTypes.dynamicType)]),
|
||||
CoreTypes.list, [BridgeTypeRef.type(RuntimeTypes.stringType)]),
|
||||
),
|
||||
),
|
||||
'urls': BridgeFieldDef(
|
||||
BridgeTypeAnnotation(
|
||||
BridgeTypeRef(
|
||||
CoreTypes.list, [BridgeTypeRef.type(RuntimeTypes.dynamicType)]),
|
||||
CoreTypes.list, [BridgeTypeRef.type(RuntimeTypes.stringType)]),
|
||||
),
|
||||
),
|
||||
'chaptersScanlators': BridgeFieldDef(
|
||||
BridgeTypeAnnotation(
|
||||
BridgeTypeRef(
|
||||
CoreTypes.list, [BridgeTypeRef.type(RuntimeTypes.dynamicType)]),
|
||||
CoreTypes.list, [BridgeTypeRef.type(RuntimeTypes.stringType)]),
|
||||
),
|
||||
),
|
||||
'chaptersDateUploads': BridgeFieldDef(
|
||||
BridgeTypeAnnotation(
|
||||
BridgeTypeRef(
|
||||
CoreTypes.list, [BridgeTypeRef.type(RuntimeTypes.dynamicType)]),
|
||||
CoreTypes.list, [BridgeTypeRef.type(RuntimeTypes.stringType)]),
|
||||
),
|
||||
),
|
||||
'chaptersVolumes': BridgeFieldDef(
|
||||
BridgeTypeAnnotation(
|
||||
BridgeTypeRef(
|
||||
CoreTypes.list, [BridgeTypeRef.type(RuntimeTypes.dynamicType)]),
|
||||
CoreTypes.list, [BridgeTypeRef.type(RuntimeTypes.stringType)]),
|
||||
),
|
||||
),
|
||||
'chaptersChaps': BridgeFieldDef(
|
||||
BridgeTypeAnnotation(
|
||||
BridgeTypeRef(
|
||||
CoreTypes.list, [BridgeTypeRef.type(RuntimeTypes.dynamicType)]),
|
||||
CoreTypes.list, [BridgeTypeRef.type(RuntimeTypes.stringType)]),
|
||||
),
|
||||
),
|
||||
'images': BridgeFieldDef(
|
||||
BridgeTypeAnnotation(
|
||||
BridgeTypeRef(
|
||||
CoreTypes.list, [BridgeTypeRef.type(RuntimeTypes.dynamicType)]),
|
||||
),
|
||||
),
|
||||
'statusList': BridgeFieldDef(
|
||||
BridgeTypeAnnotation(
|
||||
BridgeTypeRef(
|
||||
CoreTypes.list, [BridgeTypeRef.type(RuntimeTypes.dynamicType)]),
|
||||
CoreTypes.list, [BridgeTypeRef.type(RuntimeTypes.stringType)]),
|
||||
),
|
||||
),
|
||||
'hasNextPage': BridgeFieldDef(
|
||||
|
|
@ -255,14 +104,14 @@ class $MangaModel implements MangaModel, $Instance {
|
|||
wrap: true);
|
||||
|
||||
static $Value? $new(Runtime runtime, $Value? target, List<$Value?> args) {
|
||||
return $MangaModel.wrap(MangaModel());
|
||||
return $MManga.wrap(MManga());
|
||||
}
|
||||
|
||||
@override
|
||||
final MangaModel $value;
|
||||
final MManga $value;
|
||||
|
||||
@override
|
||||
MangaModel get $reified => $value;
|
||||
MManga get $reified => $value;
|
||||
|
||||
final $Instance _superclass;
|
||||
|
||||
|
|
@ -363,10 +212,7 @@ class $MangaModel implements MangaModel, $Instance {
|
|||
return e;
|
||||
}
|
||||
}).toList());
|
||||
case 'statusList':
|
||||
return $List.wrap($value.statusList!.map((e) {
|
||||
return $int(e);
|
||||
}).toList());
|
||||
|
||||
case 'hasNextPage':
|
||||
return $bool($value.hasNextPage!);
|
||||
default:
|
||||
|
|
@ -387,7 +233,7 @@ class $MangaModel implements MangaModel, $Instance {
|
|||
case 'status':
|
||||
$value.status = value.$reified;
|
||||
case 'genre':
|
||||
$value.genre = value.$reified as List<dynamic>;
|
||||
$value.genre = value.$reified;
|
||||
case 'imageUrl':
|
||||
$value.imageUrl = value.$reified;
|
||||
case 'lang':
|
||||
|
|
@ -413,21 +259,19 @@ class $MangaModel implements MangaModel, $Instance {
|
|||
case 'sourceId':
|
||||
$value.sourceId = value.$reified;
|
||||
case 'names':
|
||||
$value.names = value.$reified as List<dynamic>;
|
||||
$value.names = value.$reified;
|
||||
case 'chaptersDateUploads':
|
||||
$value.chaptersDateUploads = value.$reified as List<dynamic>;
|
||||
$value.chaptersDateUploads = value.$reified;
|
||||
case 'chaptersScanlators':
|
||||
$value.chaptersScanlators = value.$reified as List<dynamic>;
|
||||
$value.chaptersScanlators = value.$reified;
|
||||
case 'urls':
|
||||
$value.urls = value.$reified as List<dynamic>;
|
||||
$value.urls = value.$reified;
|
||||
case 'chaptersVolumes':
|
||||
$value.chaptersVolumes = value.$reified as List<dynamic>;
|
||||
$value.chaptersVolumes = value.$reified;
|
||||
case 'chaptersChaps':
|
||||
$value.chaptersChaps = value.$reified as List<dynamic>;
|
||||
$value.chaptersChaps = value.$reified;
|
||||
case 'images':
|
||||
$value.images = value.$reified as List<dynamic>;
|
||||
case 'statusList':
|
||||
$value.statusList = value.$reified as List<dynamic>;
|
||||
$value.images = value.$reified;
|
||||
case 'hasNextPage':
|
||||
$value.hasNextPage = value.$reified;
|
||||
default:
|
||||
50
lib/eval/bridge/m_status.dart
Normal file
50
lib/eval/bridge/m_status.dart
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
import 'package:dart_eval/dart_eval.dart';
|
||||
import 'package:dart_eval/dart_eval_bridge.dart';
|
||||
import 'package:dart_eval/stdlib/core.dart';
|
||||
import 'package:mangayomi/models/manga.dart';
|
||||
|
||||
class $MStatus implements $Instance {
|
||||
static $MStatus $wrap(Runtime runtime, $Value? target, List<$Value?> args) =>
|
||||
$MStatus.wrap(args[0]!.$value);
|
||||
static const $type = BridgeTypeRef(
|
||||
BridgeTypeSpec('package:bridge_lib/bridge_lib.dart', 'MStatus'));
|
||||
static const $declaration = BridgeEnumDef($type, values: [
|
||||
'ongoing',
|
||||
'completed',
|
||||
'canceled',
|
||||
'unknown',
|
||||
'onHiatus',
|
||||
'publishingFinished'
|
||||
], methods: {}, getters: {}, setters: {}, fields: {});
|
||||
static final $values = Status.values.asNameMap().map(
|
||||
(key, value) => MapEntry(key, $MStatus.wrap(value)),
|
||||
);
|
||||
const $MStatus.wrap(this.$value);
|
||||
|
||||
@override
|
||||
final Status $value;
|
||||
|
||||
@override
|
||||
$Value? $getProperty(Runtime runtime, String identifier) {
|
||||
switch (identifier) {
|
||||
case 'index':
|
||||
return $int($value.index);
|
||||
case 'name':
|
||||
return $String($value.name);
|
||||
case 'hashCode':
|
||||
return $int($value.hashCode);
|
||||
}
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
void $setProperty(Runtime runtime, String identifier, $Value value) {
|
||||
throw UnimplementedError('Cannot set property on an enum');
|
||||
}
|
||||
|
||||
@override
|
||||
get $reified => $value;
|
||||
|
||||
@override
|
||||
int $getRuntimeType(Runtime runtime) => runtime.lookupType($type.spec!);
|
||||
}
|
||||
|
|
@ -1,31 +1,19 @@
|
|||
import 'package:dart_eval/dart_eval.dart';
|
||||
import 'package:dart_eval/dart_eval_bridge.dart';
|
||||
import 'package:dart_eval/stdlib/core.dart';
|
||||
import 'package:mangayomi/eval/bridge_class/model.dart';
|
||||
import 'package:mangayomi/eval/model/m_track.dart';
|
||||
|
||||
class $TrackModel implements TrackModel, $Instance {
|
||||
$TrackModel.wrap(this.$value) : _superclass = $Object($value);
|
||||
class $MTrack implements MTrack, $Instance {
|
||||
$MTrack.wrap(this.$value) : _superclass = $Object($value);
|
||||
|
||||
static const $type = BridgeTypeRef(
|
||||
BridgeTypeSpec('package:bridge_lib/bridge_lib.dart', 'TrackModel'));
|
||||
BridgeTypeSpec('package:bridge_lib/bridge_lib.dart', 'MTrack'));
|
||||
|
||||
static const $declaration = BridgeClassDef(BridgeClassType($type),
|
||||
constructors: {
|
||||
'': BridgeConstructorDef(BridgeFunctionDef(
|
||||
returns: BridgeTypeAnnotation($type),
|
||||
params: [],
|
||||
namedParams: [
|
||||
BridgeParameter(
|
||||
'file',
|
||||
BridgeTypeAnnotation(
|
||||
BridgeTypeRef.type(RuntimeTypes.stringType)),
|
||||
false),
|
||||
BridgeParameter(
|
||||
'label',
|
||||
BridgeTypeAnnotation(
|
||||
BridgeTypeRef.type(RuntimeTypes.stringType)),
|
||||
false),
|
||||
]))
|
||||
returns: BridgeTypeAnnotation($type),
|
||||
))
|
||||
},
|
||||
// Specify class fields
|
||||
fields: {
|
||||
|
|
@ -37,14 +25,14 @@ class $TrackModel implements TrackModel, $Instance {
|
|||
wrap: true);
|
||||
|
||||
static $Value? $new(Runtime runtime, $Value? target, List<$Value?> args) {
|
||||
return $TrackModel.wrap(TrackModel());
|
||||
return $MTrack.wrap(MTrack());
|
||||
}
|
||||
|
||||
@override
|
||||
final TrackModel $value;
|
||||
final MTrack $value;
|
||||
|
||||
@override
|
||||
TrackModel get $reified => $value;
|
||||
MTrack get $reified => $value;
|
||||
|
||||
final $Instance _superclass;
|
||||
|
||||
|
|
@ -1,52 +1,21 @@
|
|||
import 'package:dart_eval/dart_eval.dart';
|
||||
import 'package:dart_eval/dart_eval_bridge.dart';
|
||||
import 'package:dart_eval/stdlib/core.dart';
|
||||
import 'package:mangayomi/eval/bridge_class/model.dart';
|
||||
import 'package:mangayomi/eval/bridge_class/track_model.dart';
|
||||
import 'package:mangayomi/eval/model/m_track.dart';
|
||||
import 'package:mangayomi/eval/model/m_video.dart';
|
||||
import 'package:mangayomi/eval/bridge/m_track.dart';
|
||||
|
||||
class $VideoModel implements VideoModel, $Instance {
|
||||
$VideoModel.wrap(this.$value) : _superclass = $Object($value);
|
||||
class $MVideo implements MVideo, $Instance {
|
||||
$MVideo.wrap(this.$value) : _superclass = $Object($value);
|
||||
|
||||
static const $type = BridgeTypeRef(
|
||||
BridgeTypeSpec('package:bridge_lib/bridge_lib.dart', 'VideoModel'));
|
||||
BridgeTypeSpec('package:bridge_lib/bridge_lib.dart', 'MVideo'));
|
||||
|
||||
static const $declaration = BridgeClassDef(BridgeClassType($type),
|
||||
constructors: {
|
||||
'': BridgeConstructorDef(BridgeFunctionDef(
|
||||
returns: BridgeTypeAnnotation($type),
|
||||
params: [],
|
||||
namedParams: [
|
||||
BridgeParameter(
|
||||
'url',
|
||||
BridgeTypeAnnotation(
|
||||
BridgeTypeRef.type(RuntimeTypes.stringType)),
|
||||
false),
|
||||
BridgeParameter(
|
||||
'quality',
|
||||
BridgeTypeAnnotation(
|
||||
BridgeTypeRef.type(RuntimeTypes.stringType)),
|
||||
false),
|
||||
BridgeParameter(
|
||||
'originalUrl',
|
||||
BridgeTypeAnnotation(
|
||||
BridgeTypeRef.type(RuntimeTypes.stringType)),
|
||||
false),
|
||||
BridgeParameter(
|
||||
'headers',
|
||||
BridgeTypeAnnotation(
|
||||
BridgeTypeRef.type(RuntimeTypes.mapType)),
|
||||
false),
|
||||
BridgeParameter(
|
||||
'subtitles',
|
||||
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.list,
|
||||
[BridgeTypeRef.type(RuntimeTypes.dynamicType)])),
|
||||
false),
|
||||
BridgeParameter(
|
||||
'audios',
|
||||
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.list,
|
||||
[BridgeTypeRef.type(RuntimeTypes.dynamicType)])),
|
||||
false),
|
||||
]))
|
||||
returns: BridgeTypeAnnotation($type),
|
||||
))
|
||||
},
|
||||
// Specify class fields
|
||||
fields: {
|
||||
|
|
@ -57,23 +26,26 @@ class $VideoModel implements VideoModel, $Instance {
|
|||
'originalUrl': BridgeFieldDef(
|
||||
BridgeTypeAnnotation(BridgeTypeRef.type(RuntimeTypes.stringType))),
|
||||
'headers': BridgeFieldDef(
|
||||
BridgeTypeAnnotation(BridgeTypeRef.type(RuntimeTypes.mapType))),
|
||||
'subtitles': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(
|
||||
CoreTypes.list, [BridgeTypeRef.type(RuntimeTypes.dynamicType)]))),
|
||||
'audios': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(
|
||||
CoreTypes.list, [BridgeTypeRef.type(RuntimeTypes.dynamicType)]))),
|
||||
BridgeTypeAnnotation(BridgeTypeRef.type(RuntimeTypes.mapType, [
|
||||
BridgeTypeRef.type(RuntimeTypes.stringType),
|
||||
BridgeTypeRef.type(RuntimeTypes.stringType)
|
||||
]))),
|
||||
'subtitles': BridgeFieldDef(BridgeTypeAnnotation(
|
||||
BridgeTypeRef(CoreTypes.list, [$MTrack.$type]))),
|
||||
'audios': BridgeFieldDef(BridgeTypeAnnotation(
|
||||
BridgeTypeRef(CoreTypes.list, [$MTrack.$type]))),
|
||||
},
|
||||
wrap: true);
|
||||
|
||||
static $Value? $new(Runtime runtime, $Value? target, List<$Value?> args) {
|
||||
return $VideoModel.wrap(VideoModel());
|
||||
return $MVideo.wrap(MVideo());
|
||||
}
|
||||
|
||||
@override
|
||||
final VideoModel $value;
|
||||
final MVideo $value;
|
||||
|
||||
@override
|
||||
VideoModel get $reified => $value;
|
||||
MVideo get $reified => $value;
|
||||
|
||||
final $Instance _superclass;
|
||||
|
||||
|
|
@ -91,12 +63,12 @@ class $VideoModel implements VideoModel, $Instance {
|
|||
case 'subtitles':
|
||||
return $List.wrap($value.subtitles!
|
||||
.map((e) =>
|
||||
$TrackModel.wrap(TrackModel(file: e.file, label: e.label)))
|
||||
$MTrack.wrap(MTrack(file: e.file, label: e.label)))
|
||||
.toList());
|
||||
case 'audios':
|
||||
return $List.wrap($value.audios!
|
||||
.map((e) =>
|
||||
$TrackModel.wrap(TrackModel(file: e.file, label: e.label)))
|
||||
$MTrack.wrap(MTrack(file: e.file, label: e.label)))
|
||||
.toList());
|
||||
|
||||
default:
|
||||
|
|
@ -124,7 +96,7 @@ class $VideoModel implements VideoModel, $Instance {
|
|||
case 'subtitles':
|
||||
$value.subtitles = (value.$reified as List).isNotEmpty
|
||||
? (value.$reified as List)
|
||||
.map((e) => TrackModel()
|
||||
.map((e) => MTrack()
|
||||
..file = e.file
|
||||
..label = e.label)
|
||||
.toList()
|
||||
|
|
@ -132,7 +104,7 @@ class $VideoModel implements VideoModel, $Instance {
|
|||
case 'audios':
|
||||
$value.audios = (value.$reified as List).isNotEmpty
|
||||
? (value.$reified as List)
|
||||
.map((e) => TrackModel()
|
||||
.map((e) => MTrack()
|
||||
..file = e.file
|
||||
..label = e.label)
|
||||
.toList()
|
||||
|
|
@ -147,10 +119,10 @@ class $VideoModel implements VideoModel, $Instance {
|
|||
String? get url => $value.url;
|
||||
|
||||
@override
|
||||
List<TrackModel>? get subtitles => $value.subtitles;
|
||||
List<MTrack>? get subtitles => $value.subtitles;
|
||||
|
||||
@override
|
||||
List<TrackModel>? get audios => $value.audios;
|
||||
List<MTrack>? get audios => $value.audios;
|
||||
|
||||
@override
|
||||
String? get quality => $value.quality;
|
||||
|
|
@ -1,19 +1,21 @@
|
|||
import 'dart:typed_data';
|
||||
import 'package:dart_eval/dart_eval.dart';
|
||||
import 'package:mangayomi/eval/bridge_class/manga_model.dart';
|
||||
import 'package:mangayomi/eval/bridge_class/track_model.dart';
|
||||
import 'package:mangayomi/eval/bridge_class/video_model.dart';
|
||||
import 'package:mangayomi/eval/m_bridge.dart';
|
||||
import 'package:mangayomi/eval/bridge/m_manga.dart';
|
||||
import 'package:mangayomi/eval/bridge/m_status.dart';
|
||||
import 'package:mangayomi/eval/bridge/m_track.dart';
|
||||
import 'package:mangayomi/eval/bridge/m_video.dart';
|
||||
import 'package:mangayomi/eval/bridge/m_bridge.dart';
|
||||
import 'package:mangayomi/eval/utils.dart';
|
||||
|
||||
Uint8List compilerEval(String sourceCode) {
|
||||
final compiler = Compiler();
|
||||
compiler.defineBridgeClasses([
|
||||
$MBridge.$declaration,
|
||||
$MangaModel.$declaration,
|
||||
$VideoModel.$declaration,
|
||||
$TrackModel.$declaration
|
||||
$MManga.$declaration,
|
||||
$MVideo.$declaration,
|
||||
$MTrack.$declaration
|
||||
]);
|
||||
compiler.defineBridgeEnum($MStatus.$declaration);
|
||||
final program = compiler.compile({
|
||||
'mangayomi': {'source_code.dart': sourceCode, 'utils.dart': utils}
|
||||
});
|
||||
|
|
|
|||
991
lib/eval/model/m_bridge.dart
Normal file
991
lib/eval/model/m_bridge.dart
Normal file
|
|
@ -0,0 +1,991 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'package:bot_toast/bot_toast.dart';
|
||||
import 'package:dart_eval/dart_eval_bridge.dart';
|
||||
import 'package:dart_eval/stdlib/core.dart';
|
||||
import 'package:desktop_webview_window/desktop_webview_window.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
||||
import 'package:intl/date_symbol_data_local.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:js_packer/js_packer.dart';
|
||||
import 'package:json_path/json_path.dart';
|
||||
import 'package:mangayomi/services/anime_extractors/dood_extractor.dart';
|
||||
import 'package:mangayomi/services/anime_extractors/filemoon.dart';
|
||||
import 'package:mangayomi/services/anime_extractors/gogocdn_extractor.dart';
|
||||
import 'package:mangayomi/services/anime_extractors/mp4upload_extractor.dart';
|
||||
import 'package:mangayomi/services/anime_extractors/mytv_extractor.dart';
|
||||
import 'package:mangayomi/services/anime_extractors/okru_extractor.dart';
|
||||
import 'package:mangayomi/services/anime_extractors/rapidcloud_extractor.dart';
|
||||
import 'package:mangayomi/services/anime_extractors/sendvid_extractor.dart';
|
||||
import 'package:mangayomi/services/anime_extractors/sibnet_extractor.dart';
|
||||
import 'package:mangayomi/services/anime_extractors/streamlare_extractor.dart';
|
||||
import 'package:mangayomi/services/anime_extractors/streamtape_extractor.dart';
|
||||
import 'package:mangayomi/main.dart';
|
||||
import 'package:mangayomi/models/source.dart';
|
||||
import 'package:mangayomi/models/video.dart';
|
||||
import 'package:mangayomi/modules/webview/webview.dart';
|
||||
import 'package:mangayomi/services/anime_extractors/streamwish_extractor.dart';
|
||||
import 'package:mangayomi/services/anime_extractors/vidbom_extractor.dart';
|
||||
import 'package:mangayomi/services/anime_extractors/voe_extractor.dart';
|
||||
import 'package:mangayomi/services/anime_extractors/your_upload_extractor.dart';
|
||||
import 'package:mangayomi/services/http_service/cloudflare/cloudflare_bypass.dart';
|
||||
import 'package:mangayomi/utils/constant.dart';
|
||||
import 'package:mangayomi/utils/cryptoaes/crypto_aes.dart';
|
||||
import 'package:mangayomi/utils/cryptoaes/deobfuscator.dart';
|
||||
import 'package:mangayomi/utils/extensions.dart';
|
||||
import 'package:mangayomi/utils/reg_exp_matcher.dart';
|
||||
import 'package:mangayomi/utils/xpath_selector.dart';
|
||||
import 'package:xpath_selector_html_parser/xpath_selector_html_parser.dart';
|
||||
import 'package:html/parser.dart' as parser;
|
||||
import 'package:http/http.dart' as hp;
|
||||
import 'package:encrypt/encrypt.dart' as encrypt;
|
||||
|
||||
class WordSet {
|
||||
final List<String> words;
|
||||
|
||||
WordSet(this.words);
|
||||
|
||||
bool anyWordIn(String dateString) {
|
||||
return words
|
||||
.any((word) => dateString.toLowerCase().contains(word.toLowerCase()));
|
||||
}
|
||||
|
||||
bool startsWith(String dateString) {
|
||||
return words
|
||||
.any((word) => dateString.toLowerCase().startsWith(word.toLowerCase()));
|
||||
}
|
||||
|
||||
bool endsWith(String dateString) {
|
||||
return words
|
||||
.any((word) => dateString.toLowerCase().endsWith(word.toLowerCase()));
|
||||
}
|
||||
}
|
||||
|
||||
class MBridge {
|
||||
///Seaches for the first descendant node matching the given selectors, using a preorder traversal.
|
||||
static String querySelector(
|
||||
String html,
|
||||
String selector,
|
||||
int typeElement,
|
||||
String attributes,
|
||||
) {
|
||||
try {
|
||||
var parse = parser.parse(html);
|
||||
|
||||
// return querySelector text
|
||||
if (typeElement == 0) {
|
||||
return parse
|
||||
.querySelector(selector)!
|
||||
.text
|
||||
.trim()
|
||||
.trimLeft()
|
||||
.trimRight();
|
||||
|
||||
// return querySelector innerHtml
|
||||
} else if (typeElement == 1) {
|
||||
return parse
|
||||
.querySelector(selector)!
|
||||
.innerHtml
|
||||
.trim()
|
||||
.trimLeft()
|
||||
.trimRight();
|
||||
|
||||
// return querySelector outerHtml
|
||||
} else if (typeElement == 2) {
|
||||
return parse
|
||||
.querySelector(selector)!
|
||||
.outerHtml
|
||||
.trim()
|
||||
.trimLeft()
|
||||
.trimRight();
|
||||
}
|
||||
// return querySelector attributes
|
||||
return parse
|
||||
.querySelector(selector)!
|
||||
.attributes[attributes]!
|
||||
.trim()
|
||||
.trimLeft()
|
||||
.trimRight();
|
||||
} catch (e) {
|
||||
botToast(e.toString());
|
||||
throw Exception(e);
|
||||
}
|
||||
}
|
||||
|
||||
///Returns all descendant nodes matching the given selectors, using a preorder traversal.
|
||||
static List<String> querySelectorAll(String html, String selector,
|
||||
int typeElement, String attributes, int typeRegExp) {
|
||||
try {
|
||||
var parse = parser.parse(html);
|
||||
final a = parse.querySelectorAll(selector);
|
||||
|
||||
List<String> res = [];
|
||||
for (var element in a) {
|
||||
//text
|
||||
if (typeElement == 0) {
|
||||
res.add(element.text.trim().trimLeft().trimRight());
|
||||
}
|
||||
|
||||
//innerHtml
|
||||
else if (typeElement == 1) {
|
||||
res.add(element.innerHtml.trim().trimLeft().trimRight());
|
||||
}
|
||||
|
||||
//outerHtml
|
||||
else if (typeElement == 2) {
|
||||
res.add(element.outerHtml.trim().trimLeft().trimRight());
|
||||
}
|
||||
|
||||
//attributes
|
||||
else if (typeElement == 3) {
|
||||
res.add(
|
||||
element.attributes[attributes]!.trim().trimLeft().trimRight());
|
||||
}
|
||||
}
|
||||
// if (typeRegExp == 0) is the default parameter
|
||||
if (typeRegExp == 0) {
|
||||
return res;
|
||||
}
|
||||
|
||||
List<String> resRegExp = [];
|
||||
for (var element in res) {
|
||||
//get first element of href that match
|
||||
if (typeRegExp == 1) {
|
||||
resRegExp.add(regHrefMatcher(element.trim().trimLeft().trimRight()));
|
||||
}
|
||||
|
||||
//get first element of src that match
|
||||
else if (typeRegExp == 2) {
|
||||
resRegExp.add(regSrcMatcher(element.trim().trimLeft().trimRight()));
|
||||
}
|
||||
|
||||
//get first element of datasrc that match
|
||||
else if (typeRegExp == 3) {
|
||||
resRegExp
|
||||
.add(regDataSrcMatcher(element.trim().trimLeft().trimRight()));
|
||||
}
|
||||
|
||||
//get first element of img that match
|
||||
else if (typeRegExp == 4) {
|
||||
resRegExp.add(regImgMatcher(element.trim().trimLeft().trimRight()));
|
||||
}
|
||||
}
|
||||
return resRegExp;
|
||||
} catch (e) {
|
||||
botToast(e.toString());
|
||||
throw Exception(e);
|
||||
}
|
||||
}
|
||||
|
||||
///Create query by html string
|
||||
static List<String> xpath(String html, String xpath) {
|
||||
List<String> attrs = [];
|
||||
try {
|
||||
var htmlXPath = HtmlXPath.html(html);
|
||||
var query = htmlXPath.query(xpath);
|
||||
if (query.nodes.length > 1) {
|
||||
for (var element in query.attrs) {
|
||||
attrs.add(element!.trim().trimLeft().trimRight());
|
||||
}
|
||||
}
|
||||
|
||||
//Return one attr
|
||||
else if (query.nodes.length == 1) {
|
||||
String attr =
|
||||
query.attr != null ? query.attr!.trim().trimLeft().trimRight() : "";
|
||||
if (attr.isNotEmpty) {
|
||||
attrs = [attr];
|
||||
}
|
||||
}
|
||||
return attrs;
|
||||
} catch (e) {
|
||||
// botToast(e.toString());
|
||||
return attrs;
|
||||
}
|
||||
}
|
||||
|
||||
///A list utility function
|
||||
static List listParse(List value, int type) {
|
||||
List<dynamic> val = [];
|
||||
for (var element in value) {
|
||||
if (element is $Value) {
|
||||
val.add(element.$reified.toString());
|
||||
} else {
|
||||
val.add(element);
|
||||
}
|
||||
}
|
||||
if (type == 3) {
|
||||
return val.toSet().toList();
|
||||
} else if (type == 1) {
|
||||
return [val.first];
|
||||
} else if (type == 2) {
|
||||
return [val.last];
|
||||
} else if (type == 4) {
|
||||
return val.where((element) => element.toString().isNotEmpty).toList();
|
||||
} else if (type == 5) {
|
||||
return val.reversed.toList();
|
||||
} else if (type == 6) {
|
||||
return [val.join()];
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
///Convert serie status to int
|
||||
///[status] contains the current status of the serie
|
||||
///[statusList] contains a list of map of many static status
|
||||
static int parseStatus(String status, List statusList) {
|
||||
for (var element in statusList) {
|
||||
Map statusMap = {};
|
||||
if (element is $Map<$Value, $Value>) {
|
||||
statusMap = element.$reified;
|
||||
} else {
|
||||
statusMap = element;
|
||||
}
|
||||
for (var element in statusMap.entries) {
|
||||
if (element.key
|
||||
.toString()
|
||||
.toLowerCase()
|
||||
.contains(status.toLowerCase().trim().trimLeft().trimRight())) {
|
||||
return element.value as int;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 5;
|
||||
}
|
||||
|
||||
///Get Html content via webview when http request not working
|
||||
static Future<String> getHtmlViaWebview(String url, String rule) async {
|
||||
bool isOk = false;
|
||||
String? html;
|
||||
if (Platform.isWindows || Platform.isLinux || Platform.isMacOS) {
|
||||
final webview = await WebviewWindow.create(
|
||||
configuration: CreateConfiguration(
|
||||
windowHeight: 500,
|
||||
windowWidth: 500,
|
||||
userDataFolderWindows: await getWebViewPath(),
|
||||
),
|
||||
);
|
||||
webview
|
||||
..setApplicationNameForUserAgent(defaultUserAgent)
|
||||
..launch(url);
|
||||
await Future.doWhile(() async {
|
||||
await Future.delayed(const Duration(seconds: 3));
|
||||
html = await decodeHtml(
|
||||
webview,
|
||||
);
|
||||
if (html == null || xpathSelector(html!).query(rule).attrs.isEmpty) {
|
||||
html = await decodeHtml(webview);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
html = await decodeHtml(webview);
|
||||
webview.close();
|
||||
} else {
|
||||
HeadlessInAppWebView? headlessWebView;
|
||||
headlessWebView = HeadlessInAppWebView(
|
||||
onLoadStop: (controller, u) async {
|
||||
html = await controller.evaluateJavascript(
|
||||
source:
|
||||
"window.document.getElementsByTagName('html')[0].outerHTML;");
|
||||
await Future.doWhile(() async {
|
||||
html = await controller.evaluateJavascript(
|
||||
source:
|
||||
"window.document.getElementsByTagName('html')[0].outerHTML;");
|
||||
if (xpathSelector(html!).query(rule).attrs.isEmpty) {
|
||||
html = await controller.evaluateJavascript(
|
||||
source:
|
||||
"window.document.getElementsByTagName('html')[0].outerHTML;");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
html = await controller.evaluateJavascript(
|
||||
source:
|
||||
"window.document.getElementsByTagName('html')[0].outerHTML;");
|
||||
isOk = true;
|
||||
headlessWebView!.dispose();
|
||||
},
|
||||
initialUrlRequest: URLRequest(
|
||||
url: Uri.parse(url),
|
||||
),
|
||||
);
|
||||
headlessWebView.run();
|
||||
await Future.doWhile(() async {
|
||||
await Future.delayed(const Duration(seconds: 1));
|
||||
if (isOk == true) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
return html!;
|
||||
}
|
||||
|
||||
///Utility to decode json to List
|
||||
static List<dynamic> jsonDecodeToList(String source, int type) {
|
||||
return type == 0
|
||||
? jsonDecode(source) as List
|
||||
: (jsonDecode(source) as List).map((e) => jsonEncode(e)).toList();
|
||||
}
|
||||
|
||||
///Deobfuscate a JS code
|
||||
static String evalJs(String code) {
|
||||
try {
|
||||
// JavascriptRuntime? flutterJs;
|
||||
// flutterJs = getJavascriptRuntime();
|
||||
// final res = flutterJs.evaluate(code).stringResult;
|
||||
// flutterJs.dispose();
|
||||
// return res;
|
||||
final jsPacker = JSPacker(code);
|
||||
return jsPacker.unpack() ?? "";
|
||||
} catch (e) {
|
||||
botToast(e.toString());
|
||||
throw Exception(e);
|
||||
}
|
||||
}
|
||||
|
||||
///Read values in parsed JSON object and return resut to List<String>
|
||||
static List<String> jsonPathToList(
|
||||
String source, String expression, int type) {
|
||||
try {
|
||||
//Check jsonDecode(source) is list value
|
||||
if (jsonDecode(source) is List) {
|
||||
List<dynamic> values = [];
|
||||
final val = jsonDecode(source) as List;
|
||||
for (var element in val) {
|
||||
final mMap = element as Map?;
|
||||
Map<String, dynamic> map = {};
|
||||
if (mMap != null) {
|
||||
map = mMap.map((key, value) => MapEntry(key.toString(), value));
|
||||
}
|
||||
values.add(map);
|
||||
}
|
||||
List<String> list = [];
|
||||
for (var data in values) {
|
||||
final jsonRes = JsonPath(expression).read(data);
|
||||
String val = "";
|
||||
|
||||
//Get jsonRes first string value
|
||||
if (type == 0) {
|
||||
val = jsonRes.first.value.toString();
|
||||
}
|
||||
|
||||
//Decode jsonRes first map value
|
||||
else {
|
||||
val = jsonEncode(jsonRes.first.value);
|
||||
}
|
||||
list.add(val);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
// else jsonDecode(source) is Map value
|
||||
else {
|
||||
var map = json.decode(source);
|
||||
var values = JsonPath(expression).readValues(map);
|
||||
return values.map((e) {
|
||||
return e == null ? "{}" : json.encode(e);
|
||||
}).toList();
|
||||
}
|
||||
} catch (e) {
|
||||
botToast(e.toString());
|
||||
throw Exception(e);
|
||||
}
|
||||
}
|
||||
|
||||
///GetMapValue
|
||||
static String getMapValue(String source, String attr, bool encode) {
|
||||
try {
|
||||
var map = json.decode(source) as Map<String, dynamic>;
|
||||
if (!encode) {
|
||||
return map[attr] != null ? map[attr].toString() : "";
|
||||
}
|
||||
return map[attr] != null ? jsonEncode(map[attr]) : "";
|
||||
} catch (_) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
///Read values in parsed JSON object and return resut to String
|
||||
static String jsonPathToString(
|
||||
String source, String expression, String join) {
|
||||
try {
|
||||
List<dynamic> values = [];
|
||||
|
||||
//Check jsonDecode(source) is list value
|
||||
if (jsonDecode(source) is List) {
|
||||
final val = jsonDecode(source) as List;
|
||||
for (var element in val) {
|
||||
final mMap = element as Map?;
|
||||
Map<String, dynamic> map = {};
|
||||
if (mMap != null) {
|
||||
map = mMap.map((key, value) => MapEntry(key.toString(), value));
|
||||
}
|
||||
values.add(map);
|
||||
}
|
||||
}
|
||||
|
||||
// else jsonDecode(source) is Map value
|
||||
else {
|
||||
final mMap = jsonDecode(source) as Map?;
|
||||
Map<String, dynamic> map = {};
|
||||
if (mMap != null) {
|
||||
map = mMap.map((key, value) => MapEntry(key.toString(), value));
|
||||
}
|
||||
values.add(map);
|
||||
}
|
||||
|
||||
List<String> listRg = [];
|
||||
|
||||
for (var data in values) {
|
||||
final jsonRes = JsonPath(expression).readValues(data);
|
||||
List list = [];
|
||||
|
||||
for (var element in jsonRes) {
|
||||
list.add(element);
|
||||
}
|
||||
//join the list into listRg
|
||||
listRg.add(list.join(join));
|
||||
}
|
||||
return listRg.first;
|
||||
} catch (e) {
|
||||
botToast(e.toString());
|
||||
throw Exception(e);
|
||||
}
|
||||
}
|
||||
|
||||
//Utility to decode json values as Map<String,dynamic>
|
||||
static Map jsonPathToMap(String source) {
|
||||
final mMap = jsonDecode(source) as Map?;
|
||||
Map<String, dynamic> map = {};
|
||||
if (mMap != null) {
|
||||
map = mMap.map((key, value) => MapEntry(key.toString(), value));
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
//Parse a list of dates to millisecondsSinceEpoch
|
||||
static List listParseDateTime(
|
||||
List value, String dateFormat, String dateFormatLocale) {
|
||||
List<dynamic> val = [];
|
||||
for (var element in value) {
|
||||
if (element is $Value) {
|
||||
val.add(element.$reified.toString());
|
||||
} else {
|
||||
val.add(element);
|
||||
}
|
||||
}
|
||||
|
||||
List<dynamic> valD = [];
|
||||
for (var date in val) {
|
||||
if (date.toString().isNotEmpty) {
|
||||
valD.add(parseChapterDate(date, dateFormat, dateFormatLocale));
|
||||
}
|
||||
}
|
||||
return valD;
|
||||
}
|
||||
|
||||
static List sortMapList(List list, String value, int type) {
|
||||
if (type == 0) {
|
||||
list.sort((a, b) => a[value].compareTo(b[value]));
|
||||
} else if (type == 1) {
|
||||
list.sort((a, b) => b[value].compareTo(a[value]));
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
//Utility to use RegExp
|
||||
static String regExp(
|
||||
//RegExp(r'\[a\]'), "[123]")
|
||||
String expression,
|
||||
String source,
|
||||
String replace,
|
||||
int type,
|
||||
int group) {
|
||||
if (type == 0) {
|
||||
return expression.replaceAll(RegExp(source), replace);
|
||||
}
|
||||
return regCustomMatcher(expression, source, group);
|
||||
}
|
||||
|
||||
//Utility to parse $int to int
|
||||
static int intParse(String value) {
|
||||
return int.parse(value);
|
||||
}
|
||||
|
||||
//Utility to check if list contains a value
|
||||
static bool listContain(List value, String element) {
|
||||
List<dynamic> val = [];
|
||||
for (var element in value) {
|
||||
val.add(element.$reified);
|
||||
}
|
||||
return val.contains(element);
|
||||
}
|
||||
|
||||
//Http request for MultiparFormData
|
||||
static Future<String> httpMultiparFormData(String url, int method) async {
|
||||
try {
|
||||
hp.StreamedResponse? res;
|
||||
String result = "";
|
||||
final headersMap = jsonDecode(url)["headers"] as Map?;
|
||||
|
||||
final fieldsMap = jsonDecode(url)["fields"] as Map?;
|
||||
Map<String, String> fields = {};
|
||||
if (fieldsMap != null) {
|
||||
fields = fieldsMap
|
||||
.map((key, value) => MapEntry(key.toString(), value.toString()));
|
||||
}
|
||||
Map<String, String> headers = {};
|
||||
if (headersMap != null) {
|
||||
headers = headersMap
|
||||
.map((key, value) => MapEntry(key.toString(), value.toString()));
|
||||
}
|
||||
|
||||
var request = hp.MultipartRequest(
|
||||
method == 0
|
||||
? 'GET'
|
||||
: method == 1
|
||||
? 'POST'
|
||||
: method == 2
|
||||
? 'PUT'
|
||||
: 'DELETE',
|
||||
Uri.parse(url));
|
||||
request.fields.addAll(fields);
|
||||
|
||||
request.headers.addAll(headers);
|
||||
|
||||
res = await request.send();
|
||||
|
||||
if (res.statusCode != 200) {
|
||||
result = "400";
|
||||
} else if (res.statusCode == 200) {
|
||||
result = await res.stream.bytesToString();
|
||||
} else {
|
||||
result = res.reasonPhrase!;
|
||||
}
|
||||
|
||||
return result;
|
||||
} catch (e) {
|
||||
botToast(e.toString());
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
//http request and also webview
|
||||
static Future<String> http(String method, String datas) async {
|
||||
try {
|
||||
hp.StreamedResponse? res;
|
||||
String result = "";
|
||||
|
||||
//Get headers
|
||||
final headersMap = jsonDecode(datas)["headers"] as Map?;
|
||||
|
||||
//Get sourceId
|
||||
final sourceId = jsonDecode(datas)["sourceId"] as int?;
|
||||
|
||||
//Get body
|
||||
final bodyMap = jsonDecode(datas)["body"] as Map?;
|
||||
|
||||
final url = jsonDecode(datas)["url"] as String;
|
||||
//Convert body Map<dynamic,dynamic> to Map<String,String>
|
||||
Map<String, dynamic> body = {};
|
||||
if (bodyMap != null) {
|
||||
body = bodyMap.map((key, value) => MapEntry(key.toString(), value));
|
||||
}
|
||||
|
||||
//Convert headers Map<dynamic,dynamic> to Map<String,String>
|
||||
Map<String, String> headers = {};
|
||||
if (headersMap != null) {
|
||||
headers = headersMap
|
||||
.map((key, value) => MapEntry(key.toString(), value.toString()));
|
||||
}
|
||||
|
||||
//Get the serie source
|
||||
final source = sourceId != null ? isar.sources.getSync(sourceId) : null;
|
||||
|
||||
//Check the serie if has cloudflare
|
||||
// if (source != null && source.hasCloudflare!) {
|
||||
// final res = await cloudflareBypass(
|
||||
// url: url, sourceId: source.id.toString(), method: method);
|
||||
// return res;
|
||||
// }
|
||||
|
||||
//Do the http request if the serie hasn't cloudflare
|
||||
var request = hp.Request(method, Uri.parse(url));
|
||||
|
||||
if (bodyMap != null) {
|
||||
request.body = json.encode(body);
|
||||
}
|
||||
|
||||
request.headers.addAll(headers);
|
||||
|
||||
res = await request.send();
|
||||
|
||||
if (res.statusCode != 200 && source != null && source.hasCloudflare!) {
|
||||
result = await cloudflareBypass(
|
||||
url: url, sourceId: source.id.toString(), method: 0);
|
||||
} else if (res.statusCode != 200) {
|
||||
result = "400";
|
||||
} else if (res.statusCode == 200) {
|
||||
result = await res.stream.bytesToString();
|
||||
} else {
|
||||
result = res.reasonPhrase!;
|
||||
}
|
||||
|
||||
return result;
|
||||
} catch (e) {
|
||||
botToast(e.toString());
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
static Future<List<Video>> gogoCdnExtractor(String url) async {
|
||||
return await GogoCdnExtractor().videosFromUrl(
|
||||
url,
|
||||
);
|
||||
}
|
||||
|
||||
static Future<List<Video>> doodExtractor(String url, String? quality) async {
|
||||
return await DoodExtractor().videosFromUrl(url, quality: quality);
|
||||
}
|
||||
|
||||
static Future<List<Video>> streamWishExtractor(
|
||||
String url, String prefix) async {
|
||||
return await StreamWishExtractor().videosFromUrl(url, prefix);
|
||||
}
|
||||
|
||||
static Future<List<Video>> filemoonExtractor(
|
||||
String url, String prefix) async {
|
||||
return await FilemoonExtractor().videosFromUrl(url, prefix);
|
||||
}
|
||||
|
||||
static Future<List<Video>> mp4UploadExtractor(
|
||||
String url, String? headers, String prefix, String suffix) async {
|
||||
Map<String, String> newHeaders = {};
|
||||
if (headers != null) {
|
||||
newHeaders = (jsonDecode(headers) as Map)
|
||||
.map((key, value) => MapEntry(key.toString(), value.toString()));
|
||||
}
|
||||
return await Mp4uploadExtractor()
|
||||
.videosFromUrl(url, newHeaders, prefix: prefix, suffix: suffix);
|
||||
}
|
||||
|
||||
static Future<List<Video>> streamTapeExtractor(
|
||||
String url, String? quality) async {
|
||||
return await StreamTapeExtractor()
|
||||
.videosFromUrl(url, quality: quality ?? "StreamTape");
|
||||
}
|
||||
|
||||
//Utility to use substring
|
||||
static String substringAfter(String text, String pattern) {
|
||||
return text.substringAfter(pattern);
|
||||
}
|
||||
|
||||
//Utility to use substring
|
||||
static String substringBefore(String text, String pattern) {
|
||||
return text.substringBefore(pattern);
|
||||
}
|
||||
|
||||
//Utility to use substring
|
||||
static String substringBeforeLast(String text, String pattern) {
|
||||
return text.substringBeforeLast(pattern);
|
||||
}
|
||||
|
||||
static String substringAfterLast(String text, String pattern) {
|
||||
return text.split(pattern).last;
|
||||
}
|
||||
|
||||
//Parse a chapter date to millisecondsSinceEpoch
|
||||
static String parseChapterDate(
|
||||
String date, String dateFormat, String dateFormatLocale) {
|
||||
int parseRelativeDate(String date) {
|
||||
final number = int.tryParse(RegExp(r"(\d+)").firstMatch(date)!.group(0)!);
|
||||
if (number == null) return 0;
|
||||
final cal = DateTime.now();
|
||||
|
||||
if (WordSet([
|
||||
"hari",
|
||||
"gün",
|
||||
"jour",
|
||||
"día",
|
||||
"dia",
|
||||
"day",
|
||||
"วัน",
|
||||
"ngày",
|
||||
"giorni",
|
||||
"أيام",
|
||||
"天"
|
||||
]).anyWordIn(date)) {
|
||||
return cal.subtract(Duration(days: number)).millisecondsSinceEpoch;
|
||||
} else if (WordSet([
|
||||
"jam",
|
||||
"saat",
|
||||
"heure",
|
||||
"hora",
|
||||
"hour",
|
||||
"ชั่วโมง",
|
||||
"giờ",
|
||||
"ore",
|
||||
"ساعة",
|
||||
"小时"
|
||||
]).anyWordIn(date)) {
|
||||
return cal.subtract(Duration(hours: number)).millisecondsSinceEpoch;
|
||||
} else if (WordSet(
|
||||
["menit", "dakika", "min", "minute", "minuto", "นาที", "دقائق"])
|
||||
.anyWordIn(date)) {
|
||||
return cal.subtract(Duration(minutes: number)).millisecondsSinceEpoch;
|
||||
} else if (WordSet(["detik", "segundo", "second", "วินาที", "sec"])
|
||||
.anyWordIn(date)) {
|
||||
return cal.subtract(Duration(seconds: number)).millisecondsSinceEpoch;
|
||||
} else if (WordSet(["week", "semana"]).anyWordIn(date)) {
|
||||
return cal.subtract(Duration(days: number * 7)).millisecondsSinceEpoch;
|
||||
} else if (WordSet(["month", "mes"]).anyWordIn(date)) {
|
||||
return cal.subtract(Duration(days: number * 30)).millisecondsSinceEpoch;
|
||||
} else if (WordSet(["year", "año"]).anyWordIn(date)) {
|
||||
return cal
|
||||
.subtract(Duration(days: number * 365))
|
||||
.millisecondsSinceEpoch;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
if (WordSet(["yesterday", "يوم واحد"]).startsWith(date)) {
|
||||
DateTime cal = DateTime.now().subtract(const Duration(days: 1));
|
||||
cal = DateTime(cal.year, cal.month, cal.day);
|
||||
return cal.millisecondsSinceEpoch.toString();
|
||||
} else if (WordSet(["today"]).startsWith(date)) {
|
||||
DateTime cal = DateTime.now();
|
||||
cal = DateTime(cal.year, cal.month, cal.day);
|
||||
return cal.millisecondsSinceEpoch.toString();
|
||||
} else if (WordSet(["يومين"]).startsWith(date)) {
|
||||
DateTime cal = DateTime.now().subtract(const Duration(days: 2));
|
||||
cal = DateTime(cal.year, cal.month, cal.day);
|
||||
return cal.millisecondsSinceEpoch.toString();
|
||||
} else if (WordSet(["ago", "atrás", "önce", "قبل"]).endsWith(date)) {
|
||||
return parseRelativeDate(date).toString();
|
||||
} else if (WordSet(["hace"]).startsWith(date)) {
|
||||
return parseRelativeDate(date).toString();
|
||||
} else if (date.contains(RegExp(r"\d(st|nd|rd|th)"))) {
|
||||
final cleanedDate = date
|
||||
.split(" ")
|
||||
.map((it) => it.contains(RegExp(r"\d\D\D"))
|
||||
? it.replaceAll(RegExp(r"\D"), "")
|
||||
: it)
|
||||
.join(" ");
|
||||
return DateFormat(dateFormat, dateFormatLocale)
|
||||
.parse(cleanedDate)
|
||||
.millisecondsSinceEpoch
|
||||
.toString();
|
||||
} else {
|
||||
return DateFormat(dateFormat, dateFormatLocale)
|
||||
.parse(date)
|
||||
.millisecondsSinceEpoch
|
||||
.toString();
|
||||
}
|
||||
} catch (e) {
|
||||
final supportedLocales = DateFormat.allLocalesWithSymbols();
|
||||
|
||||
for (var locale in supportedLocales) {
|
||||
for (var dateFormat in _dateFormats) {
|
||||
try {
|
||||
initializeDateFormatting(locale);
|
||||
if (WordSet(["yesterday", "يوم واحد"]).startsWith(date)) {
|
||||
DateTime cal = DateTime.now().subtract(const Duration(days: 1));
|
||||
cal = DateTime(cal.year, cal.month, cal.day);
|
||||
return cal.millisecondsSinceEpoch.toString();
|
||||
} else if (WordSet(["today"]).startsWith(date)) {
|
||||
DateTime cal = DateTime.now();
|
||||
cal = DateTime(cal.year, cal.month, cal.day);
|
||||
return cal.millisecondsSinceEpoch.toString();
|
||||
} else if (WordSet(["يومين"]).startsWith(date)) {
|
||||
DateTime cal = DateTime.now().subtract(const Duration(days: 2));
|
||||
cal = DateTime(cal.year, cal.month, cal.day);
|
||||
return cal.millisecondsSinceEpoch.toString();
|
||||
} else if (WordSet(["ago", "atrás", "önce", "قبل"])
|
||||
.endsWith(date)) {
|
||||
return parseRelativeDate(date).toString();
|
||||
} else if (WordSet(["hace"]).startsWith(date)) {
|
||||
return parseRelativeDate(date).toString();
|
||||
} else if (date.contains(RegExp(r"\d(st|nd|rd|th)"))) {
|
||||
final cleanedDate = date
|
||||
.split(" ")
|
||||
.map((it) => it.contains(RegExp(r"\d\D\D"))
|
||||
? it.replaceAll(RegExp(r"\D"), "")
|
||||
: it)
|
||||
.join(" ");
|
||||
return DateFormat(dateFormat, locale)
|
||||
.parse(cleanedDate)
|
||||
.millisecondsSinceEpoch
|
||||
.toString();
|
||||
} else {
|
||||
return DateFormat(dateFormat, locale)
|
||||
.parse(date)
|
||||
.millisecondsSinceEpoch
|
||||
.toString();
|
||||
}
|
||||
} catch (_) {}
|
||||
}
|
||||
}
|
||||
botToast(e.toString());
|
||||
throw Exception(e);
|
||||
}
|
||||
}
|
||||
|
||||
static String deobfuscateJsPassword(String inputString) {
|
||||
return Deobfuscator.deobfuscateJsPassword(inputString);
|
||||
}
|
||||
|
||||
static Future<List<Video>> sibnetExtractor(String url) async {
|
||||
return await SibnetExtractor().videosFromUrl(
|
||||
url,
|
||||
);
|
||||
}
|
||||
|
||||
static Future<List<Video>> sendVidExtractor(
|
||||
String url, String? headers, String prefix) async {
|
||||
Map<String, String> newHeaders = {};
|
||||
if (headers != null) {
|
||||
newHeaders = (jsonDecode(headers) as Map)
|
||||
.map((key, value) => MapEntry(key.toString(), value.toString()));
|
||||
}
|
||||
|
||||
return await SendvidExtractor(newHeaders)
|
||||
.videosFromUrl(url, prefix: prefix);
|
||||
}
|
||||
|
||||
static Future<List<Video>> myTvExtractor(String url) async {
|
||||
return await MytvExtractor().videosFromUrl(
|
||||
url,
|
||||
);
|
||||
}
|
||||
|
||||
static Future<List<Video>> okruExtractor(String url) async {
|
||||
return await OkruExtractor().videosFromUrl(
|
||||
url,
|
||||
);
|
||||
}
|
||||
|
||||
static Future<List<Video>> yourUploadExtractor(
|
||||
String url, String? headers, String? name, String prefix) async {
|
||||
Map<String, String> newHeaders = {};
|
||||
if (headers != null) {
|
||||
newHeaders = (jsonDecode(headers) as Map)
|
||||
.map((key, value) => MapEntry(key.toString(), value.toString()));
|
||||
}
|
||||
return await YourUploadExtractor().videosFromUrl(url, newHeaders,
|
||||
prefix: prefix, name: name ?? "YourUpload");
|
||||
}
|
||||
|
||||
static Future<List<Video>> voeExtractor(String url, String? quality) async {
|
||||
return await VoeExtractor().videosFromUrl(url, quality);
|
||||
}
|
||||
|
||||
static Future<List<Video>> vidBomExtractor(String url) async {
|
||||
return await VidBomExtractor().videosFromUrl(
|
||||
url,
|
||||
);
|
||||
}
|
||||
|
||||
static Future<List<Video>> streamlareExtractor(
|
||||
String url, String prefix, String suffix) async {
|
||||
return await StreamlareExtractor()
|
||||
.videosFromUrl(url, prefix: prefix, suffix: suffix);
|
||||
}
|
||||
|
||||
static Future<List<Video>> rapidCloudExtractor(
|
||||
String url, String prefix) async {
|
||||
return await RapidCloudExtractor().videosFromUrl(url, prefix);
|
||||
}
|
||||
|
||||
static String encryptAESCryptoJS(String plainText, String passphrase) {
|
||||
return CryptoAES.encryptAESCryptoJS(plainText, passphrase);
|
||||
}
|
||||
|
||||
static String decryptAESCryptoJS(String encrypted, String passphrase) {
|
||||
return CryptoAES.decryptAESCryptoJS(encrypted, passphrase);
|
||||
}
|
||||
|
||||
static Video toVideo(String url, String quality, String originalUrl,
|
||||
String? headers, List<Track>? subtitles, List<Track>? audios) {
|
||||
Map<String, String> newHeaders = {};
|
||||
if (headers != null) {
|
||||
newHeaders = (jsonDecode(headers) as Map)
|
||||
.map((key, value) => MapEntry(key.toString(), value.toString()));
|
||||
}
|
||||
return Video(url, quality, originalUrl,
|
||||
headers: newHeaders, subtitles: subtitles ?? [], audios: audios ?? []);
|
||||
}
|
||||
|
||||
static String cryptoHandler(
|
||||
String text, String iv, String secretKeyString, bool encrypt) {
|
||||
if (encrypt) {
|
||||
final encryptt = _encrypt(secretKeyString, iv);
|
||||
final en = encryptt.$1.encrypt(text, iv: encryptt.$2);
|
||||
return en.base64;
|
||||
} else {
|
||||
final encryptt = _encrypt(secretKeyString, iv);
|
||||
final en = encryptt.$1.decrypt64(text, iv: encryptt.$2);
|
||||
return en;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final List<String> _dateFormats = [
|
||||
'dd/MM/yyyy',
|
||||
'MM/dd/yyyy',
|
||||
'yyyy/MM/dd',
|
||||
'dd-MM-yyyy',
|
||||
'MM-dd-yyyy',
|
||||
'yyyy-MM-dd',
|
||||
'dd.MM.yyyy',
|
||||
'MM.dd.yyyy',
|
||||
'yyyy.MM.dd',
|
||||
'dd MMMM yyyy',
|
||||
'MMMM dd, yyyy',
|
||||
'yyyy MMMM dd',
|
||||
'dd MMM yyyy',
|
||||
'MMM dd yyyy',
|
||||
'yyyy MMM dd',
|
||||
'dd MMMM, yyyy',
|
||||
'yyyy, MMMM dd',
|
||||
'MMMM dd yyyy',
|
||||
'MMM dd, yyyy',
|
||||
'dd LLLL yyyy',
|
||||
'LLLL dd, yyyy',
|
||||
'yyyy LLLL dd',
|
||||
'LLLL dd yyyy',
|
||||
"MMMMM dd, yyyy",
|
||||
"MMM d, yyy",
|
||||
"MMM d, yyyy",
|
||||
"dd/mm/yyyy",
|
||||
"d MMMM yyyy",
|
||||
"dd 'de' MMMM 'de' yyyy",
|
||||
"d MMMM'،' yyyy",
|
||||
"yyyy'年'M'月'd",
|
||||
"d MMMM, yyyy",
|
||||
"dd 'de' MMMMM 'de' yyyy",
|
||||
"dd MMMMM, yyyy",
|
||||
"MMMM d, yyyy",
|
||||
"MMM dd,yyyy"
|
||||
];
|
||||
void botToast(String title) {
|
||||
BotToast.showSimpleNotification(
|
||||
onlyOne: true,
|
||||
dismissDirections: [DismissDirection.horizontal, DismissDirection.down],
|
||||
align: const Alignment(0, 0.99),
|
||||
duration: const Duration(seconds: 10),
|
||||
title: title);
|
||||
}
|
||||
|
||||
(encrypt.Encrypter, encrypt.IV) _encrypt(String keyy, String ivv) {
|
||||
final key = encrypt.Key.fromUtf8(keyy);
|
||||
final iv = encrypt.IV.fromUtf8(ivv);
|
||||
final encrypter = encrypt.Encrypter(
|
||||
encrypt.AES(key, mode: encrypt.AESMode.cbc, padding: 'PKCS7'));
|
||||
return (encrypter, iv);
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
class MangaModel {
|
||||
class MManga {
|
||||
String? name;
|
||||
|
||||
String? link;
|
||||
|
|
@ -41,7 +41,7 @@ class MangaModel {
|
|||
List<dynamic>? chaptersChaps;
|
||||
List<dynamic>? images;
|
||||
List<dynamic>? statusList;
|
||||
MangaModel(
|
||||
MManga(
|
||||
{this.source = "",
|
||||
this.author = "",
|
||||
this.genre,
|
||||
|
|
@ -68,26 +68,3 @@ class MangaModel {
|
|||
this.statusList,
|
||||
this.hasNextPage = true});
|
||||
}
|
||||
|
||||
class VideoModel {
|
||||
String? url;
|
||||
String? quality;
|
||||
String? originalUrl;
|
||||
Map<String, String>? headers;
|
||||
List<TrackModel>? subtitles;
|
||||
List<TrackModel>? audios;
|
||||
VideoModel(
|
||||
{this.url,
|
||||
this.quality,
|
||||
this.originalUrl,
|
||||
this.headers,
|
||||
this.subtitles,
|
||||
this.audios});
|
||||
}
|
||||
|
||||
class TrackModel {
|
||||
String? file;
|
||||
String? label;
|
||||
|
||||
TrackModel({this.file, this.label});
|
||||
}
|
||||
6
lib/eval/model/m_track.dart
Normal file
6
lib/eval/model/m_track.dart
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
class MTrack {
|
||||
String? file;
|
||||
String? label;
|
||||
|
||||
MTrack({this.file, this.label});
|
||||
}
|
||||
17
lib/eval/model/m_video.dart
Normal file
17
lib/eval/model/m_video.dart
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
import 'package:mangayomi/eval/model/m_track.dart';
|
||||
|
||||
class MVideo {
|
||||
String? url;
|
||||
String? quality;
|
||||
String? originalUrl;
|
||||
Map<String, String>? headers;
|
||||
List<MTrack>? subtitles;
|
||||
List<MTrack>? audios;
|
||||
MVideo(
|
||||
{this.url,
|
||||
this.quality,
|
||||
this.originalUrl,
|
||||
this.headers,
|
||||
this.subtitles,
|
||||
this.audios});
|
||||
}
|
||||
|
|
@ -1,10 +1,11 @@
|
|||
import 'dart:typed_data';
|
||||
|
||||
import 'package:dart_eval/dart_eval.dart';
|
||||
import 'package:mangayomi/eval/bridge_class/track_model.dart';
|
||||
import 'package:mangayomi/eval/bridge_class/video_model.dart';
|
||||
import 'package:mangayomi/eval/m_bridge.dart';
|
||||
import 'package:mangayomi/eval/bridge_class/manga_model.dart';
|
||||
import 'package:mangayomi/eval/bridge/m_status.dart';
|
||||
import 'package:mangayomi/eval/bridge/m_track.dart';
|
||||
import 'package:mangayomi/eval/bridge/m_video.dart';
|
||||
import 'package:mangayomi/eval/bridge/m_bridge.dart';
|
||||
import 'package:mangayomi/eval/bridge/m_manga.dart';
|
||||
|
||||
Runtime runtimeEval(Uint8List bytecode) {
|
||||
final runtime = Runtime(bytecode.buffer.asByteData());
|
||||
|
|
@ -12,19 +13,20 @@ Runtime runtimeEval(Uint8List bytecode) {
|
|||
'package:bridge_lib/bridge_lib.dart', 'MBridge.', $MBridge.$construct,
|
||||
isBridge: true);
|
||||
runtime.registerBridgeFunc(
|
||||
'package:bridge_lib/bridge_lib.dart', 'MangaModel.', $MangaModel.$new);
|
||||
'package:bridge_lib/bridge_lib.dart', 'MManga.', $MManga.$new);
|
||||
runtime.registerBridgeFunc(
|
||||
'package:bridge_lib/bridge_lib.dart', 'VideoModel.', $VideoModel.$new);
|
||||
'package:bridge_lib/bridge_lib.dart', 'MVideo.', $MVideo.$new);
|
||||
runtime.registerBridgeFunc(
|
||||
'package:bridge_lib/bridge_lib.dart', 'TrackModel.', $TrackModel.$new);
|
||||
'package:bridge_lib/bridge_lib.dart', 'MTrack.', $MTrack.$new);
|
||||
runtime.registerBridgeEnumValues(
|
||||
'package:bridge_lib/bridge_lib.dart', 'MStatus', $MStatus.$values);
|
||||
|
||||
runtime.registerBridgeFunc(
|
||||
'package:bridge_lib/bridge_lib.dart', 'MBridge.http', $MBridge.$http);
|
||||
runtime.registerBridgeFunc('package:bridge_lib/bridge_lib.dart',
|
||||
'MBridge.listParseDateTime', $MBridge.$listParseDateTime);
|
||||
runtime.registerBridgeFunc('package:bridge_lib/bridge_lib.dart',
|
||||
'MBridge.httpMultiparFormData', $MBridge.$httpMultiparFormData);
|
||||
runtime.registerBridgeFunc(
|
||||
'package:bridge_lib/bridge_lib.dart', 'MBridge.bAse64', $MBridge.$bAse64);
|
||||
runtime.registerBridgeFunc('package:bridge_lib/bridge_lib.dart',
|
||||
'MBridge.gogoCdnExtractor', $MBridge.$gogoCdnExtractor);
|
||||
runtime.registerBridgeFunc('package:bridge_lib/bridge_lib.dart',
|
||||
|
|
@ -63,8 +65,6 @@ Runtime runtimeEval(Uint8List bytecode) {
|
|||
'MBridge.jsonPathToString', $MBridge.$jsonPathToString);
|
||||
runtime.registerBridgeFunc('package:bridge_lib/bridge_lib.dart',
|
||||
'MBridge.toVideo', $MBridge.$toVideo);
|
||||
runtime.registerBridgeFunc('package:bridge_lib/bridge_lib.dart',
|
||||
'MBridge.isEmptyOrIsNotEmpty', $MBridge.$isEmptyOrIsNotEmpty);
|
||||
runtime.registerBridgeFunc('package:bridge_lib/bridge_lib.dart',
|
||||
'MBridge.jsonPathToList', $MBridge.$jsonPathToList);
|
||||
runtime.registerBridgeFunc('package:bridge_lib/bridge_lib.dart',
|
||||
|
|
@ -73,16 +73,12 @@ Runtime runtimeEval(Uint8List bytecode) {
|
|||
'MBridge.jsonPathToMap', $MBridge.$jsonPathToMap);
|
||||
runtime.registerBridgeFunc('package:bridge_lib/bridge_lib.dart',
|
||||
'MBridge.parseStatus', $MBridge.$parseStatus);
|
||||
runtime.registerBridgeFunc('package:bridge_lib/bridge_lib.dart',
|
||||
'MBridge.stringParseValue', $MBridge.$stringParseValue);
|
||||
runtime.registerBridgeFunc('package:bridge_lib/bridge_lib.dart',
|
||||
'MBridge.getMapValue', $MBridge.$getMapValue);
|
||||
runtime.registerBridgeFunc(
|
||||
'package:bridge_lib/bridge_lib.dart', 'MBridge.regExp', $MBridge.$regExp);
|
||||
runtime.registerBridgeFunc('package:bridge_lib/bridge_lib.dart',
|
||||
'MBridge.parseChapterDate', $MBridge.$parseChapterDate);
|
||||
runtime.registerBridgeFunc('package:bridge_lib/bridge_lib.dart',
|
||||
'MBridge.stringParse', $MBridge.$stringParse);
|
||||
runtime.registerBridgeFunc('package:bridge_lib/bridge_lib.dart',
|
||||
'MBridge.substringAfter', $MBridge.$substringAfter);
|
||||
runtime.registerBridgeFunc('package:bridge_lib/bridge_lib.dart',
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
import 'package:isar/isar.dart';
|
||||
import 'package:mangayomi/eval/model/m_manga.dart';
|
||||
import 'package:mangayomi/models/chapter.dart';
|
||||
import 'package:mangayomi/models/source.dart';
|
||||
part 'manga.g.dart';
|
||||
|
||||
@collection
|
||||
|
|
@ -64,6 +66,30 @@ class Manga {
|
|||
this.lastRead = 0,
|
||||
this.isLocalArchive = false,
|
||||
this.customCoverImage});
|
||||
|
||||
MManga toMManga(Source source) {
|
||||
return MManga(
|
||||
name: name,
|
||||
link: link,
|
||||
genre: genre,
|
||||
author: author,
|
||||
status: switch (status) {
|
||||
Status.ongoing => 0,
|
||||
Status.completed => 1,
|
||||
Status.onHiatus => 2,
|
||||
Status.canceled => 3,
|
||||
Status.publishingFinished => 4,
|
||||
_ => 5,
|
||||
},
|
||||
description: description,
|
||||
imageUrl: imageUrl,
|
||||
baseUrl: source.baseUrl,
|
||||
apiUrl: source.apiUrl,
|
||||
lang: lang,
|
||||
dateFormat: source.dateFormat,
|
||||
source: source.name,
|
||||
dateFormatLocale: source.dateFormatLocale);
|
||||
}
|
||||
}
|
||||
|
||||
enum Status {
|
||||
|
|
@ -74,4 +100,3 @@ enum Status {
|
|||
onHiatus,
|
||||
publishingFinished
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import 'package:isar/isar.dart';
|
||||
import 'package:mangayomi/eval/model/m_manga.dart';
|
||||
part 'source.g.dart';
|
||||
|
||||
@collection
|
||||
|
|
@ -92,4 +93,17 @@ class Source {
|
|||
isFullData = json['isFullData'] ?? false;
|
||||
appMinVerReq = json['appMinVerReq'];
|
||||
}
|
||||
MManga toMManga({int page = 1, String? query = "", String link = ""}) {
|
||||
return MManga(
|
||||
page: page,
|
||||
query: query,
|
||||
link: link,
|
||||
lang: lang,
|
||||
baseUrl: baseUrl,
|
||||
apiUrl: apiUrl,
|
||||
sourceId: id,
|
||||
source: name,
|
||||
dateFormat: dateFormat,
|
||||
dateFormatLocale: dateFormatLocale);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|||
import 'package:isar/isar.dart';
|
||||
import 'package:mangayomi/main.dart';
|
||||
import 'package:mangayomi/models/manga.dart';
|
||||
import 'package:mangayomi/eval/bridge_class/model.dart';
|
||||
import 'package:mangayomi/eval/model/m_manga.dart';
|
||||
import 'package:mangayomi/modules/manga/home/manga_home_screen.dart';
|
||||
import 'package:mangayomi/providers/l10n_providers.dart';
|
||||
import 'package:mangayomi/router/router.dart';
|
||||
|
|
@ -173,7 +173,7 @@ class SourceSearchScreen extends ConsumerWidget {
|
|||
}
|
||||
|
||||
class MangaGlobalImageCard extends ConsumerStatefulWidget {
|
||||
final MangaModel manga;
|
||||
final MManga manga;
|
||||
final Source source;
|
||||
|
||||
const MangaGlobalImageCard({
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
import 'package:mangayomi/eval/bridge_class/model.dart';
|
||||
import 'package:mangayomi/main.dart';
|
||||
import 'package:mangayomi/models/chapter.dart';
|
||||
import 'package:mangayomi/models/manga.dart';
|
||||
|
|
@ -15,64 +14,23 @@ Future<dynamic> updateMangaDetail(UpdateMangaDetailRef ref,
|
|||
return;
|
||||
}
|
||||
final source = getSource(manga.lang!, manga.source!);
|
||||
final mangaS = MangaModel(
|
||||
name: manga.name,
|
||||
link: manga.link,
|
||||
genre: manga.genre,
|
||||
author: manga.author,
|
||||
status: switch (manga.status) {
|
||||
Status.ongoing => 0,
|
||||
Status.completed => 1,
|
||||
Status.onHiatus => 2,
|
||||
Status.canceled => 3,
|
||||
Status.publishingFinished => 4,
|
||||
_ => 5,
|
||||
},
|
||||
description: manga.description,
|
||||
imageUrl: manga.imageUrl,
|
||||
baseUrl: source!.baseUrl,
|
||||
apiUrl: source.apiUrl,
|
||||
lang: manga.lang,
|
||||
dateFormat: source.dateFormat,
|
||||
dateFormatLocale: source.dateFormatLocale);
|
||||
final getManga = await ref
|
||||
.watch(getMangaDetailProvider(manga: mangaS, source: source).future);
|
||||
|
||||
final imageUrl = getManga.imageUrl != null && getManga.imageUrl!.isNotEmpty
|
||||
? getManga.imageUrl
|
||||
: manga.imageUrl ?? "";
|
||||
final name = getManga.name != null && getManga.name!.isNotEmpty
|
||||
? getManga.name!.trim().trimLeft().trimRight()
|
||||
: manga.name ?? "";
|
||||
final genre = getManga.genre != null && getManga.genre!.isNotEmpty
|
||||
? getManga.genre!
|
||||
.map((e) => e.toString().trim().trimLeft().trimRight())
|
||||
.toList()
|
||||
.toSet()
|
||||
.toList()
|
||||
: manga.genre ?? [];
|
||||
final getManga = await ref.watch(
|
||||
getMangaDetailProvider(manga: manga.toMManga(source!), source: source)
|
||||
.future);
|
||||
|
||||
final author = getManga.author != null && getManga.author!.isNotEmpty
|
||||
? getManga.author!.trim().trimLeft().trimRight()
|
||||
: manga.author ?? "";
|
||||
final description =
|
||||
getManga.description != null && getManga.description!.isNotEmpty
|
||||
? getManga.description!.trim().trimLeft().trimRight()
|
||||
: manga.description ?? "";
|
||||
final link = getManga.link != null && getManga.link!.isNotEmpty
|
||||
? getManga.link!.trim().trimLeft().trimRight()
|
||||
: manga.link ?? "";
|
||||
final sourceA = getManga.source != null && getManga.source!.isNotEmpty
|
||||
? getManga.source!.trim().trimLeft().trimRight()
|
||||
: manga.source ?? "";
|
||||
final lang = getManga.lang != null && getManga.lang!.isNotEmpty
|
||||
? getManga.lang!.trim().trimLeft().trimRight()
|
||||
: manga.lang ?? "";
|
||||
manga
|
||||
..imageUrl = imageUrl
|
||||
..name = name
|
||||
..genre = genre
|
||||
..author = author
|
||||
..imageUrl = getManga.imageUrl ?? manga.imageUrl
|
||||
..name = getManga.name?.trim().trimLeft().trimRight() ?? manga.name
|
||||
..genre = getManga.genre
|
||||
?.map((e) => e.toString().trim().trimLeft().trimRight())
|
||||
.toList()
|
||||
.toSet()
|
||||
.toList() ??
|
||||
manga.genre ??
|
||||
[]
|
||||
..author =
|
||||
getManga.author?.trim().trimLeft().trimRight() ?? manga.author ?? ""
|
||||
..status = switch (getManga.status) {
|
||||
0 => Status.ongoing,
|
||||
1 => Status.completed,
|
||||
|
|
@ -81,10 +39,12 @@ Future<dynamic> updateMangaDetail(UpdateMangaDetailRef ref,
|
|||
4 => Status.publishingFinished,
|
||||
_ => Status.unknown,
|
||||
}
|
||||
..description = description
|
||||
..link = link
|
||||
..source = sourceA
|
||||
..lang = lang
|
||||
..description = getManga.description?.trim().trimLeft().trimRight() ??
|
||||
manga.description ??
|
||||
""
|
||||
..link = getManga.link?.trim().trimLeft().trimRight() ?? manga.link
|
||||
..source = getManga.source?.trim().trimLeft().trimRight() ?? manga.source
|
||||
..lang = manga.lang
|
||||
..isManga = source.isManga
|
||||
..lastUpdate = DateTime.now().millisecondsSinceEpoch;
|
||||
final checkManga = isar.mangas.getSync(mangaId);
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import 'package:flutter/material.dart';
|
|||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:mangayomi/models/source.dart';
|
||||
import 'package:mangayomi/eval/bridge_class/model.dart';
|
||||
import 'package:mangayomi/eval/model/m_manga.dart';
|
||||
import 'package:mangayomi/providers/l10n_providers.dart';
|
||||
import 'package:mangayomi/services/get_latest_updates_manga.dart';
|
||||
import 'package:mangayomi/services/get_popular_manga.dart';
|
||||
|
|
@ -53,8 +53,8 @@ class _MangaHomeScreenState extends ConsumerState<MangaHomeScreen> {
|
|||
];
|
||||
}
|
||||
|
||||
Future<List<MangaModel?>> _loadMore() async {
|
||||
List<MangaModel?> mangaResList = [];
|
||||
Future<List<MManga?>> _loadMore() async {
|
||||
List<MManga?> mangaResList = [];
|
||||
|
||||
if (_isLoading) {
|
||||
if (widget.source.isFullData!) {
|
||||
|
|
@ -91,7 +91,7 @@ class _MangaHomeScreenState extends ConsumerState<MangaHomeScreen> {
|
|||
late final _textEditingController = TextEditingController(text: widget.query);
|
||||
late String _query = widget.query;
|
||||
late bool _isSearch = widget.isSearch;
|
||||
AsyncValue<List<MangaModel?>>? _getManga;
|
||||
AsyncValue<List<MManga?>>? _getManga;
|
||||
int _length = 0;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
|
@ -398,7 +398,7 @@ class _MangaHomeScreenState extends ConsumerState<MangaHomeScreen> {
|
|||
}
|
||||
|
||||
class MangaHomeImageCard extends ConsumerStatefulWidget {
|
||||
final MangaModel manga;
|
||||
final MManga manga;
|
||||
final bool isManga;
|
||||
final Source source;
|
||||
const MangaHomeImageCard({
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import 'package:isar/isar.dart';
|
|||
import 'package:mangayomi/main.dart';
|
||||
import 'package:mangayomi/models/manga.dart';
|
||||
import 'package:mangayomi/models/settings.dart';
|
||||
import 'package:mangayomi/eval/bridge_class/model.dart';
|
||||
import 'package:mangayomi/eval/model/m_manga.dart';
|
||||
import 'package:mangayomi/modules/manga/detail/manga_detail_main.dart';
|
||||
import 'package:mangayomi/providers/l10n_providers.dart';
|
||||
import 'package:mangayomi/router/router.dart';
|
||||
|
|
@ -21,7 +21,7 @@ class MangaImageCardWidget extends ConsumerWidget {
|
|||
final String lang;
|
||||
final bool isManga;
|
||||
|
||||
final MangaModel? getMangaDetail;
|
||||
final MManga? getMangaDetail;
|
||||
|
||||
const MangaImageCardWidget(
|
||||
{required this.lang,
|
||||
|
|
@ -103,7 +103,7 @@ class MangaImageCardWidget extends ConsumerWidget {
|
|||
}
|
||||
|
||||
void pushToMangaReaderDetail(
|
||||
{MangaModel? getManga,
|
||||
{MManga? getManga,
|
||||
required String lang,
|
||||
required BuildContext context,
|
||||
int? archiveId,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import 'package:http/http.dart' as http;
|
||||
import 'package:mangayomi/eval/m_bridge.dart';
|
||||
import 'package:mangayomi/eval/model/m_bridge.dart';
|
||||
import 'package:mangayomi/models/video.dart';
|
||||
import 'package:mangayomi/utils/extensions.dart';
|
||||
import 'package:mangayomi/utils/xpath_selector.dart';
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import 'dart:convert';
|
||||
import 'package:html/dom.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:mangayomi/eval/m_bridge.dart';
|
||||
import 'package:mangayomi/eval/model/m_bridge.dart';
|
||||
import 'package:mangayomi/models/video.dart';
|
||||
import 'package:html/parser.dart' as parser;
|
||||
import 'package:mangayomi/utils/extensions.dart';
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import 'package:http/http.dart' as http;
|
||||
import 'package:mangayomi/eval/m_bridge.dart';
|
||||
import 'package:mangayomi/eval/model/m_bridge.dart';
|
||||
import 'package:mangayomi/models/video.dart';
|
||||
import 'package:mangayomi/utils/extensions.dart';
|
||||
import 'package:mangayomi/utils/xpath_selector.dart';
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import 'package:http/http.dart' as http;
|
||||
import 'package:mangayomi/eval/m_bridge.dart';
|
||||
import 'package:mangayomi/eval/model/m_bridge.dart';
|
||||
import 'package:mangayomi/models/video.dart';
|
||||
import 'package:mangayomi/utils/extensions.dart';
|
||||
import 'package:mangayomi/utils/xpath_selector.dart';
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
import 'package:dart_eval/stdlib/core.dart';
|
||||
import 'package:mangayomi/eval/bridge_class/manga_model.dart';
|
||||
import 'package:mangayomi/eval/bridge_class/model.dart';
|
||||
import 'package:mangayomi/eval/bridge/m_manga.dart';
|
||||
import 'package:mangayomi/eval/model/m_track.dart';
|
||||
import 'package:mangayomi/eval/compiler/compiler.dart';
|
||||
import 'package:mangayomi/models/chapter.dart';
|
||||
import 'package:mangayomi/models/video.dart';
|
||||
|
|
@ -34,16 +34,7 @@ Future<(List<Video>, bool)> getAnimeServers(
|
|||
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
|
||||
|
||||
final runtime = runtimeEval(bytecode);
|
||||
runtime.args = [
|
||||
$MangaModel.wrap(MangaModel(
|
||||
lang: source.lang,
|
||||
link: episode.url,
|
||||
baseUrl: source.baseUrl,
|
||||
source: source.name,
|
||||
apiUrl: source.apiUrl,
|
||||
sourceId: source.id,
|
||||
))
|
||||
];
|
||||
runtime.args = [$MManga.wrap(source.toMManga(link: episode.url!))];
|
||||
var res = await runtime.executeLib(
|
||||
'package:mangayomi/source_code.dart', 'getVideoList');
|
||||
if (res is $List) {
|
||||
|
|
@ -55,7 +46,7 @@ Future<(List<Video>, bool)> getAnimeServers(
|
|||
subtitles = subs.map((e) => Track(e.file, e.label)).toList();
|
||||
} else {
|
||||
try {
|
||||
subtitles = (subs as List<TrackModel>).map((e) {
|
||||
subtitles = (subs as List<MTrack>).map((e) {
|
||||
return Track(e.file, e.label);
|
||||
}).toList();
|
||||
} catch (_) {}
|
||||
|
|
@ -66,7 +57,7 @@ Future<(List<Video>, bool)> getAnimeServers(
|
|||
audios = auds.map((e) => Track(e.file, e.label)).toList();
|
||||
} else {
|
||||
try {
|
||||
audios = (subs as List<TrackModel>).map((e) {
|
||||
audios = (subs as List<MTrack>).map((e) {
|
||||
return Track(e.file, e.label);
|
||||
}).toList();
|
||||
} catch (_) {}
|
||||
|
|
|
|||
|
|
@ -3,8 +3,7 @@ import 'dart:io';
|
|||
import 'dart:typed_data';
|
||||
import 'package:dart_eval/dart_eval_bridge.dart';
|
||||
import 'package:dart_eval/stdlib/core.dart';
|
||||
import 'package:mangayomi/eval/bridge_class/manga_model.dart';
|
||||
import 'package:mangayomi/eval/bridge_class/model.dart';
|
||||
import 'package:mangayomi/eval/bridge/m_manga.dart';
|
||||
import 'package:mangayomi/eval/compiler/compiler.dart';
|
||||
import 'package:mangayomi/main.dart';
|
||||
import 'package:mangayomi/models/chapter.dart';
|
||||
|
|
@ -67,18 +66,9 @@ Future<GetChapterUrlModel> getChapterUrl(
|
|||
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
|
||||
|
||||
final runtime = runtimeEval(bytecode);
|
||||
runtime.args = [
|
||||
$MangaModel.wrap(MangaModel(
|
||||
lang: source.lang,
|
||||
link: chapter.url,
|
||||
baseUrl: source.baseUrl,
|
||||
source: source.name,
|
||||
apiUrl: source.apiUrl,
|
||||
sourceId: source.id,
|
||||
))
|
||||
];
|
||||
runtime.args = [$MManga.wrap(source.toMManga(link: chapter.url!))];
|
||||
var res = await runtime.executeLib(
|
||||
'package:mangayomi/source_code.dart', 'getChapterUrl');
|
||||
'package:mangayomi/source_code.dart', 'getChapterPages');
|
||||
if (res is $List) {
|
||||
for (var element in res.$reified) {
|
||||
if (element is $Value) {
|
||||
|
|
|
|||
|
|
@ -1,45 +1,35 @@
|
|||
import 'dart:async';
|
||||
import 'package:mangayomi/eval/compiler/compiler.dart';
|
||||
import 'package:mangayomi/models/source.dart';
|
||||
import 'package:mangayomi/eval/bridge_class/manga_model.dart';
|
||||
import 'package:mangayomi/eval/bridge_class/model.dart';
|
||||
import 'package:mangayomi/eval/bridge/m_manga.dart';
|
||||
import 'package:mangayomi/eval/model/m_manga.dart';
|
||||
import 'package:mangayomi/eval/runtime/runtime.dart';
|
||||
import 'package:mangayomi/sources/source_test.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
part 'get_latest_updates_manga.g.dart';
|
||||
|
||||
@riverpod
|
||||
Future<List<MangaModel?>> getLatestUpdatesManga(
|
||||
Future<List<MManga?>> getLatestUpdatesManga(
|
||||
GetLatestUpdatesMangaRef ref, {
|
||||
required Source source,
|
||||
required int page,
|
||||
}) async {
|
||||
List<MangaModel?>? latestUpdatesManga = [];
|
||||
final bytecode =
|
||||
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
|
||||
|
||||
final runtime = runtimeEval(bytecode);
|
||||
runtime.args = [
|
||||
$MangaModel.wrap(MangaModel(
|
||||
page: page,
|
||||
lang: source.lang,
|
||||
baseUrl: source.baseUrl,
|
||||
apiUrl: source.apiUrl,
|
||||
sourceId: source.id,
|
||||
source: source.name,
|
||||
dateFormat: source.dateFormat,
|
||||
dateFormatLocale: source.dateFormatLocale))
|
||||
];
|
||||
var res = await runtime.executeLib(
|
||||
'package:mangayomi/source_code.dart',
|
||||
source.isManga! ? 'getLatestUpdatesManga' : 'getLatestUpdatesAnime',
|
||||
);
|
||||
List<MManga?>? latestUpdatesManga = [];
|
||||
try {
|
||||
if (res is $MangaModel) {
|
||||
final bytecode =
|
||||
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
|
||||
|
||||
final runtime = runtimeEval(bytecode);
|
||||
runtime.args = [$MManga.wrap(source.toMManga(page: page))];
|
||||
var res = await runtime.executeLib(
|
||||
'package:mangayomi/source_code.dart',
|
||||
source.isManga! ? 'getLatestUpdatesManga' : 'getLatestUpdatesAnime',
|
||||
);
|
||||
if (res is $MManga) {
|
||||
final value = res.$reified;
|
||||
List<MangaModel> newManga = [];
|
||||
List<MManga> newManga = [];
|
||||
for (var i = 0; i < value.names!.length; i++) {
|
||||
MangaModel newMangaa = MangaModel(
|
||||
MManga newMangaa = MManga(
|
||||
name: value.names![i],
|
||||
link: value.urls![i],
|
||||
imageUrl: value.images!.isEmpty ? "" : value.images![i],
|
||||
|
|
@ -55,7 +45,7 @@ Future<List<MangaModel?>> getLatestUpdatesManga(
|
|||
latestUpdatesManga = newManga;
|
||||
} else {
|
||||
latestUpdatesManga =
|
||||
(res.$reified as List<dynamic>).map((e) => e as MangaModel).toList();
|
||||
(res.$reified as List<dynamic>).map((e) => e as MManga).toList();
|
||||
}
|
||||
} catch (e) {
|
||||
throw Exception(e);
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ const getLatestUpdatesMangaProvider = GetLatestUpdatesMangaFamily();
|
|||
|
||||
/// See also [getLatestUpdatesManga].
|
||||
class GetLatestUpdatesMangaFamily
|
||||
extends Family<AsyncValue<List<MangaModel?>>> {
|
||||
extends Family<AsyncValue<List<MManga?>>> {
|
||||
/// See also [getLatestUpdatesManga].
|
||||
const GetLatestUpdatesMangaFamily();
|
||||
|
||||
|
|
@ -78,7 +78,7 @@ class GetLatestUpdatesMangaFamily
|
|||
|
||||
/// See also [getLatestUpdatesManga].
|
||||
class GetLatestUpdatesMangaProvider
|
||||
extends AutoDisposeFutureProvider<List<MangaModel?>> {
|
||||
extends AutoDisposeFutureProvider<List<MManga?>> {
|
||||
/// See also [getLatestUpdatesManga].
|
||||
GetLatestUpdatesMangaProvider({
|
||||
required Source source,
|
||||
|
|
@ -118,7 +118,7 @@ class GetLatestUpdatesMangaProvider
|
|||
|
||||
@override
|
||||
Override overrideWith(
|
||||
FutureOr<List<MangaModel?>> Function(GetLatestUpdatesMangaRef provider)
|
||||
FutureOr<List<MManga?>> Function(GetLatestUpdatesMangaRef provider)
|
||||
create,
|
||||
) {
|
||||
return ProviderOverride(
|
||||
|
|
@ -137,7 +137,7 @@ class GetLatestUpdatesMangaProvider
|
|||
}
|
||||
|
||||
@override
|
||||
AutoDisposeFutureProviderElement<List<MangaModel?>> createElement() {
|
||||
AutoDisposeFutureProviderElement<List<MManga?>> createElement() {
|
||||
return _GetLatestUpdatesMangaProviderElement(this);
|
||||
}
|
||||
|
||||
|
|
@ -159,7 +159,7 @@ class GetLatestUpdatesMangaProvider
|
|||
}
|
||||
|
||||
mixin GetLatestUpdatesMangaRef
|
||||
on AutoDisposeFutureProviderRef<List<MangaModel?>> {
|
||||
on AutoDisposeFutureProviderRef<List<MManga?>> {
|
||||
/// The parameter `source` of this provider.
|
||||
Source get source;
|
||||
|
||||
|
|
@ -168,7 +168,7 @@ mixin GetLatestUpdatesMangaRef
|
|||
}
|
||||
|
||||
class _GetLatestUpdatesMangaProviderElement
|
||||
extends AutoDisposeFutureProviderElement<List<MangaModel?>>
|
||||
extends AutoDisposeFutureProviderElement<List<MManga?>>
|
||||
with GetLatestUpdatesMangaRef {
|
||||
_GetLatestUpdatesMangaProviderElement(super.provider);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,34 +1,30 @@
|
|||
import 'dart:async';
|
||||
import 'package:mangayomi/eval/compiler/compiler.dart';
|
||||
import 'package:mangayomi/models/source.dart';
|
||||
import 'package:mangayomi/eval/bridge_class/manga_model.dart';
|
||||
import 'package:mangayomi/eval/bridge_class/model.dart';
|
||||
import 'package:mangayomi/eval/bridge/m_manga.dart';
|
||||
import 'package:mangayomi/eval/model/m_manga.dart';
|
||||
import 'package:mangayomi/eval/runtime/runtime.dart';
|
||||
import 'package:mangayomi/sources/source_test.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
part 'get_manga_detail.g.dart';
|
||||
|
||||
@riverpod
|
||||
Future<MangaModel> getMangaDetail(
|
||||
Future<MManga> getMangaDetail(
|
||||
GetMangaDetailRef ref, {
|
||||
required MangaModel manga,
|
||||
required MManga manga,
|
||||
required Source source,
|
||||
}) async {
|
||||
MangaModel? mangadetail;
|
||||
MManga? mangadetail;
|
||||
final bytecode =
|
||||
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
|
||||
|
||||
final runtime = runtimeEval(bytecode);
|
||||
runtime.args = [
|
||||
$MangaModel.wrap(manga
|
||||
..source = source.name
|
||||
..lang = source.lang)
|
||||
];
|
||||
runtime.args = [$MManga.wrap(manga)];
|
||||
|
||||
var result = await runtime.executeLib('package:mangayomi/source_code.dart',
|
||||
source.isManga! ? 'getMangaDetail' : 'getAnimeDetail');
|
||||
try {
|
||||
if (result is $MangaModel) {
|
||||
if (result is $MManga) {
|
||||
final value = result.$reified;
|
||||
mangadetail = value;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,13 +34,13 @@ class _SystemHash {
|
|||
const getMangaDetailProvider = GetMangaDetailFamily();
|
||||
|
||||
/// See also [getMangaDetail].
|
||||
class GetMangaDetailFamily extends Family<AsyncValue<MangaModel>> {
|
||||
class GetMangaDetailFamily extends Family<AsyncValue<MManga>> {
|
||||
/// See also [getMangaDetail].
|
||||
const GetMangaDetailFamily();
|
||||
|
||||
/// See also [getMangaDetail].
|
||||
GetMangaDetailProvider call({
|
||||
required MangaModel manga,
|
||||
required MManga manga,
|
||||
required Source source,
|
||||
}) {
|
||||
return GetMangaDetailProvider(
|
||||
|
|
@ -75,10 +75,10 @@ class GetMangaDetailFamily extends Family<AsyncValue<MangaModel>> {
|
|||
}
|
||||
|
||||
/// See also [getMangaDetail].
|
||||
class GetMangaDetailProvider extends AutoDisposeFutureProvider<MangaModel> {
|
||||
class GetMangaDetailProvider extends AutoDisposeFutureProvider<MManga> {
|
||||
/// See also [getMangaDetail].
|
||||
GetMangaDetailProvider({
|
||||
required MangaModel manga,
|
||||
required MManga manga,
|
||||
required Source source,
|
||||
}) : this._internal(
|
||||
(ref) => getMangaDetail(
|
||||
|
|
@ -110,12 +110,12 @@ class GetMangaDetailProvider extends AutoDisposeFutureProvider<MangaModel> {
|
|||
required this.source,
|
||||
}) : super.internal();
|
||||
|
||||
final MangaModel manga;
|
||||
final MManga manga;
|
||||
final Source source;
|
||||
|
||||
@override
|
||||
Override overrideWith(
|
||||
FutureOr<MangaModel> Function(GetMangaDetailRef provider) create,
|
||||
FutureOr<MManga> Function(GetMangaDetailRef provider) create,
|
||||
) {
|
||||
return ProviderOverride(
|
||||
origin: this,
|
||||
|
|
@ -133,7 +133,7 @@ class GetMangaDetailProvider extends AutoDisposeFutureProvider<MangaModel> {
|
|||
}
|
||||
|
||||
@override
|
||||
AutoDisposeFutureProviderElement<MangaModel> createElement() {
|
||||
AutoDisposeFutureProviderElement<MManga> createElement() {
|
||||
return _GetMangaDetailProviderElement(this);
|
||||
}
|
||||
|
||||
|
|
@ -154,21 +154,21 @@ class GetMangaDetailProvider extends AutoDisposeFutureProvider<MangaModel> {
|
|||
}
|
||||
}
|
||||
|
||||
mixin GetMangaDetailRef on AutoDisposeFutureProviderRef<MangaModel> {
|
||||
mixin GetMangaDetailRef on AutoDisposeFutureProviderRef<MManga> {
|
||||
/// The parameter `manga` of this provider.
|
||||
MangaModel get manga;
|
||||
MManga get manga;
|
||||
|
||||
/// The parameter `source` of this provider.
|
||||
Source get source;
|
||||
}
|
||||
|
||||
class _GetMangaDetailProviderElement
|
||||
extends AutoDisposeFutureProviderElement<MangaModel>
|
||||
extends AutoDisposeFutureProviderElement<MManga>
|
||||
with GetMangaDetailRef {
|
||||
_GetMangaDetailProviderElement(super.provider);
|
||||
|
||||
@override
|
||||
MangaModel get manga => (origin as GetMangaDetailProvider).manga;
|
||||
MManga get manga => (origin as GetMangaDetailProvider).manga;
|
||||
@override
|
||||
Source get source => (origin as GetMangaDetailProvider).source;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,45 +1,35 @@
|
|||
import 'dart:async';
|
||||
import 'package:mangayomi/eval/compiler/compiler.dart';
|
||||
import 'package:mangayomi/models/source.dart';
|
||||
import 'package:mangayomi/eval/bridge_class/manga_model.dart';
|
||||
import 'package:mangayomi/eval/bridge_class/model.dart';
|
||||
import 'package:mangayomi/eval/bridge/m_manga.dart';
|
||||
import 'package:mangayomi/eval/model/m_manga.dart';
|
||||
import 'package:mangayomi/eval/runtime/runtime.dart';
|
||||
import 'package:mangayomi/sources/source_test.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
part 'get_popular_manga.g.dart';
|
||||
|
||||
@riverpod
|
||||
Future<List<MangaModel?>> getPopularManga(
|
||||
Future<List<MManga?>> getPopularManga(
|
||||
GetPopularMangaRef ref, {
|
||||
required Source source,
|
||||
required int page,
|
||||
}) async {
|
||||
List<MangaModel> popularManga = [];
|
||||
List<MManga> popularManga = [];
|
||||
final bytecode =
|
||||
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
|
||||
|
||||
final runtime = runtimeEval(bytecode);
|
||||
runtime.args = [
|
||||
$MangaModel.wrap(MangaModel(
|
||||
page: page,
|
||||
lang: source.lang,
|
||||
baseUrl: source.baseUrl,
|
||||
apiUrl: source.apiUrl,
|
||||
sourceId: source.id,
|
||||
source: source.name,
|
||||
dateFormat: source.dateFormat,
|
||||
dateFormatLocale: source.dateFormatLocale))
|
||||
];
|
||||
runtime.args = [$MManga.wrap(source.toMManga(page: page))];
|
||||
var res = await runtime.executeLib(
|
||||
'package:mangayomi/source_code.dart',
|
||||
source.isManga! ? 'getPopularManga' : 'getPopularAnime',
|
||||
);
|
||||
try {
|
||||
if (res is $MangaModel) {
|
||||
if (res is $MManga) {
|
||||
final value = res.$reified;
|
||||
List<MangaModel> newManga = [];
|
||||
List<MManga> newManga = [];
|
||||
for (var i = 0; i < value.names!.length; i++) {
|
||||
MangaModel newMangaa = MangaModel(
|
||||
MManga newMangaa = MManga(
|
||||
name: value.names![i],
|
||||
link: value.urls![i],
|
||||
imageUrl: value.images!.isEmpty ? "" : value.images![i],
|
||||
|
|
@ -55,7 +45,7 @@ Future<List<MangaModel?>> getPopularManga(
|
|||
popularManga = newManga;
|
||||
} else {
|
||||
popularManga =
|
||||
(res.$reified as List<dynamic>).map((e) => e as MangaModel).toList();
|
||||
(res.$reified as List<dynamic>).map((e) => e as MManga).toList();
|
||||
}
|
||||
} catch (e) {
|
||||
throw Exception(e);
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ class _SystemHash {
|
|||
const getPopularMangaProvider = GetPopularMangaFamily();
|
||||
|
||||
/// See also [getPopularManga].
|
||||
class GetPopularMangaFamily extends Family<AsyncValue<List<MangaModel?>>> {
|
||||
class GetPopularMangaFamily extends Family<AsyncValue<List<MManga?>>> {
|
||||
/// See also [getPopularManga].
|
||||
const GetPopularMangaFamily();
|
||||
|
||||
|
|
@ -76,7 +76,7 @@ class GetPopularMangaFamily extends Family<AsyncValue<List<MangaModel?>>> {
|
|||
|
||||
/// See also [getPopularManga].
|
||||
class GetPopularMangaProvider
|
||||
extends AutoDisposeFutureProvider<List<MangaModel?>> {
|
||||
extends AutoDisposeFutureProvider<List<MManga?>> {
|
||||
/// See also [getPopularManga].
|
||||
GetPopularMangaProvider({
|
||||
required Source source,
|
||||
|
|
@ -116,7 +116,7 @@ class GetPopularMangaProvider
|
|||
|
||||
@override
|
||||
Override overrideWith(
|
||||
FutureOr<List<MangaModel?>> Function(GetPopularMangaRef provider) create,
|
||||
FutureOr<List<MManga?>> Function(GetPopularMangaRef provider) create,
|
||||
) {
|
||||
return ProviderOverride(
|
||||
origin: this,
|
||||
|
|
@ -134,7 +134,7 @@ class GetPopularMangaProvider
|
|||
}
|
||||
|
||||
@override
|
||||
AutoDisposeFutureProviderElement<List<MangaModel?>> createElement() {
|
||||
AutoDisposeFutureProviderElement<List<MManga?>> createElement() {
|
||||
return _GetPopularMangaProviderElement(this);
|
||||
}
|
||||
|
||||
|
|
@ -155,7 +155,7 @@ class GetPopularMangaProvider
|
|||
}
|
||||
}
|
||||
|
||||
mixin GetPopularMangaRef on AutoDisposeFutureProviderRef<List<MangaModel?>> {
|
||||
mixin GetPopularMangaRef on AutoDisposeFutureProviderRef<List<MManga?>> {
|
||||
/// The parameter `source` of this provider.
|
||||
Source get source;
|
||||
|
||||
|
|
@ -164,7 +164,7 @@ mixin GetPopularMangaRef on AutoDisposeFutureProviderRef<List<MangaModel?>> {
|
|||
}
|
||||
|
||||
class _GetPopularMangaProviderElement
|
||||
extends AutoDisposeFutureProviderElement<List<MangaModel?>>
|
||||
extends AutoDisposeFutureProviderElement<List<MManga?>>
|
||||
with GetPopularMangaRef {
|
||||
_GetPopularMangaProviderElement(super.provider);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,46 +1,37 @@
|
|||
import 'package:mangayomi/eval/compiler/compiler.dart';
|
||||
import 'package:mangayomi/models/source.dart';
|
||||
import 'package:mangayomi/eval/bridge_class/manga_model.dart';
|
||||
import 'package:mangayomi/eval/bridge_class/model.dart';
|
||||
import 'package:mangayomi/eval/bridge/m_manga.dart';
|
||||
import 'package:mangayomi/eval/model/m_manga.dart';
|
||||
import 'package:mangayomi/eval/runtime/runtime.dart';
|
||||
import 'package:mangayomi/sources/source_test.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
part 'search_manga.g.dart';
|
||||
|
||||
@riverpod
|
||||
Future<List<MangaModel?>> searchManga(
|
||||
Future<List<MManga?>> searchManga(
|
||||
SearchMangaRef ref, {
|
||||
required Source source,
|
||||
required String query,
|
||||
required int page,
|
||||
}) async {
|
||||
List<MangaModel?>? manga = [];
|
||||
List<MManga?>? manga = [];
|
||||
final bytecode =
|
||||
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
|
||||
|
||||
final runtime = runtimeEval(bytecode);
|
||||
runtime.args = [
|
||||
$MangaModel.wrap(MangaModel(
|
||||
query: query.trim(),
|
||||
lang: source.lang,
|
||||
page: page,
|
||||
baseUrl: source.baseUrl,
|
||||
apiUrl: source.apiUrl,
|
||||
sourceId: source.id,
|
||||
source: source.name,
|
||||
dateFormat: source.dateFormat,
|
||||
dateFormatLocale: source.dateFormatLocale))
|
||||
$MManga.wrap(source.toMManga(query: query.trim(), page: page))
|
||||
];
|
||||
var res = await runtime.executeLib(
|
||||
'package:mangayomi/source_code.dart',
|
||||
source.isManga! ? 'searchManga' : 'searchAnime',
|
||||
);
|
||||
try {
|
||||
if (res is $MangaModel) {
|
||||
if (res is $MManga) {
|
||||
final value = res.$reified;
|
||||
List<MangaModel> newManga = [];
|
||||
List<MManga> newManga = [];
|
||||
for (var i = 0; i < value.names!.length; i++) {
|
||||
MangaModel newMangaa = MangaModel(
|
||||
MManga newMangaa = MManga(
|
||||
name: value.names![i],
|
||||
link: value.urls![i],
|
||||
imageUrl: value.images!.isEmpty ? "" : value.images![i],
|
||||
|
|
@ -55,8 +46,7 @@ Future<List<MangaModel?>> searchManga(
|
|||
}
|
||||
manga = newManga;
|
||||
} else {
|
||||
manga =
|
||||
(res.$reified as List<dynamic>).map((e) => e as MangaModel).toList();
|
||||
manga = (res.$reified as List<dynamic>).map((e) => e as MManga).toList();
|
||||
}
|
||||
} catch (e) {
|
||||
throw Exception(e);
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ class _SystemHash {
|
|||
const searchMangaProvider = SearchMangaFamily();
|
||||
|
||||
/// See also [searchManga].
|
||||
class SearchMangaFamily extends Family<AsyncValue<List<MangaModel?>>> {
|
||||
class SearchMangaFamily extends Family<AsyncValue<List<MManga?>>> {
|
||||
/// See also [searchManga].
|
||||
const SearchMangaFamily();
|
||||
|
||||
|
|
@ -78,7 +78,7 @@ class SearchMangaFamily extends Family<AsyncValue<List<MangaModel?>>> {
|
|||
}
|
||||
|
||||
/// See also [searchManga].
|
||||
class SearchMangaProvider extends AutoDisposeFutureProvider<List<MangaModel?>> {
|
||||
class SearchMangaProvider extends AutoDisposeFutureProvider<List<MManga?>> {
|
||||
/// See also [searchManga].
|
||||
SearchMangaProvider({
|
||||
required Source source,
|
||||
|
|
@ -123,7 +123,7 @@ class SearchMangaProvider extends AutoDisposeFutureProvider<List<MangaModel?>> {
|
|||
|
||||
@override
|
||||
Override overrideWith(
|
||||
FutureOr<List<MangaModel?>> Function(SearchMangaRef provider) create,
|
||||
FutureOr<List<MManga?>> Function(SearchMangaRef provider) create,
|
||||
) {
|
||||
return ProviderOverride(
|
||||
origin: this,
|
||||
|
|
@ -142,7 +142,7 @@ class SearchMangaProvider extends AutoDisposeFutureProvider<List<MangaModel?>> {
|
|||
}
|
||||
|
||||
@override
|
||||
AutoDisposeFutureProviderElement<List<MangaModel?>> createElement() {
|
||||
AutoDisposeFutureProviderElement<List<MManga?>> createElement() {
|
||||
return _SearchMangaProviderElement(this);
|
||||
}
|
||||
|
||||
|
|
@ -165,7 +165,7 @@ class SearchMangaProvider extends AutoDisposeFutureProvider<List<MangaModel?>> {
|
|||
}
|
||||
}
|
||||
|
||||
mixin SearchMangaRef on AutoDisposeFutureProviderRef<List<MangaModel?>> {
|
||||
mixin SearchMangaRef on AutoDisposeFutureProviderRef<List<MManga?>> {
|
||||
/// The parameter `source` of this provider.
|
||||
Source get source;
|
||||
|
||||
|
|
@ -177,7 +177,7 @@ mixin SearchMangaRef on AutoDisposeFutureProviderRef<List<MangaModel?>> {
|
|||
}
|
||||
|
||||
class _SearchMangaProviderElement
|
||||
extends AutoDisposeFutureProviderElement<List<MangaModel?>>
|
||||
extends AutoDisposeFutureProviderElement<List<MManga?>>
|
||||
with SearchMangaRef {
|
||||
_SearchMangaProviderElement(super.provider);
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import 'dart:developer';
|
|||
import 'dart:io';
|
||||
import 'package:flutter_web_auth_2/flutter_web_auth_2.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:mangayomi/eval/m_bridge.dart';
|
||||
import 'package:mangayomi/eval/model/m_bridge.dart';
|
||||
import 'package:mangayomi/main.dart';
|
||||
import 'package:mangayomi/models/track.dart';
|
||||
import 'package:mangayomi/models/track_preference.dart';
|
||||
|
|
|
|||
Loading…
Reference in a new issue