Added JavaScript extension runtime, gridview count

This commit is contained in:
kodjomoustapha 2024-03-12 17:24:41 +01:00
parent 85b3e2ee1f
commit 6fa0e8a89f
111 changed files with 3189 additions and 1049 deletions

View file

@ -3,9 +3,9 @@ import 'package:dart_eval/dart_eval_bridge.dart';
import 'package:dart_eval/stdlib/core.dart';
import 'package:html/dom.dart';
import 'package:mangayomi/eval/bridge/element.dart';
import 'package:mangayomi/eval/model/document.dart';
import 'package:mangayomi/eval/model/element.dart';
import 'package:mangayomi/eval/dart/bridge/element.dart';
import 'package:mangayomi/eval/dart/model/document.dart';
import 'package:mangayomi/eval/dart/model/element.dart';
class $MDocument implements MDocument, $Instance {
$MDocument.wrap(this.$value) : _superclass = $Object($value);
@ -131,6 +131,17 @@ class $MDocument implements MDocument, $Instance {
false)
]),
),
'attr': BridgeMethodDef(
BridgeFunctionDef(
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)),
params: [
BridgeParameter(
'attr',
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string),
nullable: true),
false)
]),
),
},
wrap: true);
@ -182,6 +193,8 @@ class $MDocument implements MDocument, $Instance {
return __xpath;
case 'xpathFirst':
return __xpathFirst;
case 'attr':
return __attr;
default:
return _superclass.$getProperty(runtime, identifier);
}
@ -257,6 +270,13 @@ class $MDocument implements MDocument, $Instance {
return res == null ? const $null() : $String(res);
}
static const $Function __attr = $Function(_attr);
static $Value? _attr(
final Runtime runtime, final $Value? target, final List<$Value?> args) {
final res = (target!.$value as MDocument).attr(args[0]?.$value ?? "");
return res == null ? const $null() : $String(res);
}
@override
List<MElement>? select(String selector) => $value.select(selector);
@ -277,6 +297,9 @@ class $MDocument implements MDocument, $Instance {
List<MElement>? getElementsByTagName(String localNames) =>
$value.getElementsByTagName(localNames);
@override
String? attr(String attr) => $value.attr(attr);
@override
MElement? getElementById(String id) => $value.getElementById(id);

View file

@ -2,7 +2,7 @@ import 'package:dart_eval/dart_eval.dart';
import 'package:dart_eval/dart_eval_bridge.dart';
import 'package:dart_eval/stdlib/core.dart';
import 'package:html/dom.dart';
import 'package:mangayomi/eval/model/element.dart';
import 'package:mangayomi/eval/dart/model/element.dart';
class $MElement implements MElement, $Instance {
$MElement.wrap(this.$value) : _superclass = $Object($value);

View file

@ -1,7 +1,7 @@
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/model/filter.dart';
import 'package:mangayomi/eval/dart/model/filter.dart';
class $FilterList implements FilterList, $Instance {
$FilterList.wrap(this.$value) : _superclass = $Object($value);
@ -71,6 +71,11 @@ class $FilterList implements FilterList, $Instance {
@override
set filters(List<dynamic> filters) {}
@override
Map<String, dynamic> toJson() {
throw UnimplementedError();
}
}
class $SelectFilter implements SelectFilter, $Instance {
@ -113,26 +118,26 @@ class $SelectFilter implements SelectFilter, $Instance {
static $Value? $new(Runtime runtime, $Value? target, List<$Value?> args) {
return $SelectFilter.wrap(SelectFilter(
args[0]!.$value,
args[1]!.$value,
args[2]!.$value,
(args[3]!.$value as List).map((e) {
if (e is $Value) {
final value = e.$reified;
if (value is Map) {
Map<String, dynamic> map = {};
map = value.map((key, value) => MapEntry(key.toString(), value));
if (map['type'] == 'SelectOption') {
final filter = map['filter'] as Map;
return SelectFilterOption.fromJson(
filter.map((key, value) => MapEntry(key.toString(), value)));
args[0]!.$value,
args[1]!.$value,
args[2]!.$value,
(args[3]!.$value as List).map((e) {
if (e is $Value) {
final value = e.$reified;
if (value is Map) {
Map<String, dynamic> map = {};
map = value.map((key, value) => MapEntry(key.toString(), value));
if (map['type'] == 'SelectOption') {
final filter = map['filter'] as Map;
return SelectFilterOption.fromJson(filter
.map((key, value) => MapEntry(key.toString(), value)));
}
}
return value;
}
return value;
}
return e;
}).toList(),
));
return e;
}).toList(),
null));
}
@override
@ -188,6 +193,12 @@ class $SelectFilter implements SelectFilter, $Instance {
@override
int get state => $value.state;
@override
String? get typeName => $value.typeName;
@override
set typeName(String? typeName) {}
@override
List<dynamic> get values => $value.values;
@ -202,6 +213,11 @@ class $SelectFilter implements SelectFilter, $Instance {
@override
set values(List<dynamic> values) {}
@override
Map<String, dynamic> toJson() {
throw UnimplementedError();
}
}
class $SelectFilterOption implements SelectFilterOption, $Instance {
@ -230,7 +246,7 @@ class $SelectFilterOption implements SelectFilterOption, $Instance {
static $Value? $new(Runtime runtime, $Value? target, List<$Value?> args) {
return $SelectFilterOption
.wrap(SelectFilterOption(args[0]!.$value, args[1]!.$value));
.wrap(SelectFilterOption(args[0]!.$value, args[1]!.$value, null));
}
@override
@ -276,11 +292,22 @@ class $SelectFilterOption implements SelectFilterOption, $Instance {
@override
String get name => $value.name;
@override
String? get typeName => $value.typeName;
@override
set typeName(String? typeName) {}
@override
set name(String name) {}
@override
set value(String value) {}
@override
Map<String, dynamic> toJson() {
throw UnimplementedError();
}
}
class $SeparatorFilter implements SeparatorFilter, $Instance {
@ -304,7 +331,8 @@ class $SeparatorFilter implements SeparatorFilter, $Instance {
wrap: true);
static $Value? $new(Runtime runtime, $Value? target, List<$Value?> args) {
return $SeparatorFilter.wrap(SeparatorFilter(type: args[0]?.$value ?? ''));
return $SeparatorFilter
.wrap(SeparatorFilter(null, type: args[0]?.$value ?? ''));
}
@override
@ -342,8 +370,19 @@ class $SeparatorFilter implements SeparatorFilter, $Instance {
@override
String? get type => $value.type ?? '';
@override
String? get typeName => $value.typeName;
@override
set typeName(String? typeName) {}
@override
set type(String? type) {}
@override
Map<String, dynamic> toJson() {
throw UnimplementedError();
}
}
class $HeaderFilter implements HeaderFilter, $Instance {
@ -372,7 +411,7 @@ class $HeaderFilter implements HeaderFilter, $Instance {
static $Value? $new(Runtime runtime, $Value? target, List<$Value?> args) {
return $HeaderFilter
.wrap(HeaderFilter(args[0]!.$value, type: args[1]?.$value ?? ''));
.wrap(HeaderFilter(args[0]!.$value, null, type: args[1]?.$value ?? ''));
}
@override
@ -423,6 +462,17 @@ class $HeaderFilter implements HeaderFilter, $Instance {
@override
String? get type => $value.type ?? '';
@override
String? get typeName => $value.typeName;
@override
set typeName(String? typeName) {}
@override
Map<String, dynamic> toJson() {
throw UnimplementedError();
}
}
class $TextFilter implements TextFilter, $Instance {
@ -450,7 +500,7 @@ class $TextFilter implements TextFilter, $Instance {
wrap: true);
static $Value? $new(Runtime runtime, $Value? target, List<$Value?> args) {
return $TextFilter.wrap(TextFilter(args[0]!.$value, args[1]!.$value));
return $TextFilter.wrap(TextFilter(args[0]!.$value, args[1]!.$value, null));
}
@override
@ -502,6 +552,12 @@ class $TextFilter implements TextFilter, $Instance {
@override
String get state => $value.state;
@override
String? get typeName => $value.typeName;
@override
set typeName(String? typeName) {}
@override
set type(String? type) {}
@ -510,6 +566,11 @@ class $TextFilter implements TextFilter, $Instance {
@override
set state(String state) {}
@override
Map<String, dynamic> toJson() {
throw UnimplementedError();
}
}
class $SortFilter implements SortFilter, $Instance {
@ -550,13 +611,14 @@ class $SortFilter implements SortFilter, $Instance {
static $Value? $new(Runtime runtime, $Value? target, List<$Value?> args) {
return $SortFilter.wrap(SortFilter(
args[0]!.$value,
args[1]!.$value,
args[2]!.$value,
(args[3]!.$value as List)
.map((e) => SelectFilterOption(e.$reified.name, e.$reified.value))
.toList(),
));
args[0]!.$value,
args[1]!.$value,
args[2]!.$value,
(args[3]!.$value as List)
.map((e) =>
SelectFilterOption(e.$reified.name, e.$reified.value, null))
.toList(),
null));
}
@override
@ -615,6 +677,12 @@ class $SortFilter implements SortFilter, $Instance {
@override
List<dynamic> get values => $value.values;
@override
String? get typeName => $value.typeName;
@override
set typeName(String? typeName) {}
@override
set type(String? type) {}
@ -626,6 +694,11 @@ class $SortFilter implements SortFilter, $Instance {
@override
set values(List<dynamic> values) {}
@override
Map<String, dynamic> toJson() {
throw UnimplementedError();
}
}
class $SortState implements SortState, $Instance {
@ -655,7 +728,7 @@ class $SortState implements SortState, $Instance {
wrap: true);
static $Value? $new(Runtime runtime, $Value? target, List<$Value?> args) {
return $SortState.wrap(SortState(args[0]!.$value, args[1]!.$value));
return $SortState.wrap(SortState(args[0]!.$value, args[1]!.$value, null));
}
@override
@ -701,11 +774,22 @@ class $SortState implements SortState, $Instance {
@override
bool get ascending => $value.ascending;
@override
String? get typeName => $value.typeName;
@override
set typeName(String? typeName) {}
@override
set ascending(bool ascending) {}
@override
set index(int index) {}
@override
Map<String, dynamic> toJson() {
throw UnimplementedError();
}
}
class $TriStateFilter implements TriStateFilter, $Instance {
@ -744,7 +828,7 @@ class $TriStateFilter implements TriStateFilter, $Instance {
static $Value? $new(Runtime runtime, $Value? target, List<$Value?> args) {
return $TriStateFilter.wrap(TriStateFilter(
args[2]?.$value ?? '', args[0]!.$value, args[1]!.$value,
args[2]?.$value ?? '', args[0]!.$value, args[1]!.$value, null,
state: args[3]?.$value ?? 0));
}
@ -808,6 +892,12 @@ class $TriStateFilter implements TriStateFilter, $Instance {
@override
String get value => $value.value;
@override
String? get typeName => $value.typeName;
@override
set typeName(String? typeName) {}
@override
set state(int state) {}
@ -816,6 +906,11 @@ class $TriStateFilter implements TriStateFilter, $Instance {
@override
set value(String value) {}
@override
Map<String, dynamic> toJson() {
throw UnimplementedError();
}
}
class $GroupFilter implements GroupFilter, $Instance {
@ -874,7 +969,8 @@ class $GroupFilter implements GroupFilter, $Instance {
return value;
}
return e;
}).toList()));
}).toList(),
null));
}
@override
@ -927,6 +1023,12 @@ class $GroupFilter implements GroupFilter, $Instance {
@override
List<dynamic> get state => $value.state;
@override
String? get typeName => $value.typeName;
@override
set typeName(String? typeName) {}
@override
set type(String? type) {}
@ -935,6 +1037,11 @@ class $GroupFilter implements GroupFilter, $Instance {
@override
set state(List<dynamic> state) {}
@override
Map<String, dynamic> toJson() {
throw UnimplementedError();
}
}
class $CheckBoxFilter implements CheckBoxFilter, $Instance {
@ -973,7 +1080,7 @@ class $CheckBoxFilter implements CheckBoxFilter, $Instance {
static $Value? $new(Runtime runtime, $Value? target, List<$Value?> args) {
return $CheckBoxFilter.wrap(CheckBoxFilter(
args[2]?.$value ?? '', args[0]!.$value, args[1]!.$value,
args[2]?.$value ?? '', args[0]!.$value, args[1]!.$value, null,
state: args[3]?.$value ?? false));
}
@ -1037,6 +1144,12 @@ class $CheckBoxFilter implements CheckBoxFilter, $Instance {
@override
String get value => $value.value;
@override
String? get typeName => $value.typeName;
@override
set typeName(String? typeName) {}
@override
set type(String? type) {}
@ -1045,4 +1158,9 @@ class $CheckBoxFilter implements CheckBoxFilter, $Instance {
@override
set value(String value) {}
@override
Map<String, dynamic> toJson() {
throw UnimplementedError();
}
}

View file

@ -4,8 +4,8 @@ import 'package:dart_eval/dart_eval_bridge.dart';
import 'package:dart_eval/stdlib/core.dart';
import 'package:flutter/foundation.dart';
import 'package:http_interceptor/http_interceptor.dart';
import 'package:mangayomi/eval/bridge/m_source.dart';
import 'package:mangayomi/eval/model/m_bridge.dart';
import 'package:mangayomi/eval/dart/bridge/m_source.dart';
import 'package:mangayomi/eval/dart/model/m_bridge.dart';
import 'package:mangayomi/services/http/interceptor.dart';
/// dart_eval wrapper for [InterceptedClient]

View file

@ -1,7 +1,7 @@
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/model/m_chapter.dart';
import 'package:mangayomi/eval/dart/model/m_chapter.dart';
class $MChapter implements MChapter, $Instance {
$MChapter.wrap(this.$value) : _superclass = $Object($value);

View file

@ -1,10 +1,10 @@
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/m_chapter.dart';
import 'package:mangayomi/eval/bridge/m_status.dart';
import 'package:mangayomi/eval/model/m_chapter.dart';
import 'package:mangayomi/eval/model/m_manga.dart';
import 'package:mangayomi/eval/dart/bridge/m_chapter.dart';
import 'package:mangayomi/eval/dart/bridge/m_status.dart';
import 'package:mangayomi/eval/dart/model/m_chapter.dart';
import 'package:mangayomi/eval/dart/model/m_manga.dart';
import 'package:mangayomi/models/manga.dart';
class $MManga implements MManga, $Instance {

View file

@ -1,9 +1,9 @@
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/m_manga.dart';
import 'package:mangayomi/eval/model/m_manga.dart';
import 'package:mangayomi/eval/model/m_pages.dart';
import 'package:mangayomi/eval/dart/bridge/m_manga.dart';
import 'package:mangayomi/eval/dart/model/m_manga.dart';
import 'package:mangayomi/eval/dart/model/m_pages.dart';
class $MPages implements MPages, $Instance {
$MPages.wrap(this.$value) : _superclass = $Object($value);

View file

@ -2,18 +2,18 @@ import 'dart:convert';
import 'package:dart_eval/dart_eval.dart';
import 'package:dart_eval/dart_eval_bridge.dart';
import 'package:dart_eval/stdlib/core.dart';
import 'package:mangayomi/eval/bridge/document.dart';
import 'package:mangayomi/eval/bridge/filter.dart';
import 'package:mangayomi/eval/bridge/m_manga.dart';
import 'package:mangayomi/eval/bridge/m_pages.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/model/filter.dart';
import 'package:mangayomi/eval/model/m_bridge.dart';
import 'package:mangayomi/eval/model/m_pages.dart';
import 'package:mangayomi/eval/model/m_manga.dart';
import 'package:mangayomi/eval/model/m_provider.dart';
import 'package:mangayomi/eval/dart/bridge/document.dart';
import 'package:mangayomi/eval/dart/bridge/filter.dart';
import 'package:mangayomi/eval/dart/bridge/m_manga.dart';
import 'package:mangayomi/eval/dart/bridge/m_pages.dart';
import 'package:mangayomi/eval/dart/bridge/m_status.dart';
import 'package:mangayomi/eval/dart/bridge/m_track.dart';
import 'package:mangayomi/eval/dart/bridge/m_video.dart';
import 'package:mangayomi/eval/dart/model/filter.dart';
import 'package:mangayomi/eval/dart/model/m_bridge.dart';
import 'package:mangayomi/eval/dart/model/m_pages.dart';
import 'package:mangayomi/eval/dart/model/m_manga.dart';
import 'package:mangayomi/eval/dart/model/m_provider.dart';
import 'package:mangayomi/models/video.dart';
import 'package:mangayomi/modules/browse/extension/providers/extension_preferences_providers.dart';
import 'package:mangayomi/services/boa_js.dart';
@ -1025,8 +1025,8 @@ class $MProvider extends MProvider with $Bridge<MProvider> {
_toValueList(List filters) {
return (filters).map((e) {
if (e is SelectFilter) {
return $SelectFilter.wrap(
SelectFilter(e.type, e.name, e.state, _toValueList(e.values)));
return $SelectFilter.wrap(SelectFilter(
e.type, e.name, e.state, _toValueList(e.values), e.typeName));
} else if (e is TextFilter) {
return $TextFilter.wrap(e);
} else if (e is HeaderFilter) {
@ -1038,8 +1038,8 @@ class $MProvider extends MProvider with $Bridge<MProvider> {
} else if (e is SeparatorFilter) {
return $SeparatorFilter.wrap(e);
} else if (e is SortFilter) {
return $SortFilter
.wrap(SortFilter(e.type, e.name, e.state, _toValueList(e.values)));
return $SortFilter.wrap(SortFilter(
e.type, e.name, e.state, _toValueList(e.values), e.typeName));
} else if (e is SortState) {
return $SortState.wrap(e);
} else if (e is CheckBoxFilter) {
@ -1047,8 +1047,8 @@ class $MProvider extends MProvider with $Bridge<MProvider> {
} else if (e is SelectFilterOption) {
return $SelectFilterOption.wrap(e);
} else if (e is GroupFilter) {
return $GroupFilter
.wrap(GroupFilter(e.type, e.name, _toValueList(e.state)));
return $GroupFilter.wrap(
GroupFilter(e.type, e.name, _toValueList(e.state), e.typeName));
}
return e;
}).toList();

View file

@ -1,7 +1,7 @@
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/model/m_source.dart';
import 'package:mangayomi/eval/dart/model/m_source.dart';
class $MSource implements MSource, $Instance {
$MSource.wrap(this.$value) : _superclass = $Object($value);

View file

@ -76,4 +76,9 @@ class $MTrack implements Track, $Instance {
@override
set label(String? label) {}
@override
Map<String, dynamic> toJson() {
throw UnimplementedError();
}
}

View file

@ -1,7 +1,7 @@
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/m_track.dart';
import 'package:mangayomi/eval/dart/bridge/m_track.dart';
import 'package:mangayomi/models/video.dart';
class $MVideo implements Video, $Instance {
@ -139,4 +139,9 @@ class $MVideo implements Video, $Instance {
@override
set audios(List? audios) {}
@override
Map<String, dynamic> toJson() {
throw UnimplementedError();
}
}

View file

@ -2,7 +2,7 @@ import 'package:dart_eval/dart_eval.dart';
import 'package:dart_eval/dart_eval_bridge.dart';
import 'package:dart_eval/stdlib/core.dart';
import 'package:isar/isar.dart';
import 'package:mangayomi/eval/model/source_preference.dart';
import 'package:mangayomi/eval/dart/model/source_preference.dart';
class $CheckBoxPreference implements SourcePreference, $Instance {
$CheckBoxPreference.wrap(this.$value) : _superclass = $Object($value);

View file

@ -1,6 +1,6 @@
import 'dart:typed_data';
import 'package:dart_eval/dart_eval.dart';
import 'package:mangayomi/eval/plugin.dart';
import 'package:mangayomi/eval/dart/plugin.dart';
Uint8List compilerEval(String code) {
late Compiler compiler = Compiler();

View file

@ -1,5 +1,5 @@
import 'package:html/dom.dart';
import 'package:mangayomi/eval/model/element.dart';
import 'package:mangayomi/eval/dart/model/element.dart';
import 'package:mangayomi/utils/extensions/dom_extensions.dart';
class MDocument {
@ -55,4 +55,8 @@ class MDocument {
MElement? selectFirst(String selector) {
return MElement(_document?.selectFirst(selector));
}
String? attr(String attr) {
return _document?.attr(attr);
}
}

View file

@ -0,0 +1,237 @@
import 'package:mangayomi/eval/javascript/http.dart';
class FilterList {
List<dynamic> filters;
FilterList(this.filters);
factory FilterList.fromJson(Map<String, dynamic> json) {
return FilterList(fromJsonFilterValuestoList(json['filters']));
}
Map<String, dynamic> toJson() => {'filters': filterValuesListToJson(filters)};
}
class SelectFilter {
String? type;
String name;
int state;
List<dynamic> values;
String? typeName;
SelectFilter(this.type, this.name, this.state, this.values, this.typeName);
factory SelectFilter.fromJson(Map<String, dynamic> json) {
return SelectFilter(json['type'], json['name'], json['state'] ?? 0,
fromJsonFilterValuestoList(json['values']), json['type_name']);
}
Map<String, dynamic> toJson() => {
'type': type,
'name': name,
'values': filterValuesListToJson(values),
'type_name': typeName
};
}
class SelectFilterOption {
String name;
String value;
String? typeName;
SelectFilterOption(this.name, this.value, this.typeName);
factory SelectFilterOption.fromJson(Map<String, dynamic> json) {
return SelectFilterOption(json['name'], json['value'], json['type_name']);
}
Map<String, dynamic> toJson() =>
{'value': value, 'name': name, 'type_name': typeName};
}
class SeparatorFilter {
String? type;
String? typeName;
SeparatorFilter(this.typeName, {this.type = ''});
factory SeparatorFilter.fromJson(Map<String, dynamic> json) {
return SeparatorFilter(type: json['type'], json['type_name']);
}
Map<String, dynamic> toJson() => {'type': type, 'type_name': typeName};
}
class HeaderFilter {
String? type;
String name;
String? typeName;
HeaderFilter(this.name, this.typeName, {this.type = ''});
factory HeaderFilter.fromJson(Map<String, dynamic> json) {
return HeaderFilter(json['name'], json['type_name'], type: json['value']);
}
Map<String, dynamic> toJson() =>
{'type': type, 'name': name, 'type_name': typeName};
}
class TextFilter {
String? type;
String name;
String state;
String? typeName;
TextFilter(this.type, this.name, this.typeName, {this.state = ""});
factory TextFilter.fromJson(Map<String, dynamic> json) {
return TextFilter(json['type'], json['name'], json['type_name'],
state: json['state'] ?? "");
}
Map<String, dynamic> toJson() =>
{'type': type, 'name': name, 'state': state, 'type_name': typeName};
}
class SortFilter {
String? type;
String name;
SortState state;
List<dynamic> values;
String? typeName;
SortFilter(this.type, this.name, this.state, this.values, this.typeName);
factory SortFilter.fromJson(Map<String, dynamic> json) {
return SortFilter(
json['type'],
json['name'],
json['state'] == null
? SortState(0, false, "")
: SortState.fromJson(json['state']),
fromJsonFilterValuestoList(json['values']),
json['type_name']);
}
Map<String, dynamic> toJson() => {
'type': type,
'name': name,
'state': state,
'values': filterValuesListToJson(values),
'type_name': typeName
};
}
class SortState {
int index;
bool ascending;
String? typeName;
SortState(this.index, this.ascending, this.typeName);
factory SortState.fromJson(Map<String, dynamic> json) {
return SortState(json['index'], json['ascending'], json['type_name']);
}
Map<String, dynamic> toJson() =>
{'index': index, 'ascending': ascending, 'type_name': typeName};
}
class TriStateFilter {
String? type;
String name;
String value;
int state;
String? typeName;
factory TriStateFilter.fromJson(Map<String, dynamic> json) {
return TriStateFilter(
json['type'], json['name'], json['value'], json['type_name'],
state: json['state'] ?? 0);
}
TriStateFilter(this.type, this.name, this.value, this.typeName,
{this.state = 0});
Map<String, dynamic> toJson() => {
'type': type,
'name': name,
'value': value,
'state': state,
'type_name': typeName
};
}
class GroupFilter {
String? type;
String name;
List<dynamic> state;
String? typeName;
GroupFilter(this.type, this.name, this.state, this.typeName);
factory GroupFilter.fromJson(Map<String, dynamic> json) {
return GroupFilter(json['type'], json['name'],
fromJsonFilterValuestoList(json['state']), json['type_name']);
}
Map<String, dynamic> toJson() => {
'type': type,
'name': name,
'state': filterValuesListToJson(state),
'type_name': typeName
};
}
class CheckBoxFilter {
String? type;
String name;
String value;
bool state;
String? typeName;
CheckBoxFilter(this.type, this.name, this.value, this.typeName,
{this.state = false});
factory CheckBoxFilter.fromJson(Map<String, dynamic> json) {
return CheckBoxFilter(
json['type'], json['name'], json['value'], json['type_name'],
state: json['state'] ?? false);
}
Map<String, dynamic> toJson() => {
'type': type,
'name': name,
'value': value,
'state': state,
'type_name': typeName
};
}
List<dynamic> fromJsonFilterValuestoList(List list) {
return list.map((e) {
final map = (e as Map).toMapStringDynamic!;
if (map['type_name'] == 'TriState') {
return TriStateFilter.fromJson(map.toMapStringDynamic!);
} else if (map['type_name'] == 'CheckBox') {
return CheckBoxFilter.fromJson(map.toMapStringDynamic!);
} else if (map['type_name'] == 'SelectOption') {
return SelectFilterOption.fromJson(map.toMapStringDynamic!);
} else if (map['type_name'] == 'SelectFilter') {
return SelectFilter.fromJson(map.toMapStringDynamic!);
} else if (map['type_name'] == 'SeparatorFilter') {
return SeparatorFilter.fromJson(map.toMapStringDynamic!);
} else if (map['type_name'] == 'HeaderFilter') {
return HeaderFilter.fromJson(map.toMapStringDynamic!);
} else if (map['type_name'] == 'TextFilter') {
return TextFilter.fromJson(map.toMapStringDynamic!);
} else if (map['type_name'] == 'SortFilter') {
return SortFilter.fromJson(map.toMapStringDynamic!);
} else if (map['type_name'] == 'SortState') {
return SortState.fromJson(map.toMapStringDynamic!);
} else if (map['type_name'] == 'GroupFilter') {
return GroupFilter.fromJson(map.toMapStringDynamic!);
}
}).toList();
}
List<Map<String, dynamic>?> filterValuesListToJson(List<dynamic> values) {
return values.map((e) {
if (e is SelectFilter) {
return e.toJson();
} else if (e is SelectFilterOption) {
return e.toJson();
} else if (e is SeparatorFilter) {
return e.toJson();
} else if (e is HeaderFilter) {
return e.toJson();
} else if (e is TextFilter) {
return e.toJson();
} else if (e is SortFilter) {
return e.toJson();
} else if (e is SortState) {
return e.toJson();
} else if (e is TriStateFilter) {
return e.toJson();
} else if (e is GroupFilter) {
return e.toJson();
}
return (e.toJson() as Map<String, dynamic>?);
}).toList();
}

View file

@ -8,7 +8,7 @@ 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/eval/model/document.dart';
import 'package:mangayomi/eval/dart/model/document.dart';
import 'package:mangayomi/models/manga.dart';
import 'package:mangayomi/services/anime_extractors/dood_extractor.dart';
import 'package:mangayomi/services/anime_extractors/filemoon.dart';

View file

@ -0,0 +1,17 @@
class MChapter {
String? name;
String? url;
String? dateUpload;
String? scanlator;
MChapter({this.name, this.url, this.dateUpload, this.scanlator});
factory MChapter.fromJson(Map<String, dynamic> json) {
return MChapter(
name: json['name'],
url: json['url'],
dateUpload: json['dateUpload'],
scanlator: json['scanlator']);
}
}

View file

@ -0,0 +1,50 @@
import 'package:mangayomi/eval/dart/model/m_chapter.dart';
import 'package:mangayomi/models/manga.dart';
class MManga {
String? name;
String? link;
String? imageUrl;
String? description;
String? author;
String? artist;
Status? status;
List<String>? genre;
List<MChapter>? chapters;
MManga(
{this.author,
this.artist,
this.genre,
this.imageUrl,
this.link,
this.name,
this.status = Status.unknown,
this.description,
this.chapters});
factory MManga.fromJson(Map<String, dynamic> json) {
return MManga(
name: json['name'],
link: json['link'],
imageUrl: json['imageUrl'],
description: json['description'],
author: json['author'],
artist: json['artist'],
status: json['status'],
genre: json['genre'] ?? [],
chapters: json['chapters'] != null
? (json['chapters'] as List)
.map((e) => MChapter.fromJson(e))
.toList()
: []);
}
}

View file

@ -0,0 +1,15 @@
import 'package:mangayomi/eval/dart/model/m_manga.dart';
class MPages {
List<MManga> list;
bool hasNextPage;
MPages({required this.list, this.hasNextPage = false});
factory MPages.fromJson(Map<String, dynamic> json) {
return MPages(
list: json['list'] != null
? (json['list'] as List).map((e) => MManga.fromJson(e)).toList()
: [],
hasNextPage: json['hasNextPage']);
}
}

View file

@ -1,6 +1,6 @@
import 'package:mangayomi/eval/model/filter.dart';
import 'package:mangayomi/eval/model/m_pages.dart';
import 'package:mangayomi/eval/model/m_manga.dart';
import 'package:mangayomi/eval/dart/model/filter.dart';
import 'package:mangayomi/eval/dart/model/m_pages.dart';
import 'package:mangayomi/eval/dart/model/m_manga.dart';
import 'package:mangayomi/models/video.dart';
abstract class MProvider {

View file

@ -1,18 +1,18 @@
import 'package:dart_eval/dart_eval.dart';
import 'package:dart_eval/dart_eval_bridge.dart';
import 'package:mangayomi/eval/bridge/document.dart';
import 'package:mangayomi/eval/bridge/element.dart';
import 'package:mangayomi/eval/bridge/http.dart';
import 'package:mangayomi/eval/bridge/m_chapter.dart';
import 'package:mangayomi/eval/bridge/filter.dart';
import 'package:mangayomi/eval/bridge/m_pages.dart';
import 'package:mangayomi/eval/bridge/m_status.dart';
import 'package:mangayomi/eval/bridge/m_provider.dart';
import 'package:mangayomi/eval/bridge/m_manga.dart';
import 'package:mangayomi/eval/bridge/m_source.dart';
import 'package:mangayomi/eval/bridge/m_track.dart';
import 'package:mangayomi/eval/bridge/m_video.dart';
import 'package:mangayomi/eval/bridge/source_preference.dart';
import 'package:mangayomi/eval/dart/bridge/document.dart';
import 'package:mangayomi/eval/dart/bridge/element.dart';
import 'package:mangayomi/eval/dart/bridge/http.dart';
import 'package:mangayomi/eval/dart/bridge/m_chapter.dart';
import 'package:mangayomi/eval/dart/bridge/filter.dart';
import 'package:mangayomi/eval/dart/bridge/m_pages.dart';
import 'package:mangayomi/eval/dart/bridge/m_status.dart';
import 'package:mangayomi/eval/dart/bridge/m_provider.dart';
import 'package:mangayomi/eval/dart/bridge/m_manga.dart';
import 'package:mangayomi/eval/dart/bridge/m_source.dart';
import 'package:mangayomi/eval/dart/bridge/m_track.dart';
import 'package:mangayomi/eval/dart/bridge/m_video.dart';
import 'package:mangayomi/eval/dart/bridge/source_preference.dart';
class MEvalPlugin extends EvalPlugin {
@override

View file

@ -1,6 +1,6 @@
import 'dart:typed_data';
import 'package:dart_eval/dart_eval.dart';
import 'package:mangayomi/eval/plugin.dart';
import 'package:mangayomi/eval/dart/plugin.dart';
Runtime runtimeEval(Uint8List bytecode) {
final runtime = Runtime(bytecode.buffer.asByteData());

View file

@ -0,0 +1,312 @@
import 'dart:convert';
import 'package:flutter_qjs/flutter_qjs.dart';
import 'package:html/dom.dart';
import 'package:html/parser.dart';
import 'package:mangayomi/utils/extensions/dom_extensions.dart';
class JsDomSelector {
late JavascriptRuntime runtime;
JsDomSelector(this.runtime);
init() {
runtime.onMessage('getDocElement', (dynamic args) async {
final input = args[0];
final type = args[1];
final doc = parse(input);
final res = switch (type) {
'body' => doc.body,
'documentElement' => doc.documentElement,
'head' => doc.head,
_ => doc.parent
};
return res?.outerHtml ?? "";
});
runtime.onMessage('getDocumentString', (dynamic args) async {
final input = args[0];
final type = args[1];
final doc = parse(input);
final res = switch (type) { 'text' => doc.text, _ => doc.outerHtml };
return res ?? "";
});
runtime.onMessage('getElementString', (dynamic args) async {
final input = args[0];
final selector = args[1];
final type = args[2];
final element = parse(input).selectFirst(selector);
final res = switch (type) {
'text' => element?.text,
'innerHtml' => element?.innerHtml,
'outerHtml' => element?.outerHtml,
'previousElementSibling' => element?.previousElementSibling?.outerHtml,
'nextElementSibling' => element?.nextElementSibling?.outerHtml,
'className' => element?.className,
'localName' => element?.localName,
'namespaceUri' => element?.namespaceUri,
'getSrc' => element?.getSrc,
'getImg' => element?.getImg,
'getHref' => element?.getHref,
_ => element?.getDataSrc
};
return res ?? "";
});
runtime.onMessage('selectFirst', (dynamic args) async {
final input = args[0];
final selector = args[1];
final element = parse(input).selectFirst(selector);
return element?.outerHtml ?? "";
});
runtime.onMessage('attr', (dynamic args) async {
final input = args[0];
final selector = args[1];
final attr = args[2];
return parse(input).selectFirst(selector)?.attr(attr) ?? "";
});
runtime.onMessage('docAttr', (dynamic args) async {
final input = args[0];
final attr = args[1];
return parse(input).attr(attr) ?? "";
});
runtime.onMessage('xpathFirst', (dynamic args) async {
final input = args[0];
final selector = args[1];
final xpath = args[2];
return parse(input).selectFirst(selector)?.xpathFirst(xpath) ?? "";
});
runtime.onMessage('xpath', (dynamic args) async {
final input = args[0];
final selector = args[1];
final xpath = args[2];
return jsonEncode(parse(input).selectFirst(selector)?.xpath(xpath));
});
runtime.onMessage('docGetElementsListBy', (dynamic args) async {
final input = args[0];
final type = args[1];
final name = args[2];
final doc = parse(input);
final elements = switch (type) {
'children' => doc.children,
'getElementsByTagName' => doc.getElementsByTagName(name),
_ => doc.getElementsByClassName(name)
};
return jsonEncode(elements.map((e) => e.outerHtml).toList());
});
runtime.onMessage('elemGetElementsListBy', (dynamic args) async {
final input = args[0];
final type = args[1];
final name = args[2];
final selector = args[3];
final doc = parse(input).selectFirst(selector);
final elements = switch (type) {
'children' => doc?.children,
'getElementsByTagName' => doc?.getElementsByTagName(name),
_ => doc?.getElementsByClassName(name)
};
return jsonEncode(elements?.map((e) => e.outerHtml).toList());
});
runtime.onMessage('getElementById', (dynamic args) async {
final input = args[0];
final id = args[1];
return parse(input).getElementById(id)?.outerHtml ?? "";
});
runtime.onMessage('select', (dynamic args) async {
final input = args[0];
final selector = args[1];
final listElement = parse(input).select(selector);
final elements = jsonEncode(listElement?.map((e) {
return e.outerHtml;
}).toList());
return elements;
});
runtime.evaluate('''
class Document {
constructor(html) {
this.html = html;
}
async getDocElement(type) {
return JSON.parse(await sendMessage(
"getDocElement",
JSON.stringify([this.html, type]))
);
}
get body() {
return this.getDocElement('body');
}
get documentElement() {
return this.getDocElement('documentElement');
}
get head() {
return this.getDocElement('head');
}
get parent() {
return this.getDocElement('parent');
}
async getDocumentString(type) {
return JSON.parse(await sendMessage(
"getDocumentString",
JSON.stringify([this.html, type]))
);
}
get text() {
return this.getDocumentString('text');
}
get outerHtml() {
return this.getDocumentString('outerHtml');
}
async selectFirst(selector) {
const res = await sendMessage(
"selectFirst",
JSON.stringify([this.html, selector])
);
return new Element(res, selector);
}
async select(selector) {
let htmlList = [];
JSON.parse(
await sendMessage("select", JSON.stringify([this.html, selector]))
).forEach((e) => {
htmlList.push(e);
});
return htmlList;
}
async xpathFirst(xpath) {
return await sendMessage(
"xpathFirst",
JSON.stringify([this.html, xpath])
);
}
async xpath(xpath) {
return JSON.parse(await sendMessage(
"xpath",
JSON.stringify([this.html, xpath]))
);
}
async docGetElementsListBy(type, name) {
name = name || '';
return JSON.parse(await sendMessage(
"docGetElementsListBy",
JSON.stringify([this.html, type, name]))
);
}
get children() {
return this.docGetElementsListBy('children');
}
async getElementsByTagName(name) {
return this.docGetElementsListBy('getElementsByTagName', name);
}
async getElementsByClassName(name) {
return this.docGetElementsListBy('getElementsByClassName', name);
}
async getElementById(id) {
return await sendMessage(
"getElementById",
JSON.stringify([(await this.parse()).outerHtml, id])
);
}
async attr(attr) {
return await sendMessage(
"docAttr",
JSON.stringify([this.res.html, this.res.selector, attr])
);
}
}
class Element {
constructor(html, selector) {
this.html = html;
this.selector = selector;
}
async getElementString(type) {
return await sendMessage(
"getElementString",
JSON.stringify([this.html, this.selector, type])
);
}
get text() {
return this.getElementString("text");
}
get outerHtml() {
return this.getElementString("outerHtml");
}
get innerHtml() {
return this.getElementString("innerHtml");
}
get className() {
return this.getElementString("className");
}
get localName() {
return this.getElementString("localName");
}
get namespaceUri() {
return this.getElementString("namespaceUri");
}
get getSrc() {
return this.getElementString("getSrc");
}
get getImg() {
return this.getElementString("getImg");
}
get getHref() {
return this.getElementString("getHref");
}
get getDataSrc() {
return this.getElementString("getDataSrc");
}
get previousElementSibling() {
return this.getElementString("previousElementSibling");
}
get nextElementSibling() {
return this.getElementString("nextElementSibling");
}
async elemGetElementsListBy(type, name) {
name = name || '';
return JSON.parse(await sendMessage(
"elemGetElementsListBy",
JSON.stringify([this.html, type, name]))
);
}
get children() {
return this.elemGetElementsListBy('children');
}
async getElementsByTagName(name) {
return this.elemGetElementsListBy('getElementsByTagName', name);
}
async getElementsByClassName(name) {
return this.elemGetElementsListBy('getElementsByClassName', name);
}
async xpath(xpath) {
return JSON.parse(await sendMessage(
"xpath",
JSON.stringify([this.html, xpath]))
);
}
async attr(attr) {
return await sendMessage(
"attr",
JSON.stringify([this.html, this.selector, attr])
);
}
async xpathFirst(xpath) {
return await sendMessage(
"xpathFirst",
JSON.stringify([this.html, xpath])
);
}
}
''');
}
}
extension ElementExtexsion on Element? {
Map<String, dynamic> toJson() => {
'text': this?.text,
'className': this?.className,
'localName': this?.localName,
'namespaceUri': this?.namespaceUri,
'getSrc': this?.getSrc,
'getImg': this?.getImg,
'getHref': this?.getHref,
'getDataSrc': this?.getDataSrc,
};
}

View file

@ -0,0 +1,172 @@
import 'dart:convert';
import 'package:flutter_qjs/flutter_qjs.dart';
import 'package:mangayomi/eval/dart/model/m_bridge.dart';
import 'package:mangayomi/models/video.dart';
class JsVideosExtractors {
late JavascriptRuntime runtime;
JsVideosExtractors(this.runtime);
init() {
runtime.onMessage('sibnetExtractor', (dynamic args) async {
return (await MBridge.sibnetExtractor(args[0], args[1] ?? ""))
.encodeToJson();
});
runtime.onMessage('myTvExtractor', (dynamic args) async {
return (await MBridge.myTvExtractor(args[0])).encodeToJson();
});
runtime.onMessage('okruExtractor', (dynamic args) async {
return (await MBridge.okruExtractor(args[0])).encodeToJson();
});
runtime.onMessage('voeExtractor', (dynamic args) async {
return (await MBridge.voeExtractor(args[0], args[1])).encodeToJson();
});
runtime.onMessage('vidBomExtractor', (dynamic args) async {
return (await MBridge.vidBomExtractor(args[0])).encodeToJson();
});
runtime.onMessage('streamlareExtractor', (dynamic args) async {
return (await MBridge.streamlareExtractor(args[0], args[1], args[2]))
.encodeToJson();
});
runtime.onMessage('sendVidExtractor', (dynamic args) async {
return (await MBridge.sendVidExtractor(args[0], args[1], args[2] ?? ""))
.encodeToJson();
});
runtime.onMessage('yourUploadExtractor', (dynamic args) async {
return (await MBridge.yourUploadExtractor(
args[0], args[1], args[2], args[3] ?? ""))
.encodeToJson();
});
runtime.onMessage('gogoCdnExtractor', (dynamic args) async {
return (await MBridge.gogoCdnExtractor(args[0])).encodeToJson();
});
runtime.onMessage('doodExtractor', (dynamic args) async {
return (await MBridge.doodExtractor(args[0], args[1])).encodeToJson();
});
runtime.onMessage('streamTapeExtractor', (dynamic args) async {
return (await MBridge.streamTapeExtractor(args[0], args[1]))
.encodeToJson();
});
runtime.onMessage('mp4UploadExtractor', (dynamic args) async {
return (await MBridge.mp4UploadExtractor(
args[0], args[1], args[2], args[3] ?? ""))
.encodeToJson();
});
runtime.onMessage('streamWishExtractor', (dynamic args) async {
return (await MBridge.streamWishExtractor(args[0], args[1] ?? ""))
.encodeToJson();
});
runtime.onMessage('filemoonExtractor', (dynamic args) async {
return (await MBridge.filemoonExtractor(
args[0], args[1] ?? "", args[2] ?? ""))
.encodeToJson();
});
runtime.evaluate('''
async function sibnetExtractor(url, prefix) {
const result = await sendMessage(
"sibnetExtractor",
JSON.stringify([url, prefix])
);
return JSON.parse(result);
}
async function myTvExtractor(url) {
const result = await sendMessage(
"myTvExtractor",
JSON.stringify([url])
);
return JSON.parse(result);
}
async function okruExtractor(url) {
const result = await sendMessage(
"okruExtractor",
JSON.stringify([url])
);
return JSON.parse(result);
}
async function voeExtractor(url, quality) {
const result = await sendMessage(
"voeExtractor",
JSON.stringify([url, quality])
);
return JSON.parse(result);
}
async function vidBomExtractor(url) {
const result = await sendMessage(
"vidBomExtractor",
JSON.stringify([url])
);
return JSON.parse(result);
}
async function streamlareExtractor(url, prefix, suffix) {
const result = await sendMessage(
"streamlareExtractor",
JSON.stringify([url, prefix, suffix])
);
return JSON.parse(result);
}
async function sendVidExtractor(url, headers, prefix) {
const result = await sendMessage(
"sendVidExtractor",
JSON.stringify([url, JSON.stringify(headers), prefix])
);
return JSON.parse(result);
}
async function yourUploadExtractor(url, headers, name, prefix) {
const result = await sendMessage(
"yourUploadExtractor",
JSON.stringify([url, JSON.stringify(headers), name, prefix])
);
return JSON.parse(result);
}
async function gogoCdnExtractor(url) {
const result = await sendMessage(
"gogoCdnExtractor",
JSON.stringify([url])
);
return JSON.parse(result);
}
async function doodExtractor(url, quality) {
const result = await sendMessage(
"doodExtractor",
JSON.stringify([url, quality])
);
return JSON.parse(result);
}
async function streamTapeExtractor(url, quality) {
const result = await sendMessage(
"streamTapeExtractor",
JSON.stringify([url, quality])
);
return JSON.parse(result);
}
async function mp4UploadExtractor(url, headers, prefix, suffix) {
const result = await sendMessage(
"mp4UploadExtractor",
JSON.stringify([url, JSON.stringify(headers), prefix, suffix])
);
return JSON.parse(result);
}
async function streamWishExtractor(url, prefix) {
const result = await sendMessage(
"streamWishExtractor",
JSON.stringify([url, prefix])
);
return JSON.parse(result);
}
async function filemoonExtractor(url, prefix, suffix) {
const result = await sendMessage(
"filemoonExtractor",
JSON.stringify([url, prefix, suffix])
);
return JSON.parse(result);
}
''');
}
}
extension ResponseExtexsion on List<Video> {
String encodeToJson() {
return jsonEncode(map((e) => e.toJson()).toList());
}
}

View file

@ -0,0 +1,134 @@
import 'dart:convert';
import 'package:flutter_qjs/flutter_qjs.dart';
import 'package:http_interceptor/http_interceptor.dart';
import 'package:mangayomi/services/http/interceptor.dart';
class JsHttpClient {
late JavascriptRuntime runtime;
JsHttpClient(this.runtime);
init() {
runtime.onMessage('http_get', (dynamic args) async {
return jsonEncode((await MInterceptor.init(
source: null,
reqcopyWith: (args[1] as Map?)?.toMapStringDynamic)
.get(Uri.parse(args[2]),
headers: (args[3] as Map?)?.toMapStringString))
.toJson());
});
runtime.onMessage('http_post', (dynamic args) async {
return jsonEncode((await MInterceptor.init(
source: null,
reqcopyWith: (args[1] as Map?)?.toMapStringDynamic)
.post(Uri.parse(args[2]),
headers: (args[3] as Map?)?.toMapStringString, body: args[4]))
.toJson());
});
runtime.onMessage('http_put', (dynamic args) async {
return (await MInterceptor.init(
source: null,
reqcopyWith: (args[1] as Map?)?.toMapStringDynamic)
.put(Uri.parse(args[2]),
headers: (args[3] as Map?)?.toMapStringString, body: args[4]))
.toJson();
});
runtime.onMessage('http_delete', (dynamic args) async {
return jsonEncode((await MInterceptor.init(
source: null,
reqcopyWith: (args[1] as Map?)?.map(
(key, value) => MapEntry(key.toString(), value))).delete(
Uri.parse(args[0]),
headers: (args[1] as Map?)?.map(
(key, value) => MapEntry(key.toString(), value.toString())),
body: args[2]))
.toJson());
});
runtime.onMessage('http_patch', (dynamic args) async {
return jsonEncode((await MInterceptor.init(
source: null,
reqcopyWith: (args[1] as Map?)?.toMapStringDynamic)
.patch(Uri.parse(args[2]),
headers: (args[3] as Map?)?.toMapStringString, body: args[4]))
.toJson());
});
runtime.evaluate('''
class Client {
constructor(reqcopyWith) {
this.reqcopyWith = reqcopyWith;
}
async get(url, headers) {
headers = headers;
const result = await sendMessage(
"http_get",
JSON.stringify([null, this.reqcopyWith, url, headers])
);
return JSON.parse(result);
}
async post(url, headers, body) {
headers = headers;
const result = await sendMessage(
"http_post",
JSON.stringify([null, this.reqcopyWith, url, headers, body])
);
return JSON.parse(result);
}
async put(url, headers, body) {
headers = headers;
const result = await sendMessage(
"http_post",
JSON.stringify([null, this.reqcopyWith, url, headers, body])
);
return JSON.parse(result);
}
async delete(url, headers, body) {
headers = headers;
const result = await sendMessage(
"http_post",
JSON.stringify([null, this.reqcopyWith, url, headers, body])
);
return JSON.parse(result);
}
async patch(url, headers, body) {
headers = headers;
const result = await sendMessage(
"http_post",
JSON.stringify([null, this.reqcopyWith, url, headers, body])
);
return JSON.parse(result);
}
}
''');
}
}
extension ResponseExtexsion on Response {
Map<String, dynamic> toJson() => {
'body': body,
'headers': headers,
'isRedirect': isRedirect,
'persistentConnection': persistentConnection,
'reasonPhrase': reasonPhrase,
'statusCode': statusCode,
'request': {
'contentLength': request?.contentLength,
'finalized': request?.finalized,
'followRedirects': request?.followRedirects,
'headers': request?.headers,
'maxRedirects': request?.maxRedirects,
'method': request?.method,
'persistentConnection': request?.persistentConnection,
'url': request?.url.toString()
}
};
}
extension ToMapExtension on Map? {
Map<String, dynamic>? get toMapStringDynamic {
return this?.map((key, value) => MapEntry(key.toString(), value));
}
Map<String, String>? get toMapStringString {
return this
?.map((key, value) => MapEntry(key.toString(), value.toString()));
}
}

View file

@ -0,0 +1,45 @@
import 'package:flutter_qjs/flutter_qjs.dart';
import 'package:mangayomi/models/source.dart';
import 'package:mangayomi/modules/browse/extension/providers/extension_preferences_providers.dart';
class JsPreferences {
late JavascriptRuntime runtime;
late Source? source;
JsPreferences(this.runtime, this.source);
init() {
runtime.onMessage('getPreferenceValue', (dynamic args) async {
return await getPreferenceValueAsync(source!.id!, args[0]);
});
runtime.onMessage('getPrefStringValue', (dynamic args) async {
return getSourcePreferenceStringValue(source!.id!, args[0], args[1]);
});
runtime.onMessage('setPrefStringValue', (dynamic args) async {
return setSourcePreferenceStringValue(source!.id!, args[0], args[1]);
});
runtime.evaluate('''
async function getPreferenceValue(key) {
const result = await sendMessage(
"getPreferenceValue",
JSON.stringify([key])
);
return result;
}
async function getPrefStringValue(key,defaultValue) {
const result = await sendMessage(
"getPrefStringValue",
JSON.stringify([key,defaultValue])
);
return result;
}
async function setPrefStringValue(key,defaultValue) {
const result = await sendMessage(
"setPrefStringValue",
JSON.stringify([key,defaultValue])
);
return result;
}
''');
}
}

View file

@ -0,0 +1,141 @@
import 'dart:convert';
import 'package:flutter_qjs/flutter_qjs.dart';
import 'package:mangayomi/eval/javascript/dom_selector.dart';
import 'package:mangayomi/eval/javascript/extractors.dart';
import 'package:mangayomi/eval/javascript/http.dart';
import 'package:mangayomi/eval/javascript/preferences.dart';
import 'package:mangayomi/eval/javascript/utils.dart';
import 'package:mangayomi/eval/dart/model/filter.dart';
import 'package:mangayomi/eval/dart/model/m_manga.dart';
import 'package:mangayomi/eval/dart/model/m_pages.dart';
import 'package:mangayomi/eval/dart/model/source_preference.dart';
import 'package:mangayomi/models/source.dart';
import 'package:mangayomi/models/video.dart';
class JsExtensionService {
late JavascriptRuntime runtime;
late Source? source;
JsExtensionService(this.source);
void _init() {
runtime = getJavascriptRuntime(xhr: false);
JsHttpClient(runtime).init();
JsDomSelector(runtime).init();
JsVideosExtractors(runtime).init();
JsUtils(runtime).init();
JsPreferences(runtime, source).init();
runtime.evaluate(r'''
class MProvider {
async getPopular(page) {
throw new Error("getPopular not implemented");
}
async getLatestUpdates(page) {
throw new Error("getLatestUpdates not implemented");
}
async search(query, page, filters) {
throw new Error("search not implemented");
}
async getDetail(url) {
throw new Error("getDetail not implemented");
}
async getPageList() {
throw new Error("getPageList not implemented");
}
async getVideoList(url) {
throw new Error("getVideoList not implemented");
}
getFilterList() {
throw new Error("getFilterList not implemented");
}
getSourcePreferences() {
throw new Error("getSourcePreferences not implemented");
}
}
''');
runtime.evaluate('''${source!.sourceCode}
var extention = new DefaultExtension();
''');
}
Future<MPages> getPopular(int page) async {
_init();
final res = (await runtime.handlePromise(
await runtime.evaluateAsync('extention.getPopular($page)')))
.stringResult;
return MPages.fromJson(jsonDecode(res));
}
Future<MPages> getLatestUpdates(int page) async {
_init();
final res = (await runtime.handlePromise(
await runtime.evaluateAsync('extention.getLatestUpdates($page)')))
.stringResult;
return MPages.fromJson(jsonDecode(res));
}
Future<MPages> search(String query, int page, String filters) async {
_init();
final res = (await runtime.handlePromise(await runtime
.evaluateAsync('extention.search("$query",$page,$filters)')))
.stringResult;
return MPages.fromJson(jsonDecode(res));
}
Future<MManga> getDetail(String url) async {
_init();
final res = (await runtime.handlePromise(
await runtime.evaluateAsync('extention.getDetail("$url")')))
.stringResult;
return MManga.fromJson(jsonDecode(res));
}
Future<List<String>> getPageList(String url) async {
_init();
final res = (await runtime.handlePromise(
await runtime.evaluateAsync('extention.getPageList("$url")')))
.stringResult;
return jsonDecode(res);
}
Future<List<Video>> getVideoList(String url) async {
_init();
final res = (await runtime.handlePromise(
await runtime.evaluateAsync('extention.getVideoList("$url")')))
.stringResult;
return (jsonDecode(res) as List).map((e) => Video.fromJson(e)).toList();
}
Future<dynamic> getFilterList() async {
_init();
try {
final res = (await runtime.handlePromise(
await runtime.evaluateAsync('extention.getFilterList()')))
.stringResult;
return FilterList(fromJsonFilterValuestoList(jsonDecode(res))).filters;
} catch (_) {
return [];
}
}
Future<List<SourcePreference>> getSourcePreferences() async {
_init();
try {
final res = (await runtime.handlePromise(
await runtime.evaluateAsync('extention.getSourcePreferences()')))
.stringResult;
return (jsonDecode(res) as List)
.map((e) => SourcePreference.fromJson(e))
.toList();
} catch (_) {
return [];
}
}
}

View file

@ -0,0 +1,86 @@
import 'dart:convert';
import 'package:flutter_qjs/flutter_qjs.dart';
import 'package:js_packer/js_packer.dart';
import 'package:mangayomi/eval/dart/model/m_bridge.dart';
import 'package:mangayomi/utils/cryptoaes/js_unpacker.dart';
class JsUtils {
late JavascriptRuntime runtime;
JsUtils(this.runtime);
init() {
runtime.onMessage('cryptoHandler', (dynamic args) async {
return MBridge.cryptoHandler(args[0], args[1], args[2], args[3]);
});
runtime.onMessage('encryptAESCryptoJS', (dynamic args) async {
return MBridge.encryptAESCryptoJS(args[0], args[1]);
});
runtime.onMessage('decryptAESCryptoJS', (dynamic args) async {
return MBridge.decryptAESCryptoJS(args[0], args[1]);
});
runtime.onMessage('deobfuscateJsPassword', (dynamic args) async {
return MBridge.deobfuscateJsPassword(args[0]);
});
runtime.onMessage('unpackJsAndCombine', (dynamic args) async {
return JsUnpacker.unpackAndCombine(args[0]) ?? "";
});
runtime.onMessage('unpackJs', (dynamic args) async {
return JSPacker(args[0]).unpack() ?? "";
});
runtime.onMessage('parseDates', (dynamic args) async {
return jsonEncode(MBridge.parseDates(args[0], args[1], args[2]));
});
runtime.evaluate('''
async function cryptoHandler(text, iv, secretKeyString, encrypt) {
const result = await sendMessage(
"cryptoHandler",
JSON.stringify([text, iv, secretKeyString, encrypt])
);
return JSON.parse(result);
}
async function encryptAESCryptoJS(plainText, passphrase) {
const result = await sendMessage(
"encryptAESCryptoJS",
JSON.stringify([plainText, passphrase])
);
return JSON.parse(result);
}
async function decryptAESCryptoJS(encrypted, passphrase) {
const result = await sendMessage(
"decryptAESCryptoJS",
JSON.stringify([encrypted, passphrase])
);
return JSON.parse(result);
}
async function deobfuscateJsPassword(inputString) {
const result = await sendMessage(
"deobfuscateJsPassword",
JSON.stringify([inputString])
);
return JSON.parse(result);
}
async function unpackJsAndCombine(scriptBlock) {
const result = await sendMessage(
"unpackJsAndCombine",
JSON.stringify([scriptBlock])
);
return JSON.parse(result);
}
async function unpackJs(packedJS) {
const result = await sendMessage(
"unpackJs",
JSON.stringify([packedJS])
);
return JSON.parse(result);
}
async function parseDates(value, dateFormat, dateFormatLocale) {
const result = await sendMessage(
"parseDates",
JSON.stringify([value, dateFormat, dateFormatLocale])
);
return JSON.parse(result);
}
''');
}
}

View file

@ -1,93 +0,0 @@
class FilterList {
List<dynamic> filters;
FilterList(this.filters);
}
class SelectFilter {
String? type;
String name;
int state;
List<dynamic> values;
SelectFilter(this.type, this.name, this.state, this.values);
}
class SelectFilterOption {
String name;
String value;
SelectFilterOption(this.name, this.value);
factory SelectFilterOption.fromJson(Map<String, dynamic> json) {
return SelectFilterOption(json['name'], json['value']);
}
}
class SeparatorFilter {
String? type;
SeparatorFilter({this.type = ''});
}
class HeaderFilter {
String? type;
String name;
HeaderFilter(this.name, {this.type = ''});
}
class TextFilter {
String? type;
String name;
String state;
TextFilter(this.type, this.name, {this.state = ""});
}
class SortFilter {
String? type;
String name;
SortState state;
List<dynamic> values;
SortFilter(this.type, this.name, this.state, this.values);
}
class SortState {
int index;
bool ascending;
SortState(this.index, this.ascending);
}
class TriStateFilter {
String? type;
String name;
String value;
int state;
factory TriStateFilter.fromJson(Map<String, dynamic> json) {
return TriStateFilter(json['type'], json['name'], json['value'],
state: json['state'] ?? 0);
}
TriStateFilter(this.type, this.name, this.value, {this.state = 0});
}
class GroupFilter {
String? type;
String name;
List<dynamic> state;
GroupFilter(this.type, this.name, this.state);
}
class CheckBoxFilter {
String? type;
String name;
String value;
bool state;
factory CheckBoxFilter.fromJson(Map<String, dynamic> json) {
return CheckBoxFilter(json['type'], json['name'], json['value'],
state: json['state'] ?? false);
}
CheckBoxFilter(this.type, this.name, this.value, {this.state = false});
}

View file

@ -1,10 +0,0 @@
class MChapter {
String? name;
String? url;
String? dateUpload;
String? scanlator;
MChapter({this.name, this.url, this.dateUpload, this.scanlator});
}

View file

@ -1,33 +0,0 @@
import 'package:mangayomi/eval/model/m_chapter.dart';
import 'package:mangayomi/models/manga.dart';
class MManga {
String? name;
String? link;
String? imageUrl;
String? description;
String? author;
String? artist;
Status? status;
List<String>? genre;
List<MChapter>? chapters;
MManga(
{this.author,
this.artist,
this.genre,
this.imageUrl,
this.link,
this.name,
this.status = Status.unknown,
this.description,
this.chapters});
}

View file

@ -1,7 +0,0 @@
import 'package:mangayomi/eval/model/m_manga.dart';
class MPages {
List<MManga> list;
bool hasNextPage;
MPages({required this.list, this.hasNextPage = false});
}

View file

@ -317,5 +317,7 @@
"text": "النص",
"border": "الحدود",
"background": "الخلفية",
"no_subtite_warning_message": "لا تؤثر لأنه لا توجد مسارات ترجمة في هذا الفيديو"
"no_subtite_warning_message": "لا تؤثر لأنه لا توجد مسارات ترجمة في هذا الفيديو",
"grid_size": "حجم الشبكة",
"n_per_row": "{n} في الصف الواحد"
}

View file

@ -317,5 +317,7 @@
"text": "Text",
"border": "Rand",
"background": "Hintergrund",
"no_subtite_warning_message": "Hat keine Wirkung, da in diesem Video keine Untertitelspuren vorhanden sind"
"no_subtite_warning_message": "Hat keine Wirkung, da in diesem Video keine Untertitelspuren vorhanden sind",
"grid_size": "Rastergröße",
"n_per_row": "{n} pro Zeile"
}

View file

@ -319,5 +319,7 @@
"text": "Text",
"border": "Border",
"background": "Background",
"no_subtite_warning_message": "Has no effect because there aren't any subtitle tracks in this video"
"no_subtite_warning_message": "Has no effect because there aren't any subtitle tracks in this video",
"grid_size": "Grid size",
"n_per_row": "{n} per row"
}

View file

@ -317,5 +317,7 @@
"text": "Texto",
"border": "Borde",
"background": "Fondo",
"no_subtite_warning_message": "No tiene efecto porque no hay pistas de subtítulos en este vídeo"
"no_subtite_warning_message": "No tiene efecto porque no hay pistas de subtítulos en este vídeo",
"grid_size": "Tamaño de la cuadrícula",
"n_per_row": "{n} por fila"
}

View file

@ -317,5 +317,7 @@
"text": "Texto",
"border": "Borde",
"background": "Fondo",
"no_subtite_warning_message": "No tiene efecto porque no hay pistas de subtítulos en este video"
"no_subtite_warning_message": "No tiene efecto porque no hay pistas de subtítulos en este video",
"grid_size": "Tamaño de la cuadrícula",
"n_per_row": "{n} por fila"
}

View file

@ -318,5 +318,7 @@
"text": "Texte",
"border": "Bordure",
"background": "Arrière-plan",
"no_subtite_warning_message": "N'a aucun effet car il n'y a pas de pistes de sous-titres dans cette vidéo"
"no_subtite_warning_message": "N'a aucun effet car il n'y a pas de pistes de sous-titres dans cette vidéo",
"grid_size": "Taille de la grille",
"n_per_row": "{n} par ligne"
}

View file

@ -317,5 +317,7 @@
"text": "Teks",
"border": "Batas",
"background": "Latar Belakang",
"no_subtite_warning_message": "Tidak berpengaruh karena tidak ada trek subtitle dalam video ini"
"no_subtite_warning_message": "Tidak berpengaruh karena tidak ada trek subtitle dalam video ini",
"grid_size": "Ukuran Grid",
"n_per_row": "{n} per baris"
}

View file

@ -317,5 +317,7 @@
"text": "Testo",
"border": "Bordo",
"background": "Sfondo",
"no_subtite_warning_message": "Non ha effetto perché non ci sono tracce sottotitoli in questo video"
"no_subtite_warning_message": "Non ha effetto perché non ci sono tracce sottotitoli in questo video",
"grid_size": "Dimensione griglia",
"n_per_row": "{n} per riga"
}

View file

@ -317,5 +317,7 @@
"text": "Texto",
"border": "Borda",
"background": "Fundo",
"no_subtite_warning_message": "Não tem efeito porque não há faixas de legendas neste vídeo"
"no_subtite_warning_message": "Não tem efeito porque não há faixas de legendas neste vídeo",
"grid_size": "Tamanho da grade",
"n_per_row": "{n} por linha"
}

View file

@ -317,5 +317,7 @@
"text": "Texto",
"border": "Borda",
"background": "Fundo",
"no_subtite_warning_message": "Não tem efeito porque não há faixas de legenda neste vídeo"
"no_subtite_warning_message": "Não tem efeito porque não há faixas de legenda neste vídeo",
"grid_size": "Tamanho da grade",
"n_per_row": "{n} por linha"
}

View file

@ -317,5 +317,7 @@
"text": "Текст",
"border": "Граница",
"background": "Фон",
"no_subtite_warning_message": "Не имеет эффекта, потому что в этом видео нет субтитров"
"no_subtite_warning_message": "Не имеет эффекта, потому что в этом видео нет субтитров",
"grid_size": "Размер сетки",
"n_per_row": "{n} в ряд"
}

View file

@ -317,5 +317,7 @@
"text": "Metin",
"border": "Kenarlık",
"background": "Arka Plan",
"no_subtite_warning_message": "Bu videoda altyazı parçaları olmadığı için etkisi yok"
"no_subtite_warning_message": "Bu videoda altyazı parçaları olmadığı için etkisi yok",
"grid_size": "Kılavuz Boyutu",
"n_per_row": "{n} satır başına"
}

View file

@ -319,5 +319,7 @@
"text": "文本",
"border": "边框",
"background": "背景",
"no_subtite_warning_message": "由于此视频中没有字幕轨道,因此无效。"
"no_subtite_warning_message": "由于此视频中没有字幕轨道,因此无效。",
"grid_size": "网格大小",
"n_per_row": "{n} 每行"
}

View file

@ -179,6 +179,10 @@ class Settings {
String? appFontFamily;
int? mangaGridSize;
int? animeGridSize;
Settings(
{this.id = 227,
this.displayType = DisplayType.compactGrid,
@ -257,7 +261,9 @@ class Settings {
this.colorFilterBlendMode = ColorFilterBlendMode.none,
this.playerSubtitleSettings,
this.mangaHomeDisplayType = DisplayType.comfortableGrid,
this.appFontFamily});
this.appFontFamily,
this.mangaGridSize,
this.animeGridSize});
Settings.fromJson(Map<String, dynamic> json) {
animatePageTransitions = json['animatePageTransitions'];
@ -398,6 +404,8 @@ class Settings {
: null;
mangaHomeDisplayType = DisplayType.values[json['mangaHomeDisplayType']];
appFontFamily = json['appFontFamily'];
mangaGridSize = json['mangaGridSize'];
animeGridSize = json['animeGridSize'];
}
Map<String, dynamic> toJson() => {
@ -502,7 +510,9 @@ class Settings {
if (playerSubtitleSettings != null)
'playerSubtitleSettings': playerSubtitleSettings!.toJson(),
'mangaHomeDisplayType': mangaHomeDisplayType.index,
'appFontFamily': appFontFamily
'appFontFamily': appFontFamily,
'mangaGridSize': mangaGridSize,
'animeGridSize': animeGridSize
};
}

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,5 @@
import 'package:isar/isar.dart';
import 'package:mangayomi/eval/model/m_source.dart';
import 'package:mangayomi/eval/dart/model/m_source.dart';
part 'source.g.dart';
@collection
@ -53,6 +53,9 @@ class Source {
String? additionalParams;
@enumerated
SourceCodeLanguage sourceCodeLanguage = SourceCodeLanguage.dart;
Source(
{this.id = 0,
this.name = '',
@ -104,6 +107,7 @@ class Source {
version = json['version'];
versionLast = json['versionLast'];
additionalParams = json['additionalParams'] ?? "";
sourceCodeLanguage = SourceCodeLanguage.values[json['sourceCodeLanguage']];
}
Map<String, dynamic> toJson() => {
@ -131,6 +135,7 @@ class Source {
'version': version,
'versionLast': versionLast,
'additionalParams': additionalParams,
'sourceCodeLanguage': sourceCodeLanguage.index
};
bool get isTorrent => (typeSource?.toLowerCase() ?? "") == "torrent";
@ -149,3 +154,5 @@ class Source {
additionalParams: additionalParams);
}
}
enum SourceCodeLanguage { dart, javascript }

View file

@ -117,23 +117,29 @@ const SourceSchema = CollectionSchema(
name: r'sourceCode',
type: IsarType.string,
),
r'sourceCodeUrl': PropertySchema(
r'sourceCodeLanguage': PropertySchema(
id: 20,
name: r'sourceCodeLanguage',
type: IsarType.byte,
enumMap: _SourcesourceCodeLanguageEnumValueMap,
),
r'sourceCodeUrl': PropertySchema(
id: 21,
name: r'sourceCodeUrl',
type: IsarType.string,
),
r'typeSource': PropertySchema(
id: 21,
id: 22,
name: r'typeSource',
type: IsarType.string,
),
r'version': PropertySchema(
id: 22,
id: 23,
name: r'version',
type: IsarType.string,
),
r'versionLast': PropertySchema(
id: 23,
id: 24,
name: r'versionLast',
type: IsarType.string,
)
@ -277,10 +283,11 @@ void _sourceSerialize(
writer.writeBool(offsets[17], object.lastUsed);
writer.writeString(offsets[18], object.name);
writer.writeString(offsets[19], object.sourceCode);
writer.writeString(offsets[20], object.sourceCodeUrl);
writer.writeString(offsets[21], object.typeSource);
writer.writeString(offsets[22], object.version);
writer.writeString(offsets[23], object.versionLast);
writer.writeByte(offsets[20], object.sourceCodeLanguage.index);
writer.writeString(offsets[21], object.sourceCodeUrl);
writer.writeString(offsets[22], object.typeSource);
writer.writeString(offsets[23], object.version);
writer.writeString(offsets[24], object.versionLast);
}
Source _sourceDeserialize(
@ -310,11 +317,14 @@ Source _sourceDeserialize(
lastUsed: reader.readBoolOrNull(offsets[17]),
name: reader.readStringOrNull(offsets[18]),
sourceCode: reader.readStringOrNull(offsets[19]),
sourceCodeUrl: reader.readStringOrNull(offsets[20]),
typeSource: reader.readStringOrNull(offsets[21]),
version: reader.readStringOrNull(offsets[22]),
versionLast: reader.readStringOrNull(offsets[23]),
sourceCodeUrl: reader.readStringOrNull(offsets[21]),
typeSource: reader.readStringOrNull(offsets[22]),
version: reader.readStringOrNull(offsets[23]),
versionLast: reader.readStringOrNull(offsets[24]),
);
object.sourceCodeLanguage = _SourcesourceCodeLanguageValueEnumMap[
reader.readByteOrNull(offsets[20])] ??
SourceCodeLanguage.dart;
return object;
}
@ -366,18 +376,31 @@ P _sourceDeserializeProp<P>(
case 19:
return (reader.readStringOrNull(offset)) as P;
case 20:
return (reader.readStringOrNull(offset)) as P;
return (_SourcesourceCodeLanguageValueEnumMap[
reader.readByteOrNull(offset)] ??
SourceCodeLanguage.dart) as P;
case 21:
return (reader.readStringOrNull(offset)) as P;
case 22:
return (reader.readStringOrNull(offset)) as P;
case 23:
return (reader.readStringOrNull(offset)) as P;
case 24:
return (reader.readStringOrNull(offset)) as P;
default:
throw IsarError('Unknown property with id $propertyId');
}
}
const _SourcesourceCodeLanguageEnumValueMap = {
'dart': 0,
'javascript': 1,
};
const _SourcesourceCodeLanguageValueEnumMap = {
0: SourceCodeLanguage.dart,
1: SourceCodeLanguage.javascript,
};
Id _sourceGetId(Source object) {
return object.id ?? Isar.autoIncrement;
}
@ -2366,6 +2389,61 @@ extension SourceQueryFilter on QueryBuilder<Source, Source, QFilterCondition> {
});
}
QueryBuilder<Source, Source, QAfterFilterCondition> sourceCodeLanguageEqualTo(
SourceCodeLanguage value) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.equalTo(
property: r'sourceCodeLanguage',
value: value,
));
});
}
QueryBuilder<Source, Source, QAfterFilterCondition>
sourceCodeLanguageGreaterThan(
SourceCodeLanguage value, {
bool include = false,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.greaterThan(
include: include,
property: r'sourceCodeLanguage',
value: value,
));
});
}
QueryBuilder<Source, Source, QAfterFilterCondition>
sourceCodeLanguageLessThan(
SourceCodeLanguage value, {
bool include = false,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.lessThan(
include: include,
property: r'sourceCodeLanguage',
value: value,
));
});
}
QueryBuilder<Source, Source, QAfterFilterCondition> sourceCodeLanguageBetween(
SourceCodeLanguage lower,
SourceCodeLanguage upper, {
bool includeLower = true,
bool includeUpper = true,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.between(
property: r'sourceCodeLanguage',
lower: lower,
includeLower: includeLower,
upper: upper,
includeUpper: includeUpper,
));
});
}
QueryBuilder<Source, Source, QAfterFilterCondition> sourceCodeUrlIsNull() {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(const FilterCondition.isNull(
@ -3197,6 +3275,18 @@ extension SourceQuerySortBy on QueryBuilder<Source, Source, QSortBy> {
});
}
QueryBuilder<Source, Source, QAfterSortBy> sortBySourceCodeLanguage() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'sourceCodeLanguage', Sort.asc);
});
}
QueryBuilder<Source, Source, QAfterSortBy> sortBySourceCodeLanguageDesc() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'sourceCodeLanguage', Sort.desc);
});
}
QueryBuilder<Source, Source, QAfterSortBy> sortBySourceCodeUrl() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'sourceCodeUrl', Sort.asc);
@ -3499,6 +3589,18 @@ extension SourceQuerySortThenBy on QueryBuilder<Source, Source, QSortThenBy> {
});
}
QueryBuilder<Source, Source, QAfterSortBy> thenBySourceCodeLanguage() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'sourceCodeLanguage', Sort.asc);
});
}
QueryBuilder<Source, Source, QAfterSortBy> thenBySourceCodeLanguageDesc() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'sourceCodeLanguage', Sort.desc);
});
}
QueryBuilder<Source, Source, QAfterSortBy> thenBySourceCodeUrl() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'sourceCodeUrl', Sort.asc);
@ -3682,6 +3784,12 @@ extension SourceQueryWhereDistinct on QueryBuilder<Source, Source, QDistinct> {
});
}
QueryBuilder<Source, Source, QDistinct> distinctBySourceCodeLanguage() {
return QueryBuilder.apply(this, (query) {
return query.addDistinctBy(r'sourceCodeLanguage');
});
}
QueryBuilder<Source, Source, QDistinct> distinctBySourceCodeUrl(
{bool caseSensitive = true}) {
return QueryBuilder.apply(this, (query) {
@ -3839,6 +3947,13 @@ extension SourceQueryProperty on QueryBuilder<Source, Source, QQueryProperty> {
});
}
QueryBuilder<Source, SourceCodeLanguage, QQueryOperations>
sourceCodeLanguageProperty() {
return QueryBuilder.apply(this, (query) {
return query.addPropertyName(r'sourceCodeLanguage');
});
}
QueryBuilder<Source, String?, QQueryOperations> sourceCodeUrlProperty() {
return QueryBuilder.apply(this, (query) {
return query.addPropertyName(r'sourceCodeUrl');

View file

@ -1,3 +1,5 @@
import 'package:mangayomi/eval/javascript/http.dart';
class Video {
String url;
String quality;
@ -8,6 +10,24 @@ class Video {
Video(this.url, this.quality, this.originalUrl,
{this.headers, this.subtitles, this.audios});
factory Video.fromJson(Map<String, dynamic> json) {
return Video(json['url'], json['quality'], json['originalUrl'],
headers: (json['headers'] as Map?).toMapStringString,
subtitles: json['subtitles'] != null
? (json['subtitles'] as List).map((e) => Track.fromJson(e)).toList()
: [],
audios: json['audios'] != null
? (json['audios'] as List).map((e) => Track.fromJson(e)).toList()
: []);
}
Map<String, dynamic> toJson() => {
'url': url,
'quality': quality,
'originalUrl': originalUrl,
'headers': headers,
'subtitles': subtitles?.map((e) => toJson()),
'audios': audios?.map((e) => toJson()),
};
}
class Track {
@ -19,4 +39,5 @@ class Track {
file = json['file'];
label = json['label'];
}
Map<String, dynamic> toJson() => {'file': file, 'label': label};
}

View file

@ -7,7 +7,7 @@ part of 'state_provider.dart';
// **************************************************************************
String _$subtitleSettingsStateHash() =>
r'4f668c79675772a76d80585db43d041675d0d178';
r'4b89ea55392e662651d5aeee4dfce2fcd23ac0e7';
/// See also [SubtitleSettingsState].
@ProviderFor(SubtitleSettingsState)

View file

@ -1,7 +1,7 @@
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:mangayomi/eval/model/source_preference.dart';
import 'package:mangayomi/eval/dart/model/source_preference.dart';
import 'package:mangayomi/main.dart';
import 'package:mangayomi/models/source.dart';
import 'package:mangayomi/modules/browse/extension/providers/extension_preferences_providers.dart';
@ -21,10 +21,21 @@ class ExtensionDetail extends ConsumerStatefulWidget {
class _ExtensionDetailState extends ConsumerState<ExtensionDetail> {
late Source source = widget.source;
late List<SourcePreference> sourcePreference =
getSourcePreference(source: source)
.map((e) => getSourcePreferenceEntry(e.key!, source.id!))
.toList();
List<SourcePreference> sourcePreference = [];
@override
void initState() {
getSourcePreferenceAsync(source: source).then((value) {
if (mounted) {
setState(() {
sourcePreference = value
.map((e) => getSourcePreferenceEntry(e.key!, source.id!))
.toList();
});
}
});
super.initState();
}
@override
Widget build(BuildContext context) {

View file

@ -1,5 +1,5 @@
import 'package:isar/isar.dart';
import 'package:mangayomi/eval/model/source_preference.dart';
import 'package:mangayomi/eval/dart/model/source_preference.dart';
import 'package:mangayomi/main.dart';
import 'package:mangayomi/models/source.dart';
import 'package:mangayomi/services/get_source_preference.dart';
@ -85,3 +85,37 @@ void setSourcePreferenceStringValue(int sourceId, String key, String value) {
}
});
}
Future<dynamic> getPreferenceValueAsync(int sourceId, String key) async {
final sourcePreference = await getSourcePreferenceEntryAsync(key, sourceId);
if (sourcePreference.listPreference != null) {
final pref = sourcePreference.listPreference!;
return pref.entryValues![pref.valueIndex!];
} else if (sourcePreference.checkBoxPreference != null) {
return sourcePreference.checkBoxPreference!.value;
} else if (sourcePreference.switchPreferenceCompat != null) {
return sourcePreference.switchPreferenceCompat!.value;
} else if (sourcePreference.editTextPreference != null) {
return sourcePreference.editTextPreference!.value;
}
return sourcePreference.multiSelectListPreference!.values;
}
Future<SourcePreference> getSourcePreferenceEntryAsync(
String key, int sourceId) async {
SourcePreference? sourcePreference = isar.sourcePreferences
.filter()
.sourceIdEqualTo(sourceId)
.keyEqualTo(key)
.findFirstSync();
if (sourcePreference == null) {
final source = isar.sources.getSync(sourceId)!;
sourcePreference = (await getSourcePreferenceAsync(source: source))
.firstWhere((element) => element.key == key,
orElse: () => throw "Error when getting source preference");
setPreferenceSetting(sourcePreference, source);
}
return sourcePreference;
}

View file

@ -1,7 +1,7 @@
import 'dart:convert';
import 'package:dart_eval/stdlib/core.dart';
import 'package:mangayomi/eval/compiler/compiler.dart';
import 'package:mangayomi/eval/runtime/runtime.dart';
import 'package:mangayomi/eval/dart/compiler/compiler.dart';
import 'package:mangayomi/eval/dart/runtime/runtime.dart';
import 'package:mangayomi/main.dart';
import 'package:mangayomi/models/source.dart';
import 'package:mangayomi/modules/more/settings/browse/providers/browse_state_provider.dart';

View file

@ -1,5 +1,5 @@
import 'package:flutter/material.dart';
import 'package:mangayomi/eval/model/source_preference.dart';
import 'package:mangayomi/eval/dart/model/source_preference.dart';
import 'package:mangayomi/models/source.dart';
import 'package:mangayomi/modules/browse/extension/providers/extension_preferences_providers.dart';
import 'package:mangayomi/modules/manga/detail/widgets/chapter_filter_list_tile_widget.dart';

View file

@ -2,8 +2,8 @@ import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:isar/isar.dart';
import 'package:mangayomi/eval/model/m_manga.dart';
import 'package:mangayomi/eval/model/m_pages.dart';
import 'package:mangayomi/eval/dart/model/m_manga.dart';
import 'package:mangayomi/eval/dart/model/m_pages.dart';
import 'package:mangayomi/main.dart';
import 'package:mangayomi/models/manga.dart';
import 'package:mangayomi/modules/manga/home/manga_home_screen.dart';

View file

@ -1,12 +1,14 @@
// ignore_for_file: use_build_context_synchronously
import 'dart:io';
import 'dart:math';
import 'package:bot_toast/bot_toast.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import 'package:isar/isar.dart';
import 'package:mangayomi/eval/model/m_bridge.dart';
import 'package:mangayomi/eval/dart/model/m_bridge.dart';
import 'package:mangayomi/main.dart';
import 'package:mangayomi/models/category.dart';
import 'package:mangayomi/models/chapter.dart';
@ -692,6 +694,7 @@ class _LibraryScreenState extends ConsumerState<LibraryScreen>
language: language,
mangaIdsList: mangaIdsList,
localSource: localSource,
isManga: widget.isManga,
),
);
}
@ -765,6 +768,7 @@ class _LibraryScreenState extends ConsumerState<LibraryScreen>
language: language,
mangaIdsList: mangaIdsList,
localSource: localSource,
isManga: widget.isManga,
),
);
}
@ -1345,7 +1349,7 @@ class _LibraryScreenState extends ConsumerState<LibraryScreen>
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.only(left: 20, top: 10),
padding: const EdgeInsets.only(left: 20, right: 20, top: 10),
child: Row(
children: [
Text(l10n.display_mode),
@ -1408,8 +1412,63 @@ class _LibraryScreenState extends ConsumerState<LibraryScreen>
// ),
).toList()),
),
Consumer(
builder: (context, ref, child) {
final gridSize = ref.watch(libraryGridSizeStateProvider(
isManga: widget.isManga)) ??
0;
return Padding(
padding: const EdgeInsets.only(left: 8, right: 8, top: 10),
child: Row(
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Column(
children: [
Text(context.l10n.grid_size),
Text(gridSize == 0
? context.l10n.default0
: context.l10n.n_per_row(gridSize.toString()))
],
),
),
Flexible(
flex: 7,
child: SliderTheme(
data: SliderTheme.of(context).copyWith(
overlayShape: const RoundSliderOverlayShape(
overlayRadius: 5.0),
),
child: Slider(
min: 0.0,
max: 7,
divisions: max(7, 0),
value: gridSize.toDouble(),
onChanged: (value) {
HapticFeedback.vibrate();
ref
.read(libraryGridSizeStateProvider(
isManga: widget.isManga)
.notifier)
.set(value.toInt());
},
onChangeEnd: (value) {
ref
.read(libraryGridSizeStateProvider(
isManga: widget.isManga)
.notifier)
.set(value.toInt(), end: true);
},
),
),
)
],
),
);
},
),
Padding(
padding: const EdgeInsets.only(left: 20, top: 10),
padding: const EdgeInsets.only(left: 20, right: 20, top: 10),
child: Row(
children: [
Text(l10n.badges),
@ -1469,7 +1528,7 @@ class _LibraryScreenState extends ConsumerState<LibraryScreen>
),
),
Padding(
padding: const EdgeInsets.only(left: 20, top: 10),
padding: const EdgeInsets.only(left: 20, right: 20, top: 10),
child: Row(
children: [Text(l10n.tabs)],
),

View file

@ -42,6 +42,35 @@ class LibraryDisplayTypeState extends _$LibraryDisplayTypeState {
}
}
@riverpod
class LibraryGridSizeState extends _$LibraryGridSizeState {
@override
int? build({required bool isManga}) {
return isManga ? settings.mangaGridSize : settings.animeGridSize;
}
Settings get settings {
return isar.settings.getSync(227)!;
}
void set(int? value, {bool end = false}) {
Settings appSettings = Settings();
state = value;
if (end) {
if (isManga) {
appSettings = settings..mangaGridSize = value;
} else {
appSettings = settings..animeGridSize = value;
}
isar.writeTxnSync(() {
isar.settings.putSync(appSettings);
});
}
}
}
@riverpod
class MangaFilterDownloadedState extends _$MangaFilterDownloadedState {
@override

View file

@ -196,6 +196,151 @@ class _LibraryDisplayTypeStateProviderElement
Settings get settings => (origin as LibraryDisplayTypeStateProvider).settings;
}
String _$libraryGridSizeStateHash() =>
r'a4e55ef92f9387c2588679c5e2f23ef689e5d593';
abstract class _$LibraryGridSizeState
extends BuildlessAutoDisposeNotifier<int?> {
late final bool isManga;
int? build({
required bool isManga,
});
}
/// See also [LibraryGridSizeState].
@ProviderFor(LibraryGridSizeState)
const libraryGridSizeStateProvider = LibraryGridSizeStateFamily();
/// See also [LibraryGridSizeState].
class LibraryGridSizeStateFamily extends Family<int?> {
/// See also [LibraryGridSizeState].
const LibraryGridSizeStateFamily();
/// See also [LibraryGridSizeState].
LibraryGridSizeStateProvider call({
required bool isManga,
}) {
return LibraryGridSizeStateProvider(
isManga: isManga,
);
}
@override
LibraryGridSizeStateProvider getProviderOverride(
covariant LibraryGridSizeStateProvider provider,
) {
return call(
isManga: provider.isManga,
);
}
static const Iterable<ProviderOrFamily>? _dependencies = null;
@override
Iterable<ProviderOrFamily>? get dependencies => _dependencies;
static const Iterable<ProviderOrFamily>? _allTransitiveDependencies = null;
@override
Iterable<ProviderOrFamily>? get allTransitiveDependencies =>
_allTransitiveDependencies;
@override
String? get name => r'libraryGridSizeStateProvider';
}
/// See also [LibraryGridSizeState].
class LibraryGridSizeStateProvider
extends AutoDisposeNotifierProviderImpl<LibraryGridSizeState, int?> {
/// See also [LibraryGridSizeState].
LibraryGridSizeStateProvider({
required bool isManga,
}) : this._internal(
() => LibraryGridSizeState()..isManga = isManga,
from: libraryGridSizeStateProvider,
name: r'libraryGridSizeStateProvider',
debugGetCreateSourceHash:
const bool.fromEnvironment('dart.vm.product')
? null
: _$libraryGridSizeStateHash,
dependencies: LibraryGridSizeStateFamily._dependencies,
allTransitiveDependencies:
LibraryGridSizeStateFamily._allTransitiveDependencies,
isManga: isManga,
);
LibraryGridSizeStateProvider._internal(
super._createNotifier, {
required super.name,
required super.dependencies,
required super.allTransitiveDependencies,
required super.debugGetCreateSourceHash,
required super.from,
required this.isManga,
}) : super.internal();
final bool isManga;
@override
int? runNotifierBuild(
covariant LibraryGridSizeState notifier,
) {
return notifier.build(
isManga: isManga,
);
}
@override
Override overrideWith(LibraryGridSizeState Function() create) {
return ProviderOverride(
origin: this,
override: LibraryGridSizeStateProvider._internal(
() => create()..isManga = isManga,
from: from,
name: null,
dependencies: null,
allTransitiveDependencies: null,
debugGetCreateSourceHash: null,
isManga: isManga,
),
);
}
@override
AutoDisposeNotifierProviderElement<LibraryGridSizeState, int?>
createElement() {
return _LibraryGridSizeStateProviderElement(this);
}
@override
bool operator ==(Object other) {
return other is LibraryGridSizeStateProvider && other.isManga == isManga;
}
@override
int get hashCode {
var hash = _SystemHash.combine(0, runtimeType.hashCode);
hash = _SystemHash.combine(hash, isManga.hashCode);
return _SystemHash.finish(hash);
}
}
mixin LibraryGridSizeStateRef on AutoDisposeNotifierProviderRef<int?> {
/// The parameter `isManga` of this provider.
bool get isManga;
}
class _LibraryGridSizeStateProviderElement
extends AutoDisposeNotifierProviderElement<LibraryGridSizeState, int?>
with LibraryGridSizeStateRef {
_LibraryGridSizeStateProviderElement(super.provider);
@override
bool get isManga => (origin as LibraryGridSizeStateProvider).isManga;
}
String _$mangaFilterDownloadedStateHash() =>
r'9c07e64580061bf2cbf892ef679274913aaa3b20';

View file

@ -7,6 +7,7 @@ import 'package:mangayomi/main.dart';
import 'package:mangayomi/models/download.dart';
import 'package:mangayomi/modules/history/providers/isar_providers.dart';
import 'package:mangayomi/modules/library/providers/library_state_provider.dart';
import 'package:mangayomi/modules/library/widgets/measure_widget_sync.dart';
import 'package:mangayomi/modules/manga/reader/providers/push_router.dart';
import 'package:mangayomi/models/manga.dart';
import 'package:mangayomi/utils/extensions/build_context_extensions.dart';
@ -20,7 +21,10 @@ import 'package:mangayomi/modules/widgets/gridview_widget.dart';
import 'package:mangayomi/modules/widgets/manga_image_card_widget.dart';
import 'package:mangayomi/modules/widgets/progress_center.dart';
class LibraryGridViewWidget extends StatelessWidget {
final animeCardheightStateProvider = StateProvider<double>((ref) => 300);
final mangaCardheightStateProvider = StateProvider<double>((ref) => 300);
class LibraryGridViewWidget extends StatefulWidget {
final bool isCoverOnlyGrid;
final bool isComfortableGrid;
final List<int> mangaIdsList;
@ -29,6 +33,7 @@ class LibraryGridViewWidget extends StatelessWidget {
final bool downloadedChapter;
final bool continueReaderBtn;
final bool localSource;
final bool isManga;
const LibraryGridViewWidget(
{super.key,
required this.entriesManga,
@ -38,271 +43,332 @@ class LibraryGridViewWidget extends StatelessWidget {
required this.downloadedChapter,
required this.continueReaderBtn,
required this.mangaIdsList,
required this.localSource});
required this.localSource,
required this.isManga});
@override
State<LibraryGridViewWidget> createState() => _LibraryGridViewWidgetState();
}
class _LibraryGridViewWidgetState extends State<LibraryGridViewWidget> {
@override
Widget build(BuildContext context) {
return GridViewWidget(
childAspectRatio: isComfortableGrid ? 0.642 : 0.69,
itemCount: entriesManga.length,
itemBuilder: (context, index) {
final entry = entriesManga[index];
return Consumer(builder: (context, ref, child) {
bool isLocalArchive = entry.isLocalArchive ?? false;
final isLongPressed = ref.watch(isLongPressedMangaStateProvider);
return Padding(
padding: const EdgeInsets.all(2),
child: CoverViewWidget(
isLongPressed: mangaIdsList.contains(entry.id),
bottomTextWidget: BottomTextWidget(
maxLines: 1,
text: entry.name!,
isComfortableGrid: isComfortableGrid,
),
isComfortableGrid: isComfortableGrid,
image: entry.customCoverImage != null
? MemoryImage(entry.customCoverImage as Uint8List)
as ImageProvider
: CachedNetworkImageProvider(
toImgUrl(entry.customCoverFromTracker ?? entry.imageUrl!),
headers: entry.isLocalArchive!
? null
: ref.watch(headersProvider(
source: entry.source!, lang: entry.lang!)),
return Consumer(builder: (context, ref, child) {
final isLongPressed = ref.watch(isLongPressedMangaStateProvider);
final isManga = widget.isManga;
final height = ref.watch(isManga
? mangaCardheightStateProvider
: animeCardheightStateProvider);
final gridSize =
ref.watch(libraryGridSizeStateProvider(isManga: isManga));
return GridViewWidget(
gridSize: gridSize,
childAspectRatio: widget.isComfortableGrid ? 0.642 : 0.69,
itemCount: widget.entriesManga.length,
itemBuilder: (context, index) {
final entry = widget.entriesManga[index];
return Builder(builder: (context) {
bool isLocalArchive = entry.isLocalArchive ?? false;
return SizedBox(
height: height +
(widget.isComfortableGrid &&
(gridSize != null && gridSize != 0)
? 22
: 0),
child: MeasureWidgetSizeSync(
onCalculateSize: (size) {
if (size != null) {
final newHeight = size.width * 1.5;
if (height.ceil() != newHeight.ceil()) {
ref
.read((isManga
? mangaCardheightStateProvider
: animeCardheightStateProvider)
.notifier)
.state = size.width * 1.5;
}
}
},
child: Padding(
padding: const EdgeInsets.all(2),
child: CoverViewWidget(
isLongPressed: widget.mangaIdsList.contains(entry.id),
bottomTextWidget: BottomTextWidget(
maxLines: 1,
text: entry.name!,
isComfortableGrid: widget.isComfortableGrid,
),
onTap: () {
if (isLongPressed) {
ref.read(mangasListStateProvider.notifier).update(entry);
} else {
pushToMangaReaderDetail(
archiveId: isLocalArchive ? entry.id : null,
context: context,
lang: entry.lang!,
mangaM: entry,
source: entry.source!);
}
},
onLongPress: () {
if (!isLongPressed) {
ref.read(mangasListStateProvider.notifier).update(entry);
ref
.read(isLongPressedMangaStateProvider.notifier)
.update(!isLongPressed);
} else {
ref.read(mangasListStateProvider.notifier).update(entry);
}
},
children: [
Stack(
children: [
Positioned(
top: 0,
left: 0,
child: Padding(
padding: const EdgeInsets.all(5),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(3),
color: context.primaryColor,
),
child: Row(
children: [
if (localSource && isLocalArchive)
Container(
decoration: BoxDecoration(
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(3),
bottomLeft: Radius.circular(3)),
color: Theme.of(context).hintColor,
),
child: const Padding(
padding:
EdgeInsets.only(left: 3, right: 3),
child: Text(
"Local",
style: TextStyle(color: Colors.white),
),
),
),
if (downloadedChapter)
Padding(
padding: const EdgeInsets.only(right: 5),
child: Consumer(
builder: (context, ref, child) {
List nbrDown = [];
isar.txnSync(() {
for (var i = 0;
i < entry.chapters.length;
i++) {
final entries = isar.downloads
.filter()
.idIsNotNull()
.chapterIdEqualTo(entry.chapters
.toList()[i]
.id)
.findAllSync();
if (entries.isNotEmpty &&
entries.first.isDownload!) {
nbrDown.add(entries.first);
}
}
});
if (nbrDown.isNotEmpty) {
return Container(
decoration: BoxDecoration(
borderRadius:
const BorderRadius.only(
topLeft:
Radius.circular(3),
bottomLeft:
Radius.circular(3)),
color:
Theme.of(context).hintColor,
),
child: Padding(
padding: const EdgeInsets.only(
left: 3, right: 3),
child: Text(
nbrDown.length.toString(),
style: const TextStyle(
color: Colors.white),
),
),
);
} else {
return Container();
}
},
),
),
Padding(
padding: const EdgeInsets.only(right: 3),
child: Text(
entry.chapters.length.toString(),
style: const TextStyle(color: Colors.white),
),
),
],
),
isComfortableGrid: widget.isComfortableGrid,
image: entry.customCoverImage != null
? MemoryImage(entry.customCoverImage as Uint8List)
as ImageProvider
: CachedNetworkImageProvider(
toImgUrl(entry.customCoverFromTracker ??
entry.imageUrl!),
headers: entry.isLocalArchive!
? null
: ref.watch(headersProvider(
source: entry.source!, lang: entry.lang!)),
),
)),
if (language && entry.lang!.isNotEmpty)
Positioned(
top: 0,
right: 0,
child: Padding(
padding: const EdgeInsets.all(5),
child: Container(
color: context.themeData.cardColor,
child: Container(
decoration: BoxDecoration(
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(3),
bottomLeft: Radius.circular(3)),
color: Theme.of(context).hintColor,
),
child: Padding(
padding:
const EdgeInsets.only(left: 3, right: 3),
child: Text(
entry.lang!.toUpperCase(),
style: const TextStyle(color: Colors.white),
onTap: () {
if (isLongPressed) {
ref
.read(mangasListStateProvider.notifier)
.update(entry);
} else {
pushToMangaReaderDetail(
archiveId: isLocalArchive ? entry.id : null,
context: context,
lang: entry.lang!,
mangaM: entry,
source: entry.source!);
}
},
onLongPress: () {
if (!isLongPressed) {
ref
.read(mangasListStateProvider.notifier)
.update(entry);
ref
.read(isLongPressedMangaStateProvider.notifier)
.update(!isLongPressed);
} else {
ref
.read(mangasListStateProvider.notifier)
.update(entry);
}
},
children: [
Stack(
children: [
Positioned(
top: 0,
left: 0,
child: Padding(
padding: const EdgeInsets.all(5),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(3),
color: context.primaryColor,
),
child: Row(
children: [
if (widget.localSource && isLocalArchive)
Container(
decoration: BoxDecoration(
borderRadius:
const BorderRadius.only(
topLeft: Radius.circular(3),
bottomLeft:
Radius.circular(3)),
color: Theme.of(context).hintColor,
),
child: const Padding(
padding: EdgeInsets.only(
left: 3, right: 3),
child: Text(
"Local",
style: TextStyle(
color: Colors.white),
),
),
),
if (widget.downloadedChapter)
Padding(
padding:
const EdgeInsets.only(right: 5),
child: Consumer(
builder: (context, ref, child) {
List nbrDown = [];
isar.txnSync(() {
for (var i = 0;
i < entry.chapters.length;
i++) {
final entries = isar.downloads
.filter()
.idIsNotNull()
.chapterIdEqualTo(entry
.chapters
.toList()[i]
.id)
.findAllSync();
if (entries.isNotEmpty &&
entries
.first.isDownload!) {
nbrDown.add(entries.first);
}
}
});
if (nbrDown.isNotEmpty) {
return Container(
decoration: BoxDecoration(
borderRadius:
const BorderRadius.only(
topLeft:
Radius.circular(
3),
bottomLeft:
Radius.circular(
3)),
color: Theme.of(context)
.hintColor,
),
child: Padding(
padding:
const EdgeInsets.only(
left: 3, right: 3),
child: Text(
nbrDown.length.toString(),
style: const TextStyle(
color: Colors.white),
),
),
);
} else {
return Container();
}
},
),
),
Padding(
padding:
const EdgeInsets.only(right: 3),
child: Text(
entry.chapters.length.toString(),
style: const TextStyle(
color: Colors.white),
),
),
],
),
),
),
),
)),
],
),
if (!isComfortableGrid && !isCoverOnlyGrid)
BottomTextWidget(text: entry.name!),
if (continueReaderBtn)
Positioned(
bottom: 0,
right: 0,
child: Padding(
padding: const EdgeInsets.all(9),
child: Consumer(
builder: (context, ref, child) {
final history = ref.watch(
getAllHistoryStreamProvider(
isManga: entry.isManga!));
return history.when(
data: (data) {
final incognitoMode =
ref.watch(incognitoModeStateProvider);
final entries = data
.where((element) =>
element.mangaId == entry.id)
.toList();
if (entries.isNotEmpty && !incognitoMode) {
return GestureDetector(
onTap: () {
pushMangaReaderView(
context: context,
chapter: entries.first.chapter.value!,
);
},
child: Container(
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(5),
color: context.primaryColor
.withOpacity(0.9),
),
child: const Padding(
padding: EdgeInsets.all(7),
child: Icon(
Icons.play_arrow,
size: 19,
color: Colors.white,
)),
),
);
}
return GestureDetector(
onTap: () {
pushMangaReaderView(
context: context,
chapter: entry.chapters
.toList()
.reversed
.toList()
.last);
},
)),
if (widget.language && entry.lang!.isNotEmpty)
Positioned(
top: 0,
right: 0,
child: Padding(
padding: const EdgeInsets.all(5),
child: Container(
color: context.themeData.cardColor,
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
color: context.primaryColor
.withOpacity(0.9),
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(3),
bottomLeft: Radius.circular(3)),
color: Theme.of(context).hintColor,
),
child: Padding(
padding: const EdgeInsets.only(
left: 3, right: 3),
child: Text(
entry.lang!.toUpperCase(),
style: const TextStyle(
color: Colors.white),
),
),
child: const Padding(
padding: EdgeInsets.all(7),
child: Icon(
Icons.play_arrow,
size: 19,
color: Colors.white,
)),
),
);
},
error: (Object error, StackTrace stackTrace) {
return ErrorText(error);
},
loading: () {
return const ProgressCenter();
},
);
},
)))
],
),
);
});
},
);
),
)),
],
),
if (!widget.isComfortableGrid && !widget.isCoverOnlyGrid)
BottomTextWidget(text: entry.name!),
if (widget.continueReaderBtn)
Positioned(
bottom: 0,
right: 0,
child: Padding(
padding: const EdgeInsets.all(9),
child: Consumer(
builder: (context, ref, child) {
final history = ref.watch(
getAllHistoryStreamProvider(
isManga: entry.isManga!));
return history.when(
data: (data) {
final incognitoMode = ref
.watch(incognitoModeStateProvider);
final entries = data
.where((element) =>
element.mangaId == entry.id)
.toList();
if (entries.isNotEmpty &&
!incognitoMode) {
return GestureDetector(
onTap: () {
pushMangaReaderView(
context: context,
chapter: entries
.first.chapter.value!,
);
},
child: Container(
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(5),
color: context.primaryColor
.withOpacity(0.9),
),
child: const Padding(
padding: EdgeInsets.all(7),
child: Icon(
Icons.play_arrow,
size: 19,
color: Colors.white,
)),
),
);
}
return GestureDetector(
onTap: () {
pushMangaReaderView(
context: context,
chapter: entry.chapters
.toList()
.reversed
.toList()
.last);
},
child: Container(
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(5),
color: context.primaryColor
.withOpacity(0.9),
),
child: const Padding(
padding: EdgeInsets.all(7),
child: Icon(
Icons.play_arrow,
size: 19,
color: Colors.white,
)),
),
);
},
error: (Object error,
StackTrace stackTrace) {
return ErrorText(error);
},
loading: () {
return const ProgressCenter();
},
);
},
)))
],
),
),
),
);
});
},
);
});
}
}

View file

@ -0,0 +1,25 @@
import 'package:flutter/material.dart';
class MeasureWidgetSizeSync extends StatefulWidget {
final Function(Size? size) onCalculateSize;
final Widget child;
const MeasureWidgetSizeSync(
{super.key, required this.onCalculateSize, required this.child});
@override
State<MeasureWidgetSizeSync> createState() => _MeasureWidgetSizeSyncState();
}
class _MeasureWidgetSizeSyncState extends State<MeasureWidgetSizeSync> {
final _key = GlobalKey();
@override
Widget build(BuildContext context) {
if (context.mounted) {
WidgetsBinding.instance.addPostFrameCallback(
(_) => widget.onCalculateSize(_key.currentContext?.size));
}
return Container(key: _key, child: widget.child);
}
}

View file

@ -8,7 +8,7 @@ import 'package:flutter/rendering.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import 'package:isar/isar.dart';
import 'package:mangayomi/eval/model/m_bridge.dart';
import 'package:mangayomi/eval/dart/model/m_bridge.dart';
import 'package:mangayomi/main.dart';
import 'package:mangayomi/models/chapter.dart';
import 'package:mangayomi/models/download.dart';

View file

@ -1,5 +1,5 @@
import 'package:mangayomi/eval/model/m_bridge.dart';
import 'package:mangayomi/eval/model/m_manga.dart';
import 'package:mangayomi/eval/dart/model/m_bridge.dart';
import 'package:mangayomi/eval/dart/model/m_manga.dart';
import 'package:mangayomi/main.dart';
import 'package:mangayomi/models/chapter.dart';
import 'package:mangayomi/models/manga.dart';

View file

@ -3,10 +3,13 @@ import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import 'package:mangayomi/eval/model/m_manga.dart';
import 'package:mangayomi/eval/model/m_pages.dart';
import 'package:mangayomi/eval/dart/model/m_manga.dart';
import 'package:mangayomi/eval/dart/model/m_pages.dart';
import 'package:mangayomi/models/settings.dart';
import 'package:mangayomi/models/source.dart';
import 'package:mangayomi/modules/library/providers/library_state_provider.dart';
import 'package:mangayomi/modules/library/widgets/library_gridview_widget.dart';
import 'package:mangayomi/modules/library/widgets/measure_widget_sync.dart';
import 'package:mangayomi/modules/manga/home/providers/state_provider.dart';
import 'package:mangayomi/modules/manga/home/widget/filter_widget.dart';
import 'package:mangayomi/modules/widgets/listview_widget.dart';
@ -119,11 +122,19 @@ class _MangaHomeScreenState extends ConsumerState<MangaHomeScreen> {
AsyncValue<MPages?>? _getManga;
int _length = 0;
bool _isFiltering = false;
List<dynamic> filterList = [];
@override
void initState() {
getFilterList(source: widget.source).then((value) => setState(() {
filterList = value;
}));
super.initState();
}
@override
Widget build(BuildContext context) {
final supportsLatest =
ref.watch(supportsLatestProvider(source: widget.source));
final filterList = getFilterList(source: widget.source);
if (_selectedIndex == 2 && (_isSearch && _query.isNotEmpty) ||
_isFiltering) {
_getManga = ref.watch(searchProvider(
@ -328,8 +339,7 @@ class _MangaHomeScreenState extends ConsumerState<MangaHomeScreen> {
TextButton(
onPressed: () {
setState(() {
filters = getFilterList(
source: widget.source);
filters = filterList;
});
},
child: Text(l10n.reset),
@ -521,23 +531,56 @@ class _MangaHomeScreenState extends ConsumerState<MangaHomeScreen> {
manga: _mangaList[index],
source: widget.source);
})
: GridViewWidget(
controller: _scrollController,
itemCount: _length + 1,
childAspectRatio:
isComfortableGrid ? 0.642 : 0.69,
itemBuilder: (context, index) {
if (index == _length) {
return buildProgressIndicator();
}
return MangaHomeImageCard(
isManga: widget.source.isManga ?? true,
manga: _mangaList[index],
source: widget.source,
isComfortableGrid: isComfortableGrid,
);
},
)),
: Consumer(builder: (context, ref, child) {
final gridSize = ref.watch(
libraryGridSizeStateProvider(
isManga: widget.source.isManga!));
final height = ref.watch(widget.source.isManga!
? mangaCardheightStateProvider
: animeCardheightStateProvider);
return GridViewWidget(
gridSize: gridSize,
controller: _scrollController,
itemCount: _length + 1,
childAspectRatio:
isComfortableGrid ? 0.642 : 0.69,
itemBuilder: (context, index) {
if (index == _length) {
return buildProgressIndicator();
}
return SizedBox(
height: height +
(isComfortableGrid &&
(gridSize != null &&
gridSize != 0)
? 22
: 0),
child: MeasureWidgetSizeSync(
onCalculateSize: (size) {
if (size != null) {
final newHeight = size.width * 1.5;
if (height.ceil() !=
newHeight.ceil()) {
ref
.read((widget.source.isManga!
? mangaCardheightStateProvider
: animeCardheightStateProvider)
.notifier)
.state = size.width * 1.5;
}
}
},
child: MangaHomeImageCard(
isManga: widget.source.isManga ?? true,
manga: _mangaList[index],
source: widget.source,
isComfortableGrid: isComfortableGrid,
),
),
);
},
);
})),
],
),
);

View file

@ -1,5 +1,5 @@
import 'package:flutter/material.dart';
import 'package:mangayomi/eval/model/filter.dart';
import 'package:mangayomi/eval/dart/model/filter.dart';
import 'package:mangayomi/utils/extensions/build_context_extensions.dart';
class FilterWidget extends StatelessWidget {

View file

@ -8,9 +8,8 @@ import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:mangayomi/eval/model/m_bridge.dart';
import 'package:mangayomi/eval/dart/model/m_bridge.dart';
import 'package:mangayomi/main.dart';
import 'package:mangayomi/messages/generated.dart';
import 'package:mangayomi/models/chapter.dart';
import 'package:mangayomi/models/manga.dart';
import 'package:mangayomi/models/settings.dart';
@ -984,8 +983,6 @@ class _MangaChapterPageGalleryState
}
void _initCurrentIndex() async {
await finalizeRust();
await initializeRust();
final readerMode = _readerController.getReaderMode();
_uChapDataPreload.addAll(_chapterUrlModel.uChapDataPreload);
_readerController.setMangaHistoryUpdate();

View file

@ -2,7 +2,7 @@ import 'dart:io';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:mangayomi/eval/model/m_bridge.dart';
import 'package:mangayomi/eval/dart/model/m_bridge.dart';
import 'package:mangayomi/modules/manga/detail/widgets/chapter_filter_list_tile_widget.dart';
import 'package:mangayomi/modules/more/backup_and_restore/providers/auto_backup.dart';
import 'package:mangayomi/modules/more/backup_and_restore/providers/backup.dart';

View file

@ -4,7 +4,7 @@ import 'package:archive/archive_io.dart';
import 'package:bot_toast/bot_toast.dart';
import 'package:flutter/material.dart';
import 'package:isar/isar.dart';
import 'package:mangayomi/eval/model/source_preference.dart';
import 'package:mangayomi/eval/dart/model/source_preference.dart';
import 'package:mangayomi/main.dart';
import 'package:mangayomi/models/category.dart';
import 'package:mangayomi/models/chapter.dart';

View file

@ -2,8 +2,8 @@ import 'dart:convert';
import 'package:archive/archive_io.dart';
import 'package:bot_toast/bot_toast.dart';
import 'package:flutter/material.dart';
import 'package:mangayomi/eval/model/m_bridge.dart';
import 'package:mangayomi/eval/model/source_preference.dart';
import 'package:mangayomi/eval/dart/model/m_bridge.dart';
import 'package:mangayomi/eval/dart/model/source_preference.dart';
import 'package:mangayomi/main.dart';
import 'package:mangayomi/models/category.dart';
import 'package:mangayomi/models/chapter.dart';

View file

@ -6,7 +6,7 @@ part of 'app_font_family.dart';
// RiverpodGenerator
// **************************************************************************
String _$appFontFamilyHash() => r'500f9cd0c0b0dd27d7026c4aa029c33fed337430';
String _$appFontFamilyHash() => r'7f115012111256848d806e47382db1f8abcff5ec';
/// See also [AppFontFamily].
@ProviderFor(AppFontFamily)

View file

@ -46,12 +46,9 @@ class CoverViewWidget extends StatelessWidget {
children: children,
)
: Ink.image(
height: 200,
fit: BoxFit.cover,
image: image!,
child: Stack(
children: children,
),
child: Stack(children: children),
),
)),
),

View file

@ -6,27 +6,32 @@ class GridViewWidget extends StatelessWidget {
final bool reverse;
final double? childAspectRatio;
final Widget? Function(BuildContext, int) itemBuilder;
final int? gridSize;
const GridViewWidget(
{super.key,
this.controller,
required this.itemCount,
required this.itemBuilder,
this.reverse = false,
this.childAspectRatio = 0.69});
this.childAspectRatio = 0.69,
this.gridSize});
@override
Widget build(BuildContext context) {
return Container(
color: Theme.of(context).scaffoldBackgroundColor,
child: GridView.builder(
padding: const EdgeInsets.only(top: 13),
controller: controller,
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
childAspectRatio: childAspectRatio!,
maxCrossAxisExtent: 220,
),
itemCount: itemCount,
itemBuilder: itemBuilder),
);
color: Theme.of(context).scaffoldBackgroundColor,
child: GridView.builder(
padding: const EdgeInsets.only(top: 13),
controller: controller,
gridDelegate: (gridSize == null || gridSize == 0)
? SliverGridDelegateWithMaxCrossAxisExtent(
childAspectRatio: childAspectRatio!,
maxCrossAxisExtent: 220,
)
: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: gridSize!,
childAspectRatio: childAspectRatio!),
itemCount: itemCount,
itemBuilder: itemBuilder));
}
}

View file

@ -4,7 +4,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import 'package:isar/isar.dart';
import 'package:mangayomi/eval/model/m_manga.dart';
import 'package:mangayomi/eval/dart/model/m_manga.dart';
import 'package:mangayomi/main.dart';
import 'package:mangayomi/models/manga.dart';
import 'package:mangayomi/models/settings.dart';

View file

@ -1,7 +1,7 @@
// ignore_for_file: depend_on_referenced_packages
import 'dart:io';
import 'package:isar/isar.dart';
import 'package:mangayomi/eval/model/source_preference.dart';
import 'package:mangayomi/eval/dart/model/source_preference.dart';
import 'package:mangayomi/main.dart';
import 'package:mangayomi/models/category.dart';
import 'package:mangayomi/models/chapter.dart';

View file

@ -1,7 +1,7 @@
import 'dart:convert';
import 'package:html/dom.dart';
import 'package:http_interceptor/http_interceptor.dart';
import 'package:mangayomi/eval/model/m_bridge.dart';
import 'package:mangayomi/eval/dart/model/m_bridge.dart';
import 'package:mangayomi/models/video.dart';
import 'package:html/parser.dart' as parser;
import 'package:mangayomi/services/http/interceptor.dart';

View file

@ -1,17 +1,18 @@
import 'dart:async';
import 'dart:io';
import 'dart:typed_data';
import 'package:mangayomi/eval/bridge/m_source.dart';
import 'package:mangayomi/eval/compiler/compiler.dart';
import 'package:mangayomi/eval/model/m_provider.dart';
import 'package:mangayomi/eval/dart/bridge/m_source.dart';
import 'package:mangayomi/eval/dart/compiler/compiler.dart';
import 'package:mangayomi/eval/javascript/service.dart';
import 'package:mangayomi/eval/dart/model/m_provider.dart';
import 'package:mangayomi/main.dart';
import 'package:mangayomi/messages/generated.dart';
import 'package:mangayomi/models/chapter.dart';
import 'package:mangayomi/models/settings.dart';
import 'package:mangayomi/models/source.dart';
import 'package:mangayomi/modules/manga/archive_reader/providers/archive_reader_providers.dart';
import 'package:mangayomi/modules/manga/reader/reader_view.dart';
import 'package:mangayomi/providers/storage_provider.dart';
import 'package:mangayomi/eval/runtime/runtime.dart';
import 'package:mangayomi/eval/dart/runtime/runtime.dart';
import 'package:mangayomi/sources/utils/utils.dart';
import 'package:mangayomi/utils/reg_exp_matcher.dart';
import 'package:mangayomi/modules/more/providers/incognito_mode_state_provider.dart';
@ -62,16 +63,18 @@ Future<GetChapterPagesModel> getChapterPages(
isarPageUrls.first.urls!.isNotEmpty) {
pageUrls = isarPageUrls.first.urls!;
} else {
await finalizeRust();
await initializeRust();
final bytecode =
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
if (source.sourceCodeLanguage == SourceCodeLanguage.dart) {
final bytecode = compilerEval(
useTestSourceCode ? testSourceCode : source.sourceCode!);
final runtime = runtimeEval(bytecode);
final runtime = runtimeEval(bytecode);
var res = await runtime.executeLib('package:mangayomi/main.dart', 'main',
[$MSource.wrap(source.toMSource())]);
pageUrls = (await (res as MProvider).getPageList(chapter.url!));
var res = await runtime.executeLib('package:mangayomi/main.dart',
'main', [$MSource.wrap(source.toMSource())]);
pageUrls = (await (res as MProvider).getPageList(chapter.url!));
} else {
pageUrls = await JsExtensionService(source).getPageList(chapter.url!);
}
}
}

View file

@ -6,7 +6,7 @@ part of 'get_chapter_pages.dart';
// RiverpodGenerator
// **************************************************************************
String _$getChapterPagesHash() => r'aa95d95504a7f52e22bd3886782a9ef4443453e9';
String _$getChapterPagesHash() => r'e637b2e307606818eae08438d3c98aaec0ae0a00';
/// Copied from Dart SDK
class _SystemHash {

View file

@ -1,10 +1,11 @@
import 'dart:async';
import 'package:mangayomi/eval/bridge/m_source.dart';
import 'package:mangayomi/eval/model/m_manga.dart';
import 'package:mangayomi/eval/compiler/compiler.dart';
import 'package:mangayomi/eval/model/m_provider.dart';
import 'package:mangayomi/eval/dart/bridge/m_source.dart';
import 'package:mangayomi/eval/javascript/service.dart';
import 'package:mangayomi/eval/dart/model/m_manga.dart';
import 'package:mangayomi/eval/dart/compiler/compiler.dart';
import 'package:mangayomi/eval/dart/model/m_provider.dart';
import 'package:mangayomi/models/source.dart';
import 'package:mangayomi/eval/runtime/runtime.dart';
import 'package:mangayomi/eval/dart/runtime/runtime.dart';
import 'package:mangayomi/sources/source_test.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'get_detail.g.dart';
@ -16,17 +17,21 @@ Future<MManga> getDetail(
required Source source,
}) async {
MManga? mangadetail;
final bytecode =
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
if (source.sourceCodeLanguage == SourceCodeLanguage.dart) {
final bytecode =
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
final runtime = runtimeEval(bytecode);
final runtime = runtimeEval(bytecode);
var res = await runtime.executeLib('package:mangayomi/main.dart', 'main',
[$MSource.wrap(source.toMSource())]);
try {
mangadetail = await (res as MProvider).getDetail(url);
} catch (e) {
throw Exception(e);
var res = await runtime.executeLib('package:mangayomi/main.dart', 'main',
[$MSource.wrap(source.toMSource())]);
try {
mangadetail = await (res as MProvider).getDetail(url);
} catch (e) {
throw Exception(e);
}
} else {
mangadetail = await JsExtensionService(source).getDetail(url);
}
return mangadetail;
}

View file

@ -6,7 +6,7 @@ part of 'get_detail.dart';
// RiverpodGenerator
// **************************************************************************
String _$getDetailHash() => r'a1808953ca93c379c91b3e280a298c0852cebb34';
String _$getDetailHash() => r'a3e63c6d6a5ad9eccea268080f5506344677032b';
/// Copied from Dart SDK
class _SystemHash {

View file

@ -1,28 +1,32 @@
import 'package:dart_eval/dart_eval_bridge.dart';
import 'package:mangayomi/eval/bridge/m_source.dart';
import 'package:mangayomi/eval/compiler/compiler.dart';
import 'package:mangayomi/eval/model/m_provider.dart';
import 'package:mangayomi/eval/dart/bridge/m_source.dart';
import 'package:mangayomi/eval/dart/compiler/compiler.dart';
import 'package:mangayomi/eval/javascript/service.dart';
import 'package:mangayomi/eval/dart/model/m_provider.dart';
import 'package:mangayomi/models/source.dart';
import 'package:mangayomi/eval/runtime/runtime.dart';
import 'package:mangayomi/eval/dart/runtime/runtime.dart';
import 'package:mangayomi/sources/source_test.dart';
List<dynamic> getFilterList({required Source source}) {
Future<List<dynamic>> getFilterList({required Source source}) async {
List<dynamic> filterList = [];
if (source.sourceCodeLanguage == SourceCodeLanguage.dart) {
try {
final bytecode =
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
try {
final bytecode =
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
final runtime = runtimeEval(bytecode);
final runtime = runtimeEval(bytecode);
var res = runtime.executeLib('package:mangayomi/main.dart', 'main',
[$MSource.wrap(source.toMSource())]);
filterList = (res as MProvider)
.getFilterList()
.map((e) => e is $Value ? e.$reified : e)
.toList();
} catch (_) {
return [];
var res = runtime.executeLib('package:mangayomi/main.dart', 'main',
[$MSource.wrap(source.toMSource())]);
filterList = (res as MProvider)
.getFilterList()
.map((e) => e is $Value ? e.$reified : e)
.toList();
} catch (_) {
return [];
}
} else {
filterList = (await JsExtensionService(source).getFilterList()).filters;
}
return filterList;

View file

@ -1,10 +1,11 @@
import 'dart:async';
import 'package:mangayomi/eval/bridge/m_source.dart';
import 'package:mangayomi/eval/model/m_pages.dart';
import 'package:mangayomi/eval/compiler/compiler.dart';
import 'package:mangayomi/eval/model/m_provider.dart';
import 'package:mangayomi/eval/dart/bridge/m_source.dart';
import 'package:mangayomi/eval/javascript/service.dart';
import 'package:mangayomi/eval/dart/model/m_pages.dart';
import 'package:mangayomi/eval/dart/compiler/compiler.dart';
import 'package:mangayomi/eval/dart/model/m_provider.dart';
import 'package:mangayomi/models/source.dart';
import 'package:mangayomi/eval/runtime/runtime.dart';
import 'package:mangayomi/eval/dart/runtime/runtime.dart';
import 'package:mangayomi/sources/source_test.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'get_latest_updates.g.dart';
@ -16,19 +17,22 @@ Future<MPages?> getLatestUpdates(
required int page,
}) async {
MPages? latestUpdatesManga;
if (source.sourceCodeLanguage == SourceCodeLanguage.dart) {
try {
final bytecode =
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
try {
final bytecode =
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
final runtime = runtimeEval(bytecode);
final runtime = runtimeEval(bytecode);
var res = await runtime.executeLib('package:mangayomi/main.dart', 'main',
[$MSource.wrap(source.toMSource())]);
latestUpdatesManga = await (res as MProvider).getLatestUpdates(page);
} catch (e) {
throw Exception(e);
var res = await runtime.executeLib('package:mangayomi/main.dart', 'main',
[$MSource.wrap(source.toMSource())]);
latestUpdatesManga = await (res as MProvider).getLatestUpdates(page);
} catch (e) {
throw Exception(e);
}
} else {
latestUpdatesManga =
await JsExtensionService(source).getLatestUpdates(page);
}
return latestUpdatesManga;
}

View file

@ -6,7 +6,7 @@ part of 'get_latest_updates.dart';
// RiverpodGenerator
// **************************************************************************
String _$getLatestUpdatesHash() => r'288b2ce3b2e79c1924c8e2a312282900fd9e645f';
String _$getLatestUpdatesHash() => r'89ccdaf3b19ee84b2d61fd66301ef6d6eefbe797';
/// Copied from Dart SDK
class _SystemHash {

View file

@ -1,10 +1,11 @@
import 'dart:async';
import 'package:mangayomi/eval/bridge/m_source.dart';
import 'package:mangayomi/eval/model/m_pages.dart';
import 'package:mangayomi/eval/compiler/compiler.dart';
import 'package:mangayomi/eval/model/m_provider.dart';
import 'package:mangayomi/eval/dart/bridge/m_source.dart';
import 'package:mangayomi/eval/javascript/service.dart';
import 'package:mangayomi/eval/dart/model/m_pages.dart';
import 'package:mangayomi/eval/dart/compiler/compiler.dart';
import 'package:mangayomi/eval/dart/model/m_provider.dart';
import 'package:mangayomi/models/source.dart';
import 'package:mangayomi/eval/runtime/runtime.dart';
import 'package:mangayomi/eval/dart/runtime/runtime.dart';
import 'package:mangayomi/sources/source_test.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'get_popular.g.dart';
@ -16,18 +17,21 @@ Future<MPages?> getPopular(
required int page,
}) async {
MPages? popularManga;
if (source.sourceCodeLanguage == SourceCodeLanguage.dart) {
try {
final bytecode =
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
try {
final bytecode =
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
final runtime = runtimeEval(bytecode);
final runtime = runtimeEval(bytecode);
var res = runtime.executeLib('package:mangayomi/main.dart', 'main',
[$MSource.wrap(source.toMSource())]);
popularManga = await (res as MProvider).getPopular(page);
} catch (e) {
throw Exception(e);
var res = runtime.executeLib('package:mangayomi/main.dart', 'main',
[$MSource.wrap(source.toMSource())]);
popularManga = await (res as MProvider).getPopular(page);
} catch (e) {
throw Exception(e);
}
} else {
popularManga = await JsExtensionService(source).getPopular(page);
}
return popularManga;

View file

@ -6,7 +6,7 @@ part of 'get_popular.dart';
// RiverpodGenerator
// **************************************************************************
String _$getPopularHash() => r'd78a01ea5854ad3f592e713e4f4052929774e78e';
String _$getPopularHash() => r'81c132dc4a1dc78a5bedb69eb33a7f6fdb9bff16';
/// Copied from Dart SDK
class _SystemHash {

View file

@ -1,8 +1,8 @@
import 'package:mangayomi/eval/bridge/m_source.dart';
import 'package:mangayomi/eval/compiler/compiler.dart';
import 'package:mangayomi/eval/model/m_provider.dart';
import 'package:mangayomi/eval/dart/bridge/m_source.dart';
import 'package:mangayomi/eval/dart/compiler/compiler.dart';
import 'package:mangayomi/eval/dart/model/m_provider.dart';
import 'package:mangayomi/models/source.dart';
import 'package:mangayomi/eval/runtime/runtime.dart';
import 'package:mangayomi/eval/dart/runtime/runtime.dart';
import 'package:mangayomi/sources/source_test.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'get_source_baseurl.g.dart';
@ -10,19 +10,20 @@ part 'get_source_baseurl.g.dart';
@riverpod
String sourceBaseUrl(SourceBaseUrlRef ref, {required Source source}) {
String? baseUrl;
if (source.sourceCodeLanguage == SourceCodeLanguage.dart) {
try {
final bytecode =
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
try {
final bytecode =
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
final runtime = runtimeEval(bytecode);
final runtime = runtimeEval(bytecode);
var res = runtime.executeLib('package:mangayomi/main.dart', 'main',
[$MSource.wrap(source.toMSource())]);
baseUrl = (res as MProvider).baseUrl;
} catch (e) {
baseUrl = source.baseUrl;
}
var res = runtime.executeLib('package:mangayomi/main.dart', 'main',
[$MSource.wrap(source.toMSource())]);
baseUrl = (res as MProvider).baseUrl;
} catch (e) {
baseUrl = source.baseUrl;
}
} else {}
if (baseUrl == null || baseUrl.isEmpty) {
baseUrl = source.baseUrl;
}

View file

@ -6,7 +6,7 @@ part of 'get_source_baseurl.dart';
// RiverpodGenerator
// **************************************************************************
String _$sourceBaseUrlHash() => r'232addc3559f2b77974224a5ed8813eee9a0ba8e';
String _$sourceBaseUrlHash() => r'1e4352256b54a61220c09e719e2d0fa907bf6cd9';
/// Copied from Dart SDK
class _SystemHash {

View file

@ -1,10 +1,11 @@
import 'package:dart_eval/dart_eval_bridge.dart';
import 'package:mangayomi/eval/bridge/m_source.dart';
import 'package:mangayomi/eval/compiler/compiler.dart';
import 'package:mangayomi/eval/model/m_provider.dart';
import 'package:mangayomi/eval/model/source_preference.dart';
import 'package:mangayomi/eval/dart/bridge/m_source.dart';
import 'package:mangayomi/eval/dart/compiler/compiler.dart';
import 'package:mangayomi/eval/javascript/service.dart';
import 'package:mangayomi/eval/dart/model/m_provider.dart';
import 'package:mangayomi/eval/dart/model/source_preference.dart';
import 'package:mangayomi/models/source.dart';
import 'package:mangayomi/eval/runtime/runtime.dart';
import 'package:mangayomi/eval/dart/runtime/runtime.dart';
List<SourcePreference> getSourcePreference({required Source source}) {
List<SourcePreference> sourcePreference = [];
@ -26,3 +27,28 @@ List<SourcePreference> getSourcePreference({required Source source}) {
return sourcePreference;
}
Future<List<SourcePreference>> getSourcePreferenceAsync(
{required Source source}) async {
List<SourcePreference> sourcePreference = [];
if (source.sourceCodeLanguage == SourceCodeLanguage.dart) {
try {
final bytecode = compilerEval(source.sourceCode!);
final runtime = runtimeEval(bytecode);
var res = runtime.executeLib('package:mangayomi/main.dart', 'main',
[$MSource.wrap(source.toMSource())]);
sourcePreference = (res as MProvider)
.getSourcePreferences()
.map((e) => (e is $Value ? e.$reified : e) as SourcePreference)
.toList();
} catch (_) {
return [];
}
} else {
sourcePreference = await JsExtensionService(source).getSourcePreferences();
}
return sourcePreference;
}

View file

@ -1,12 +1,11 @@
import 'dart:async';
import 'dart:io';
import 'package:mangayomi/eval/bridge/m_source.dart';
import 'package:mangayomi/eval/model/m_provider.dart';
import 'package:mangayomi/eval/compiler/compiler.dart';
import 'package:mangayomi/messages/generated.dart';
import 'package:mangayomi/eval/dart/bridge/m_source.dart';
import 'package:mangayomi/eval/dart/model/m_provider.dart';
import 'package:mangayomi/eval/dart/compiler/compiler.dart';
import 'package:mangayomi/models/chapter.dart';
import 'package:mangayomi/models/video.dart';
import 'package:mangayomi/eval/runtime/runtime.dart';
import 'package:mangayomi/eval/dart/runtime/runtime.dart';
import 'package:mangayomi/providers/storage_provider.dart';
import 'package:mangayomi/services/torrent_server.dart';
import 'package:mangayomi/sources/utils/utils.dart';
@ -37,8 +36,7 @@ Future<(List<Video>, bool, String?)> getVideoList(
await MTorrentServer().getTorrentPlaylist(episode.url!);
return (videos, false, infohash);
}
await finalizeRust();
await initializeRust();
final bytecode =
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);

View file

@ -6,7 +6,7 @@ part of 'get_video_list.dart';
// RiverpodGenerator
// **************************************************************************
String _$getVideoListHash() => r'dd1908b1174efac883d05862ea55febf09ad976c';
String _$getVideoListHash() => r'dd53ef51fd6c729a985644336d467507e5c7923d';
/// Copied from Dart SDK
class _SystemHash {

View file

@ -1,9 +1,9 @@
import 'package:flutter/foundation.dart';
import 'package:http_interceptor/http_interceptor.dart';
import 'package:mangayomi/eval/model/m_bridge.dart';
import 'package:mangayomi/eval/dart/model/m_bridge.dart';
import 'dart:async';
import 'dart:io';
import 'package:mangayomi/eval/model/m_source.dart';
import 'package:mangayomi/eval/dart/model/m_source.dart';
import 'package:mangayomi/main.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart'
as flutter_inappwebview;

View file

@ -1,10 +1,12 @@
import 'package:mangayomi/eval/bridge/m_source.dart';
import 'package:mangayomi/eval/model/filter.dart';
import 'package:mangayomi/eval/model/m_pages.dart';
import 'package:mangayomi/eval/compiler/compiler.dart';
import 'package:mangayomi/eval/model/m_provider.dart';
import 'dart:convert';
import 'package:mangayomi/eval/dart/bridge/m_source.dart';
import 'package:mangayomi/eval/javascript/service.dart';
import 'package:mangayomi/eval/dart/model/filter.dart';
import 'package:mangayomi/eval/dart/model/m_pages.dart';
import 'package:mangayomi/eval/dart/compiler/compiler.dart';
import 'package:mangayomi/eval/dart/model/m_provider.dart';
import 'package:mangayomi/models/source.dart';
import 'package:mangayomi/eval/runtime/runtime.dart';
import 'package:mangayomi/eval/dart/runtime/runtime.dart';
import 'package:mangayomi/sources/source_test.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'search.g.dart';
@ -16,16 +18,21 @@ Future<MPages?> search(SearchRef ref,
required int page,
required List<dynamic> filterList}) async {
MPages? manga;
final bytecode =
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
final runtime = runtimeEval(bytecode);
var res = runtime.executeLib('package:mangayomi/main.dart', 'main',
[$MSource.wrap(source.toMSource())]);
try {
manga =
await (res as MProvider).search(query, page, FilterList(filterList));
} catch (e) {
throw Exception(e);
if (source.sourceCodeLanguage == SourceCodeLanguage.dart) {
final bytecode =
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
final runtime = runtimeEval(bytecode);
var res = runtime.executeLib('package:mangayomi/main.dart', 'main',
[$MSource.wrap(source.toMSource())]);
try {
manga =
await (res as MProvider).search(query, page, FilterList(filterList));
} catch (e) {
throw Exception(e);
}
} else {
manga = await JsExtensionService(source)
.search(query, page, jsonEncode(filterValuesListToJson(filterList)));
}
return manga;
}

View file

@ -6,7 +6,7 @@ part of 'search.dart';
// RiverpodGenerator
// **************************************************************************
String _$searchHash() => r'685e379023d83ede702d76696d64fccb803e5549';
String _$searchHash() => r'aa2fdda26ef0178495a18e0dec5a4bd7f9792fc7';
/// Copied from Dart SDK
class _SystemHash {

View file

@ -1,10 +1,13 @@
import 'package:mangayomi/eval/bridge/m_source.dart';
import 'package:mangayomi/eval/model/filter.dart';
import 'package:mangayomi/eval/model/m_pages.dart';
import 'package:mangayomi/eval/compiler/compiler.dart';
import 'package:mangayomi/eval/model/m_provider.dart';
import 'dart:convert';
import 'package:mangayomi/eval/dart/bridge/m_source.dart';
import 'package:mangayomi/eval/javascript/service.dart';
import 'package:mangayomi/eval/dart/model/filter.dart';
import 'package:mangayomi/eval/dart/model/m_pages.dart';
import 'package:mangayomi/eval/dart/compiler/compiler.dart';
import 'package:mangayomi/eval/dart/model/m_provider.dart';
import 'package:mangayomi/models/source.dart';
import 'package:mangayomi/eval/runtime/runtime.dart';
import 'package:mangayomi/eval/dart/runtime/runtime.dart';
import 'package:mangayomi/sources/source_test.dart';
Future<MPages?> search(
@ -13,16 +16,21 @@ Future<MPages?> search(
required int page,
required List<dynamic> filterList}) async {
MPages? manga;
final bytecode =
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
final runtime = runtimeEval(bytecode);
var res = runtime.executeLib('package:mangayomi/main.dart', 'main',
[$MSource.wrap(source.toMSource())]);
try {
manga =
await (res as MProvider).search(query, page, FilterList(filterList));
} catch (e) {
throw Exception(e);
if (source.sourceCodeLanguage == SourceCodeLanguage.dart) {
final bytecode =
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
final runtime = runtimeEval(bytecode);
var res = runtime.executeLib('package:mangayomi/main.dart', 'main',
[$MSource.wrap(source.toMSource())]);
try {
manga =
await (res as MProvider).search(query, page, FilterList(filterList));
} catch (e) {
throw Exception(e);
}
} else {
manga = await JsExtensionService(source)
.search(query, page, jsonEncode(filterValuesListToJson(filterList)));
}
return manga;
}

View file

@ -1,8 +1,8 @@
import 'package:mangayomi/eval/bridge/m_source.dart';
import 'package:mangayomi/eval/compiler/compiler.dart';
import 'package:mangayomi/eval/model/m_provider.dart';
import 'package:mangayomi/eval/dart/bridge/m_source.dart';
import 'package:mangayomi/eval/dart/compiler/compiler.dart';
import 'package:mangayomi/eval/dart/model/m_provider.dart';
import 'package:mangayomi/models/source.dart';
import 'package:mangayomi/eval/runtime/runtime.dart';
import 'package:mangayomi/eval/dart/runtime/runtime.dart';
import 'package:mangayomi/sources/source_test.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'supports_latest.g.dart';
@ -10,19 +10,21 @@ part 'supports_latest.g.dart';
@riverpod
bool supportsLatest(SupportsLatestRef ref, {required Source source}) {
bool? supportsLatest;
if (source.sourceCodeLanguage == SourceCodeLanguage.dart) {
try {
final bytecode =
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
try {
final bytecode =
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
final runtime = runtimeEval(bytecode);
final runtime = runtimeEval(bytecode);
var res = runtime.executeLib('package:mangayomi/main.dart', 'main',
[$MSource.wrap(source.toMSource())]);
supportsLatest = (res as MProvider).supportsLatest;
} catch (e) {
var res = runtime.executeLib('package:mangayomi/main.dart', 'main',
[$MSource.wrap(source.toMSource())]);
supportsLatest = (res as MProvider).supportsLatest;
} catch (e) {
supportsLatest = true;
}
} else {
supportsLatest = true;
}
return supportsLatest;
}

Some files were not shown because too many files have changed in this diff Show more