mirror of
https://github.com/kodjodevf/mangayomi.git
synced 2026-04-21 16:01:58 +00:00
Added JavaScript extension runtime, gridview count
This commit is contained in:
parent
85b3e2ee1f
commit
6fa0e8a89f
111 changed files with 3189 additions and 1049 deletions
|
|
@ -3,9 +3,9 @@ import 'package:dart_eval/dart_eval_bridge.dart';
|
||||||
|
|
||||||
import 'package:dart_eval/stdlib/core.dart';
|
import 'package:dart_eval/stdlib/core.dart';
|
||||||
import 'package:html/dom.dart';
|
import 'package:html/dom.dart';
|
||||||
import 'package:mangayomi/eval/bridge/element.dart';
|
import 'package:mangayomi/eval/dart/bridge/element.dart';
|
||||||
import 'package:mangayomi/eval/model/document.dart';
|
import 'package:mangayomi/eval/dart/model/document.dart';
|
||||||
import 'package:mangayomi/eval/model/element.dart';
|
import 'package:mangayomi/eval/dart/model/element.dart';
|
||||||
|
|
||||||
class $MDocument implements MDocument, $Instance {
|
class $MDocument implements MDocument, $Instance {
|
||||||
$MDocument.wrap(this.$value) : _superclass = $Object($value);
|
$MDocument.wrap(this.$value) : _superclass = $Object($value);
|
||||||
|
|
@ -131,6 +131,17 @@ class $MDocument implements MDocument, $Instance {
|
||||||
false)
|
false)
|
||||||
]),
|
]),
|
||||||
),
|
),
|
||||||
|
'attr': BridgeMethodDef(
|
||||||
|
BridgeFunctionDef(
|
||||||
|
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)),
|
||||||
|
params: [
|
||||||
|
BridgeParameter(
|
||||||
|
'attr',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string),
|
||||||
|
nullable: true),
|
||||||
|
false)
|
||||||
|
]),
|
||||||
|
),
|
||||||
},
|
},
|
||||||
wrap: true);
|
wrap: true);
|
||||||
|
|
||||||
|
|
@ -182,6 +193,8 @@ class $MDocument implements MDocument, $Instance {
|
||||||
return __xpath;
|
return __xpath;
|
||||||
case 'xpathFirst':
|
case 'xpathFirst':
|
||||||
return __xpathFirst;
|
return __xpathFirst;
|
||||||
|
case 'attr':
|
||||||
|
return __attr;
|
||||||
default:
|
default:
|
||||||
return _superclass.$getProperty(runtime, identifier);
|
return _superclass.$getProperty(runtime, identifier);
|
||||||
}
|
}
|
||||||
|
|
@ -257,6 +270,13 @@ class $MDocument implements MDocument, $Instance {
|
||||||
return res == null ? const $null() : $String(res);
|
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
|
@override
|
||||||
List<MElement>? select(String selector) => $value.select(selector);
|
List<MElement>? select(String selector) => $value.select(selector);
|
||||||
|
|
||||||
|
|
@ -277,6 +297,9 @@ class $MDocument implements MDocument, $Instance {
|
||||||
List<MElement>? getElementsByTagName(String localNames) =>
|
List<MElement>? getElementsByTagName(String localNames) =>
|
||||||
$value.getElementsByTagName(localNames);
|
$value.getElementsByTagName(localNames);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String? attr(String attr) => $value.attr(attr);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
MElement? getElementById(String id) => $value.getElementById(id);
|
MElement? getElementById(String id) => $value.getElementById(id);
|
||||||
|
|
||||||
|
|
@ -2,7 +2,7 @@ import 'package:dart_eval/dart_eval.dart';
|
||||||
import 'package:dart_eval/dart_eval_bridge.dart';
|
import 'package:dart_eval/dart_eval_bridge.dart';
|
||||||
import 'package:dart_eval/stdlib/core.dart';
|
import 'package:dart_eval/stdlib/core.dart';
|
||||||
import 'package:html/dom.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 {
|
class $MElement implements MElement, $Instance {
|
||||||
$MElement.wrap(this.$value) : _superclass = $Object($value);
|
$MElement.wrap(this.$value) : _superclass = $Object($value);
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import 'package:dart_eval/dart_eval.dart';
|
import 'package:dart_eval/dart_eval.dart';
|
||||||
import 'package:dart_eval/dart_eval_bridge.dart';
|
import 'package:dart_eval/dart_eval_bridge.dart';
|
||||||
import 'package:dart_eval/stdlib/core.dart';
|
import 'package:dart_eval/stdlib/core.dart';
|
||||||
import 'package:mangayomi/eval/model/filter.dart';
|
import 'package:mangayomi/eval/dart/model/filter.dart';
|
||||||
|
|
||||||
class $FilterList implements FilterList, $Instance {
|
class $FilterList implements FilterList, $Instance {
|
||||||
$FilterList.wrap(this.$value) : _superclass = $Object($value);
|
$FilterList.wrap(this.$value) : _superclass = $Object($value);
|
||||||
|
|
@ -71,6 +71,11 @@ class $FilterList implements FilterList, $Instance {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
set filters(List<dynamic> filters) {}
|
set filters(List<dynamic> filters) {}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class $SelectFilter implements SelectFilter, $Instance {
|
class $SelectFilter implements SelectFilter, $Instance {
|
||||||
|
|
@ -113,26 +118,26 @@ class $SelectFilter implements SelectFilter, $Instance {
|
||||||
|
|
||||||
static $Value? $new(Runtime runtime, $Value? target, List<$Value?> args) {
|
static $Value? $new(Runtime runtime, $Value? target, List<$Value?> args) {
|
||||||
return $SelectFilter.wrap(SelectFilter(
|
return $SelectFilter.wrap(SelectFilter(
|
||||||
args[0]!.$value,
|
args[0]!.$value,
|
||||||
args[1]!.$value,
|
args[1]!.$value,
|
||||||
args[2]!.$value,
|
args[2]!.$value,
|
||||||
(args[3]!.$value as List).map((e) {
|
(args[3]!.$value as List).map((e) {
|
||||||
if (e is $Value) {
|
if (e is $Value) {
|
||||||
final value = e.$reified;
|
final value = e.$reified;
|
||||||
if (value is Map) {
|
if (value is Map) {
|
||||||
Map<String, dynamic> map = {};
|
Map<String, dynamic> map = {};
|
||||||
map = value.map((key, value) => MapEntry(key.toString(), value));
|
map = value.map((key, value) => MapEntry(key.toString(), value));
|
||||||
if (map['type'] == 'SelectOption') {
|
if (map['type'] == 'SelectOption') {
|
||||||
final filter = map['filter'] as Map;
|
final filter = map['filter'] as Map;
|
||||||
return SelectFilterOption.fromJson(
|
return SelectFilterOption.fromJson(filter
|
||||||
filter.map((key, value) => MapEntry(key.toString(), value)));
|
.map((key, value) => MapEntry(key.toString(), value)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
return value;
|
return e;
|
||||||
}
|
}).toList(),
|
||||||
return e;
|
null));
|
||||||
}).toList(),
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
@ -188,6 +193,12 @@ class $SelectFilter implements SelectFilter, $Instance {
|
||||||
@override
|
@override
|
||||||
int get state => $value.state;
|
int get state => $value.state;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String? get typeName => $value.typeName;
|
||||||
|
|
||||||
|
@override
|
||||||
|
set typeName(String? typeName) {}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<dynamic> get values => $value.values;
|
List<dynamic> get values => $value.values;
|
||||||
|
|
||||||
|
|
@ -202,6 +213,11 @@ class $SelectFilter implements SelectFilter, $Instance {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
set values(List<dynamic> values) {}
|
set values(List<dynamic> values) {}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class $SelectFilterOption implements SelectFilterOption, $Instance {
|
class $SelectFilterOption implements SelectFilterOption, $Instance {
|
||||||
|
|
@ -230,7 +246,7 @@ class $SelectFilterOption implements SelectFilterOption, $Instance {
|
||||||
|
|
||||||
static $Value? $new(Runtime runtime, $Value? target, List<$Value?> args) {
|
static $Value? $new(Runtime runtime, $Value? target, List<$Value?> args) {
|
||||||
return $SelectFilterOption
|
return $SelectFilterOption
|
||||||
.wrap(SelectFilterOption(args[0]!.$value, args[1]!.$value));
|
.wrap(SelectFilterOption(args[0]!.$value, args[1]!.$value, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
@ -276,11 +292,22 @@ class $SelectFilterOption implements SelectFilterOption, $Instance {
|
||||||
@override
|
@override
|
||||||
String get name => $value.name;
|
String get name => $value.name;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String? get typeName => $value.typeName;
|
||||||
|
|
||||||
|
@override
|
||||||
|
set typeName(String? typeName) {}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
set name(String name) {}
|
set name(String name) {}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
set value(String value) {}
|
set value(String value) {}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class $SeparatorFilter implements SeparatorFilter, $Instance {
|
class $SeparatorFilter implements SeparatorFilter, $Instance {
|
||||||
|
|
@ -304,7 +331,8 @@ class $SeparatorFilter implements SeparatorFilter, $Instance {
|
||||||
wrap: true);
|
wrap: true);
|
||||||
|
|
||||||
static $Value? $new(Runtime runtime, $Value? target, List<$Value?> args) {
|
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
|
@override
|
||||||
|
|
@ -342,8 +370,19 @@ class $SeparatorFilter implements SeparatorFilter, $Instance {
|
||||||
@override
|
@override
|
||||||
String? get type => $value.type ?? '';
|
String? get type => $value.type ?? '';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String? get typeName => $value.typeName;
|
||||||
|
|
||||||
|
@override
|
||||||
|
set typeName(String? typeName) {}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
set type(String? type) {}
|
set type(String? type) {}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class $HeaderFilter implements HeaderFilter, $Instance {
|
class $HeaderFilter implements HeaderFilter, $Instance {
|
||||||
|
|
@ -372,7 +411,7 @@ class $HeaderFilter implements HeaderFilter, $Instance {
|
||||||
|
|
||||||
static $Value? $new(Runtime runtime, $Value? target, List<$Value?> args) {
|
static $Value? $new(Runtime runtime, $Value? target, List<$Value?> args) {
|
||||||
return $HeaderFilter
|
return $HeaderFilter
|
||||||
.wrap(HeaderFilter(args[0]!.$value, type: args[1]?.$value ?? ''));
|
.wrap(HeaderFilter(args[0]!.$value, null, type: args[1]?.$value ?? ''));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
@ -423,6 +462,17 @@ class $HeaderFilter implements HeaderFilter, $Instance {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String? get type => $value.type ?? '';
|
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 {
|
class $TextFilter implements TextFilter, $Instance {
|
||||||
|
|
@ -450,7 +500,7 @@ class $TextFilter implements TextFilter, $Instance {
|
||||||
wrap: true);
|
wrap: true);
|
||||||
|
|
||||||
static $Value? $new(Runtime runtime, $Value? target, List<$Value?> args) {
|
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
|
@override
|
||||||
|
|
@ -502,6 +552,12 @@ class $TextFilter implements TextFilter, $Instance {
|
||||||
@override
|
@override
|
||||||
String get state => $value.state;
|
String get state => $value.state;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String? get typeName => $value.typeName;
|
||||||
|
|
||||||
|
@override
|
||||||
|
set typeName(String? typeName) {}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
set type(String? type) {}
|
set type(String? type) {}
|
||||||
|
|
||||||
|
|
@ -510,6 +566,11 @@ class $TextFilter implements TextFilter, $Instance {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
set state(String state) {}
|
set state(String state) {}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class $SortFilter implements SortFilter, $Instance {
|
class $SortFilter implements SortFilter, $Instance {
|
||||||
|
|
@ -550,13 +611,14 @@ class $SortFilter implements SortFilter, $Instance {
|
||||||
|
|
||||||
static $Value? $new(Runtime runtime, $Value? target, List<$Value?> args) {
|
static $Value? $new(Runtime runtime, $Value? target, List<$Value?> args) {
|
||||||
return $SortFilter.wrap(SortFilter(
|
return $SortFilter.wrap(SortFilter(
|
||||||
args[0]!.$value,
|
args[0]!.$value,
|
||||||
args[1]!.$value,
|
args[1]!.$value,
|
||||||
args[2]!.$value,
|
args[2]!.$value,
|
||||||
(args[3]!.$value as List)
|
(args[3]!.$value as List)
|
||||||
.map((e) => SelectFilterOption(e.$reified.name, e.$reified.value))
|
.map((e) =>
|
||||||
.toList(),
|
SelectFilterOption(e.$reified.name, e.$reified.value, null))
|
||||||
));
|
.toList(),
|
||||||
|
null));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
@ -615,6 +677,12 @@ class $SortFilter implements SortFilter, $Instance {
|
||||||
@override
|
@override
|
||||||
List<dynamic> get values => $value.values;
|
List<dynamic> get values => $value.values;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String? get typeName => $value.typeName;
|
||||||
|
|
||||||
|
@override
|
||||||
|
set typeName(String? typeName) {}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
set type(String? type) {}
|
set type(String? type) {}
|
||||||
|
|
||||||
|
|
@ -626,6 +694,11 @@ class $SortFilter implements SortFilter, $Instance {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
set values(List<dynamic> values) {}
|
set values(List<dynamic> values) {}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class $SortState implements SortState, $Instance {
|
class $SortState implements SortState, $Instance {
|
||||||
|
|
@ -655,7 +728,7 @@ class $SortState implements SortState, $Instance {
|
||||||
wrap: true);
|
wrap: true);
|
||||||
|
|
||||||
static $Value? $new(Runtime runtime, $Value? target, List<$Value?> args) {
|
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
|
@override
|
||||||
|
|
@ -701,11 +774,22 @@ class $SortState implements SortState, $Instance {
|
||||||
@override
|
@override
|
||||||
bool get ascending => $value.ascending;
|
bool get ascending => $value.ascending;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String? get typeName => $value.typeName;
|
||||||
|
|
||||||
|
@override
|
||||||
|
set typeName(String? typeName) {}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
set ascending(bool ascending) {}
|
set ascending(bool ascending) {}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
set index(int index) {}
|
set index(int index) {}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class $TriStateFilter implements TriStateFilter, $Instance {
|
class $TriStateFilter implements TriStateFilter, $Instance {
|
||||||
|
|
@ -744,7 +828,7 @@ class $TriStateFilter implements TriStateFilter, $Instance {
|
||||||
|
|
||||||
static $Value? $new(Runtime runtime, $Value? target, List<$Value?> args) {
|
static $Value? $new(Runtime runtime, $Value? target, List<$Value?> args) {
|
||||||
return $TriStateFilter.wrap(TriStateFilter(
|
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));
|
state: args[3]?.$value ?? 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -808,6 +892,12 @@ class $TriStateFilter implements TriStateFilter, $Instance {
|
||||||
@override
|
@override
|
||||||
String get value => $value.value;
|
String get value => $value.value;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String? get typeName => $value.typeName;
|
||||||
|
|
||||||
|
@override
|
||||||
|
set typeName(String? typeName) {}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
set state(int state) {}
|
set state(int state) {}
|
||||||
|
|
||||||
|
|
@ -816,6 +906,11 @@ class $TriStateFilter implements TriStateFilter, $Instance {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
set value(String value) {}
|
set value(String value) {}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class $GroupFilter implements GroupFilter, $Instance {
|
class $GroupFilter implements GroupFilter, $Instance {
|
||||||
|
|
@ -874,7 +969,8 @@ class $GroupFilter implements GroupFilter, $Instance {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
return e;
|
return e;
|
||||||
}).toList()));
|
}).toList(),
|
||||||
|
null));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
@ -927,6 +1023,12 @@ class $GroupFilter implements GroupFilter, $Instance {
|
||||||
@override
|
@override
|
||||||
List<dynamic> get state => $value.state;
|
List<dynamic> get state => $value.state;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String? get typeName => $value.typeName;
|
||||||
|
|
||||||
|
@override
|
||||||
|
set typeName(String? typeName) {}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
set type(String? type) {}
|
set type(String? type) {}
|
||||||
|
|
||||||
|
|
@ -935,6 +1037,11 @@ class $GroupFilter implements GroupFilter, $Instance {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
set state(List<dynamic> state) {}
|
set state(List<dynamic> state) {}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class $CheckBoxFilter implements CheckBoxFilter, $Instance {
|
class $CheckBoxFilter implements CheckBoxFilter, $Instance {
|
||||||
|
|
@ -973,7 +1080,7 @@ class $CheckBoxFilter implements CheckBoxFilter, $Instance {
|
||||||
|
|
||||||
static $Value? $new(Runtime runtime, $Value? target, List<$Value?> args) {
|
static $Value? $new(Runtime runtime, $Value? target, List<$Value?> args) {
|
||||||
return $CheckBoxFilter.wrap(CheckBoxFilter(
|
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));
|
state: args[3]?.$value ?? false));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1037,6 +1144,12 @@ class $CheckBoxFilter implements CheckBoxFilter, $Instance {
|
||||||
@override
|
@override
|
||||||
String get value => $value.value;
|
String get value => $value.value;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String? get typeName => $value.typeName;
|
||||||
|
|
||||||
|
@override
|
||||||
|
set typeName(String? typeName) {}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
set type(String? type) {}
|
set type(String? type) {}
|
||||||
|
|
||||||
|
|
@ -1045,4 +1158,9 @@ class $CheckBoxFilter implements CheckBoxFilter, $Instance {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
set value(String value) {}
|
set value(String value) {}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -4,8 +4,8 @@ import 'package:dart_eval/dart_eval_bridge.dart';
|
||||||
import 'package:dart_eval/stdlib/core.dart';
|
import 'package:dart_eval/stdlib/core.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:http_interceptor/http_interceptor.dart';
|
import 'package:http_interceptor/http_interceptor.dart';
|
||||||
import 'package:mangayomi/eval/bridge/m_source.dart';
|
import 'package:mangayomi/eval/dart/bridge/m_source.dart';
|
||||||
import 'package:mangayomi/eval/model/m_bridge.dart';
|
import 'package:mangayomi/eval/dart/model/m_bridge.dart';
|
||||||
import 'package:mangayomi/services/http/interceptor.dart';
|
import 'package:mangayomi/services/http/interceptor.dart';
|
||||||
|
|
||||||
/// dart_eval wrapper for [InterceptedClient]
|
/// dart_eval wrapper for [InterceptedClient]
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import 'package:dart_eval/dart_eval.dart';
|
import 'package:dart_eval/dart_eval.dart';
|
||||||
import 'package:dart_eval/dart_eval_bridge.dart';
|
import 'package:dart_eval/dart_eval_bridge.dart';
|
||||||
import 'package:dart_eval/stdlib/core.dart';
|
import 'package:dart_eval/stdlib/core.dart';
|
||||||
import 'package:mangayomi/eval/model/m_chapter.dart';
|
import 'package:mangayomi/eval/dart/model/m_chapter.dart';
|
||||||
|
|
||||||
class $MChapter implements MChapter, $Instance {
|
class $MChapter implements MChapter, $Instance {
|
||||||
$MChapter.wrap(this.$value) : _superclass = $Object($value);
|
$MChapter.wrap(this.$value) : _superclass = $Object($value);
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
import 'package:dart_eval/dart_eval.dart';
|
import 'package:dart_eval/dart_eval.dart';
|
||||||
import 'package:dart_eval/dart_eval_bridge.dart';
|
import 'package:dart_eval/dart_eval_bridge.dart';
|
||||||
import 'package:dart_eval/stdlib/core.dart';
|
import 'package:dart_eval/stdlib/core.dart';
|
||||||
import 'package:mangayomi/eval/bridge/m_chapter.dart';
|
import 'package:mangayomi/eval/dart/bridge/m_chapter.dart';
|
||||||
import 'package:mangayomi/eval/bridge/m_status.dart';
|
import 'package:mangayomi/eval/dart/bridge/m_status.dart';
|
||||||
import 'package:mangayomi/eval/model/m_chapter.dart';
|
import 'package:mangayomi/eval/dart/model/m_chapter.dart';
|
||||||
import 'package:mangayomi/eval/model/m_manga.dart';
|
import 'package:mangayomi/eval/dart/model/m_manga.dart';
|
||||||
import 'package:mangayomi/models/manga.dart';
|
import 'package:mangayomi/models/manga.dart';
|
||||||
|
|
||||||
class $MManga implements MManga, $Instance {
|
class $MManga implements MManga, $Instance {
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
import 'package:dart_eval/dart_eval.dart';
|
import 'package:dart_eval/dart_eval.dart';
|
||||||
import 'package:dart_eval/dart_eval_bridge.dart';
|
import 'package:dart_eval/dart_eval_bridge.dart';
|
||||||
import 'package:dart_eval/stdlib/core.dart';
|
import 'package:dart_eval/stdlib/core.dart';
|
||||||
import 'package:mangayomi/eval/bridge/m_manga.dart';
|
import 'package:mangayomi/eval/dart/bridge/m_manga.dart';
|
||||||
import 'package:mangayomi/eval/model/m_manga.dart';
|
import 'package:mangayomi/eval/dart/model/m_manga.dart';
|
||||||
import 'package:mangayomi/eval/model/m_pages.dart';
|
import 'package:mangayomi/eval/dart/model/m_pages.dart';
|
||||||
|
|
||||||
class $MPages implements MPages, $Instance {
|
class $MPages implements MPages, $Instance {
|
||||||
$MPages.wrap(this.$value) : _superclass = $Object($value);
|
$MPages.wrap(this.$value) : _superclass = $Object($value);
|
||||||
|
|
@ -2,18 +2,18 @@ import 'dart:convert';
|
||||||
import 'package:dart_eval/dart_eval.dart';
|
import 'package:dart_eval/dart_eval.dart';
|
||||||
import 'package:dart_eval/dart_eval_bridge.dart';
|
import 'package:dart_eval/dart_eval_bridge.dart';
|
||||||
import 'package:dart_eval/stdlib/core.dart';
|
import 'package:dart_eval/stdlib/core.dart';
|
||||||
import 'package:mangayomi/eval/bridge/document.dart';
|
import 'package:mangayomi/eval/dart/bridge/document.dart';
|
||||||
import 'package:mangayomi/eval/bridge/filter.dart';
|
import 'package:mangayomi/eval/dart/bridge/filter.dart';
|
||||||
import 'package:mangayomi/eval/bridge/m_manga.dart';
|
import 'package:mangayomi/eval/dart/bridge/m_manga.dart';
|
||||||
import 'package:mangayomi/eval/bridge/m_pages.dart';
|
import 'package:mangayomi/eval/dart/bridge/m_pages.dart';
|
||||||
import 'package:mangayomi/eval/bridge/m_status.dart';
|
import 'package:mangayomi/eval/dart/bridge/m_status.dart';
|
||||||
import 'package:mangayomi/eval/bridge/m_track.dart';
|
import 'package:mangayomi/eval/dart/bridge/m_track.dart';
|
||||||
import 'package:mangayomi/eval/bridge/m_video.dart';
|
import 'package:mangayomi/eval/dart/bridge/m_video.dart';
|
||||||
import 'package:mangayomi/eval/model/filter.dart';
|
import 'package:mangayomi/eval/dart/model/filter.dart';
|
||||||
import 'package:mangayomi/eval/model/m_bridge.dart';
|
import 'package:mangayomi/eval/dart/model/m_bridge.dart';
|
||||||
import 'package:mangayomi/eval/model/m_pages.dart';
|
import 'package:mangayomi/eval/dart/model/m_pages.dart';
|
||||||
import 'package:mangayomi/eval/model/m_manga.dart';
|
import 'package:mangayomi/eval/dart/model/m_manga.dart';
|
||||||
import 'package:mangayomi/eval/model/m_provider.dart';
|
import 'package:mangayomi/eval/dart/model/m_provider.dart';
|
||||||
import 'package:mangayomi/models/video.dart';
|
import 'package:mangayomi/models/video.dart';
|
||||||
import 'package:mangayomi/modules/browse/extension/providers/extension_preferences_providers.dart';
|
import 'package:mangayomi/modules/browse/extension/providers/extension_preferences_providers.dart';
|
||||||
import 'package:mangayomi/services/boa_js.dart';
|
import 'package:mangayomi/services/boa_js.dart';
|
||||||
|
|
@ -1025,8 +1025,8 @@ class $MProvider extends MProvider with $Bridge<MProvider> {
|
||||||
_toValueList(List filters) {
|
_toValueList(List filters) {
|
||||||
return (filters).map((e) {
|
return (filters).map((e) {
|
||||||
if (e is SelectFilter) {
|
if (e is SelectFilter) {
|
||||||
return $SelectFilter.wrap(
|
return $SelectFilter.wrap(SelectFilter(
|
||||||
SelectFilter(e.type, e.name, e.state, _toValueList(e.values)));
|
e.type, e.name, e.state, _toValueList(e.values), e.typeName));
|
||||||
} else if (e is TextFilter) {
|
} else if (e is TextFilter) {
|
||||||
return $TextFilter.wrap(e);
|
return $TextFilter.wrap(e);
|
||||||
} else if (e is HeaderFilter) {
|
} else if (e is HeaderFilter) {
|
||||||
|
|
@ -1038,8 +1038,8 @@ class $MProvider extends MProvider with $Bridge<MProvider> {
|
||||||
} else if (e is SeparatorFilter) {
|
} else if (e is SeparatorFilter) {
|
||||||
return $SeparatorFilter.wrap(e);
|
return $SeparatorFilter.wrap(e);
|
||||||
} else if (e is SortFilter) {
|
} else if (e is SortFilter) {
|
||||||
return $SortFilter
|
return $SortFilter.wrap(SortFilter(
|
||||||
.wrap(SortFilter(e.type, e.name, e.state, _toValueList(e.values)));
|
e.type, e.name, e.state, _toValueList(e.values), e.typeName));
|
||||||
} else if (e is SortState) {
|
} else if (e is SortState) {
|
||||||
return $SortState.wrap(e);
|
return $SortState.wrap(e);
|
||||||
} else if (e is CheckBoxFilter) {
|
} else if (e is CheckBoxFilter) {
|
||||||
|
|
@ -1047,8 +1047,8 @@ class $MProvider extends MProvider with $Bridge<MProvider> {
|
||||||
} else if (e is SelectFilterOption) {
|
} else if (e is SelectFilterOption) {
|
||||||
return $SelectFilterOption.wrap(e);
|
return $SelectFilterOption.wrap(e);
|
||||||
} else if (e is GroupFilter) {
|
} else if (e is GroupFilter) {
|
||||||
return $GroupFilter
|
return $GroupFilter.wrap(
|
||||||
.wrap(GroupFilter(e.type, e.name, _toValueList(e.state)));
|
GroupFilter(e.type, e.name, _toValueList(e.state), e.typeName));
|
||||||
}
|
}
|
||||||
return e;
|
return e;
|
||||||
}).toList();
|
}).toList();
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import 'package:dart_eval/dart_eval.dart';
|
import 'package:dart_eval/dart_eval.dart';
|
||||||
import 'package:dart_eval/dart_eval_bridge.dart';
|
import 'package:dart_eval/dart_eval_bridge.dart';
|
||||||
import 'package:dart_eval/stdlib/core.dart';
|
import 'package:dart_eval/stdlib/core.dart';
|
||||||
import 'package:mangayomi/eval/model/m_source.dart';
|
import 'package:mangayomi/eval/dart/model/m_source.dart';
|
||||||
|
|
||||||
class $MSource implements MSource, $Instance {
|
class $MSource implements MSource, $Instance {
|
||||||
$MSource.wrap(this.$value) : _superclass = $Object($value);
|
$MSource.wrap(this.$value) : _superclass = $Object($value);
|
||||||
|
|
@ -76,4 +76,9 @@ class $MTrack implements Track, $Instance {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
set label(String? label) {}
|
set label(String? label) {}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import 'package:dart_eval/dart_eval.dart';
|
import 'package:dart_eval/dart_eval.dart';
|
||||||
import 'package:dart_eval/dart_eval_bridge.dart';
|
import 'package:dart_eval/dart_eval_bridge.dart';
|
||||||
import 'package:dart_eval/stdlib/core.dart';
|
import 'package:dart_eval/stdlib/core.dart';
|
||||||
import 'package:mangayomi/eval/bridge/m_track.dart';
|
import 'package:mangayomi/eval/dart/bridge/m_track.dart';
|
||||||
import 'package:mangayomi/models/video.dart';
|
import 'package:mangayomi/models/video.dart';
|
||||||
|
|
||||||
class $MVideo implements Video, $Instance {
|
class $MVideo implements Video, $Instance {
|
||||||
|
|
@ -139,4 +139,9 @@ class $MVideo implements Video, $Instance {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
set audios(List? audios) {}
|
set audios(List? audios) {}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2,7 +2,7 @@ import 'package:dart_eval/dart_eval.dart';
|
||||||
import 'package:dart_eval/dart_eval_bridge.dart';
|
import 'package:dart_eval/dart_eval_bridge.dart';
|
||||||
import 'package:dart_eval/stdlib/core.dart';
|
import 'package:dart_eval/stdlib/core.dart';
|
||||||
import 'package:isar/isar.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 {
|
class $CheckBoxPreference implements SourcePreference, $Instance {
|
||||||
$CheckBoxPreference.wrap(this.$value) : _superclass = $Object($value);
|
$CheckBoxPreference.wrap(this.$value) : _superclass = $Object($value);
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
import 'package:dart_eval/dart_eval.dart';
|
import 'package:dart_eval/dart_eval.dart';
|
||||||
import 'package:mangayomi/eval/plugin.dart';
|
import 'package:mangayomi/eval/dart/plugin.dart';
|
||||||
|
|
||||||
Uint8List compilerEval(String code) {
|
Uint8List compilerEval(String code) {
|
||||||
late Compiler compiler = Compiler();
|
late Compiler compiler = Compiler();
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import 'package:html/dom.dart';
|
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';
|
import 'package:mangayomi/utils/extensions/dom_extensions.dart';
|
||||||
|
|
||||||
class MDocument {
|
class MDocument {
|
||||||
|
|
@ -55,4 +55,8 @@ class MDocument {
|
||||||
MElement? selectFirst(String selector) {
|
MElement? selectFirst(String selector) {
|
||||||
return MElement(_document?.selectFirst(selector));
|
return MElement(_document?.selectFirst(selector));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String? attr(String attr) {
|
||||||
|
return _document?.attr(attr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
237
lib/eval/dart/model/filter.dart
Normal file
237
lib/eval/dart/model/filter.dart
Normal 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();
|
||||||
|
}
|
||||||
|
|
@ -8,7 +8,7 @@ import 'package:intl/date_symbol_data_local.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
import 'package:js_packer/js_packer.dart';
|
import 'package:js_packer/js_packer.dart';
|
||||||
import 'package:json_path/json_path.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/models/manga.dart';
|
||||||
import 'package:mangayomi/services/anime_extractors/dood_extractor.dart';
|
import 'package:mangayomi/services/anime_extractors/dood_extractor.dart';
|
||||||
import 'package:mangayomi/services/anime_extractors/filemoon.dart';
|
import 'package:mangayomi/services/anime_extractors/filemoon.dart';
|
||||||
17
lib/eval/dart/model/m_chapter.dart
Normal file
17
lib/eval/dart/model/m_chapter.dart
Normal 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']);
|
||||||
|
}
|
||||||
|
}
|
||||||
50
lib/eval/dart/model/m_manga.dart
Normal file
50
lib/eval/dart/model/m_manga.dart
Normal 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()
|
||||||
|
: []);
|
||||||
|
}
|
||||||
|
}
|
||||||
15
lib/eval/dart/model/m_pages.dart
Normal file
15
lib/eval/dart/model/m_pages.dart
Normal 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']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import 'package:mangayomi/eval/model/filter.dart';
|
import 'package:mangayomi/eval/dart/model/filter.dart';
|
||||||
import 'package:mangayomi/eval/model/m_pages.dart';
|
import 'package:mangayomi/eval/dart/model/m_pages.dart';
|
||||||
import 'package:mangayomi/eval/model/m_manga.dart';
|
import 'package:mangayomi/eval/dart/model/m_manga.dart';
|
||||||
import 'package:mangayomi/models/video.dart';
|
import 'package:mangayomi/models/video.dart';
|
||||||
|
|
||||||
abstract class MProvider {
|
abstract class MProvider {
|
||||||
|
|
@ -1,18 +1,18 @@
|
||||||
import 'package:dart_eval/dart_eval.dart';
|
import 'package:dart_eval/dart_eval.dart';
|
||||||
import 'package:dart_eval/dart_eval_bridge.dart';
|
import 'package:dart_eval/dart_eval_bridge.dart';
|
||||||
import 'package:mangayomi/eval/bridge/document.dart';
|
import 'package:mangayomi/eval/dart/bridge/document.dart';
|
||||||
import 'package:mangayomi/eval/bridge/element.dart';
|
import 'package:mangayomi/eval/dart/bridge/element.dart';
|
||||||
import 'package:mangayomi/eval/bridge/http.dart';
|
import 'package:mangayomi/eval/dart/bridge/http.dart';
|
||||||
import 'package:mangayomi/eval/bridge/m_chapter.dart';
|
import 'package:mangayomi/eval/dart/bridge/m_chapter.dart';
|
||||||
import 'package:mangayomi/eval/bridge/filter.dart';
|
import 'package:mangayomi/eval/dart/bridge/filter.dart';
|
||||||
import 'package:mangayomi/eval/bridge/m_pages.dart';
|
import 'package:mangayomi/eval/dart/bridge/m_pages.dart';
|
||||||
import 'package:mangayomi/eval/bridge/m_status.dart';
|
import 'package:mangayomi/eval/dart/bridge/m_status.dart';
|
||||||
import 'package:mangayomi/eval/bridge/m_provider.dart';
|
import 'package:mangayomi/eval/dart/bridge/m_provider.dart';
|
||||||
import 'package:mangayomi/eval/bridge/m_manga.dart';
|
import 'package:mangayomi/eval/dart/bridge/m_manga.dart';
|
||||||
import 'package:mangayomi/eval/bridge/m_source.dart';
|
import 'package:mangayomi/eval/dart/bridge/m_source.dart';
|
||||||
import 'package:mangayomi/eval/bridge/m_track.dart';
|
import 'package:mangayomi/eval/dart/bridge/m_track.dart';
|
||||||
import 'package:mangayomi/eval/bridge/m_video.dart';
|
import 'package:mangayomi/eval/dart/bridge/m_video.dart';
|
||||||
import 'package:mangayomi/eval/bridge/source_preference.dart';
|
import 'package:mangayomi/eval/dart/bridge/source_preference.dart';
|
||||||
|
|
||||||
class MEvalPlugin extends EvalPlugin {
|
class MEvalPlugin extends EvalPlugin {
|
||||||
@override
|
@override
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
import 'package:dart_eval/dart_eval.dart';
|
import 'package:dart_eval/dart_eval.dart';
|
||||||
import 'package:mangayomi/eval/plugin.dart';
|
import 'package:mangayomi/eval/dart/plugin.dart';
|
||||||
|
|
||||||
Runtime runtimeEval(Uint8List bytecode) {
|
Runtime runtimeEval(Uint8List bytecode) {
|
||||||
final runtime = Runtime(bytecode.buffer.asByteData());
|
final runtime = Runtime(bytecode.buffer.asByteData());
|
||||||
312
lib/eval/javascript/dom_selector.dart
Normal file
312
lib/eval/javascript/dom_selector.dart
Normal 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,
|
||||||
|
};
|
||||||
|
}
|
||||||
172
lib/eval/javascript/extractors.dart
Normal file
172
lib/eval/javascript/extractors.dart
Normal 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());
|
||||||
|
}
|
||||||
|
}
|
||||||
134
lib/eval/javascript/http.dart
Normal file
134
lib/eval/javascript/http.dart
Normal 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()));
|
||||||
|
}
|
||||||
|
}
|
||||||
45
lib/eval/javascript/preferences.dart
Normal file
45
lib/eval/javascript/preferences.dart
Normal 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;
|
||||||
|
}
|
||||||
|
''');
|
||||||
|
}
|
||||||
|
}
|
||||||
141
lib/eval/javascript/service.dart
Normal file
141
lib/eval/javascript/service.dart
Normal 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 [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
86
lib/eval/javascript/utils.dart
Normal file
86
lib/eval/javascript/utils.dart
Normal 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);
|
||||||
|
}
|
||||||
|
''');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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});
|
|
||||||
}
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
class MChapter {
|
|
||||||
String? name;
|
|
||||||
|
|
||||||
String? url;
|
|
||||||
|
|
||||||
String? dateUpload;
|
|
||||||
|
|
||||||
String? scanlator;
|
|
||||||
MChapter({this.name, this.url, this.dateUpload, this.scanlator});
|
|
||||||
}
|
|
||||||
|
|
@ -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});
|
|
||||||
}
|
|
||||||
|
|
@ -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});
|
|
||||||
}
|
|
||||||
|
|
@ -317,5 +317,7 @@
|
||||||
"text": "النص",
|
"text": "النص",
|
||||||
"border": "الحدود",
|
"border": "الحدود",
|
||||||
"background": "الخلفية",
|
"background": "الخلفية",
|
||||||
"no_subtite_warning_message": "لا تؤثر لأنه لا توجد مسارات ترجمة في هذا الفيديو"
|
"no_subtite_warning_message": "لا تؤثر لأنه لا توجد مسارات ترجمة في هذا الفيديو",
|
||||||
|
"grid_size": "حجم الشبكة",
|
||||||
|
"n_per_row": "{n} في الصف الواحد"
|
||||||
}
|
}
|
||||||
|
|
@ -317,5 +317,7 @@
|
||||||
"text": "Text",
|
"text": "Text",
|
||||||
"border": "Rand",
|
"border": "Rand",
|
||||||
"background": "Hintergrund",
|
"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"
|
||||||
}
|
}
|
||||||
|
|
@ -319,5 +319,7 @@
|
||||||
"text": "Text",
|
"text": "Text",
|
||||||
"border": "Border",
|
"border": "Border",
|
||||||
"background": "Background",
|
"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"
|
||||||
}
|
}
|
||||||
|
|
@ -317,5 +317,7 @@
|
||||||
"text": "Texto",
|
"text": "Texto",
|
||||||
"border": "Borde",
|
"border": "Borde",
|
||||||
"background": "Fondo",
|
"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"
|
||||||
}
|
}
|
||||||
|
|
@ -317,5 +317,7 @@
|
||||||
"text": "Texto",
|
"text": "Texto",
|
||||||
"border": "Borde",
|
"border": "Borde",
|
||||||
"background": "Fondo",
|
"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"
|
||||||
}
|
}
|
||||||
|
|
@ -318,5 +318,7 @@
|
||||||
"text": "Texte",
|
"text": "Texte",
|
||||||
"border": "Bordure",
|
"border": "Bordure",
|
||||||
"background": "Arrière-plan",
|
"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"
|
||||||
}
|
}
|
||||||
|
|
@ -317,5 +317,7 @@
|
||||||
"text": "Teks",
|
"text": "Teks",
|
||||||
"border": "Batas",
|
"border": "Batas",
|
||||||
"background": "Latar Belakang",
|
"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"
|
||||||
}
|
}
|
||||||
|
|
@ -317,5 +317,7 @@
|
||||||
"text": "Testo",
|
"text": "Testo",
|
||||||
"border": "Bordo",
|
"border": "Bordo",
|
||||||
"background": "Sfondo",
|
"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"
|
||||||
}
|
}
|
||||||
|
|
@ -317,5 +317,7 @@
|
||||||
"text": "Texto",
|
"text": "Texto",
|
||||||
"border": "Borda",
|
"border": "Borda",
|
||||||
"background": "Fundo",
|
"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"
|
||||||
}
|
}
|
||||||
|
|
@ -317,5 +317,7 @@
|
||||||
"text": "Texto",
|
"text": "Texto",
|
||||||
"border": "Borda",
|
"border": "Borda",
|
||||||
"background": "Fundo",
|
"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"
|
||||||
}
|
}
|
||||||
|
|
@ -317,5 +317,7 @@
|
||||||
"text": "Текст",
|
"text": "Текст",
|
||||||
"border": "Граница",
|
"border": "Граница",
|
||||||
"background": "Фон",
|
"background": "Фон",
|
||||||
"no_subtite_warning_message": "Не имеет эффекта, потому что в этом видео нет субтитров"
|
"no_subtite_warning_message": "Не имеет эффекта, потому что в этом видео нет субтитров",
|
||||||
|
"grid_size": "Размер сетки",
|
||||||
|
"n_per_row": "{n} в ряд"
|
||||||
}
|
}
|
||||||
|
|
@ -317,5 +317,7 @@
|
||||||
"text": "Metin",
|
"text": "Metin",
|
||||||
"border": "Kenarlık",
|
"border": "Kenarlık",
|
||||||
"background": "Arka Plan",
|
"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"
|
||||||
}
|
}
|
||||||
|
|
@ -319,5 +319,7 @@
|
||||||
"text": "文本",
|
"text": "文本",
|
||||||
"border": "边框",
|
"border": "边框",
|
||||||
"background": "背景",
|
"background": "背景",
|
||||||
"no_subtite_warning_message": "由于此视频中没有字幕轨道,因此无效。"
|
"no_subtite_warning_message": "由于此视频中没有字幕轨道,因此无效。",
|
||||||
|
"grid_size": "网格大小",
|
||||||
|
"n_per_row": "{n} 每行"
|
||||||
}
|
}
|
||||||
|
|
@ -179,6 +179,10 @@ class Settings {
|
||||||
|
|
||||||
String? appFontFamily;
|
String? appFontFamily;
|
||||||
|
|
||||||
|
int? mangaGridSize;
|
||||||
|
|
||||||
|
int? animeGridSize;
|
||||||
|
|
||||||
Settings(
|
Settings(
|
||||||
{this.id = 227,
|
{this.id = 227,
|
||||||
this.displayType = DisplayType.compactGrid,
|
this.displayType = DisplayType.compactGrid,
|
||||||
|
|
@ -257,7 +261,9 @@ class Settings {
|
||||||
this.colorFilterBlendMode = ColorFilterBlendMode.none,
|
this.colorFilterBlendMode = ColorFilterBlendMode.none,
|
||||||
this.playerSubtitleSettings,
|
this.playerSubtitleSettings,
|
||||||
this.mangaHomeDisplayType = DisplayType.comfortableGrid,
|
this.mangaHomeDisplayType = DisplayType.comfortableGrid,
|
||||||
this.appFontFamily});
|
this.appFontFamily,
|
||||||
|
this.mangaGridSize,
|
||||||
|
this.animeGridSize});
|
||||||
|
|
||||||
Settings.fromJson(Map<String, dynamic> json) {
|
Settings.fromJson(Map<String, dynamic> json) {
|
||||||
animatePageTransitions = json['animatePageTransitions'];
|
animatePageTransitions = json['animatePageTransitions'];
|
||||||
|
|
@ -398,6 +404,8 @@ class Settings {
|
||||||
: null;
|
: null;
|
||||||
mangaHomeDisplayType = DisplayType.values[json['mangaHomeDisplayType']];
|
mangaHomeDisplayType = DisplayType.values[json['mangaHomeDisplayType']];
|
||||||
appFontFamily = json['appFontFamily'];
|
appFontFamily = json['appFontFamily'];
|
||||||
|
mangaGridSize = json['mangaGridSize'];
|
||||||
|
animeGridSize = json['animeGridSize'];
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
Map<String, dynamic> toJson() => {
|
||||||
|
|
@ -502,7 +510,9 @@ class Settings {
|
||||||
if (playerSubtitleSettings != null)
|
if (playerSubtitleSettings != null)
|
||||||
'playerSubtitleSettings': playerSubtitleSettings!.toJson(),
|
'playerSubtitleSettings': playerSubtitleSettings!.toJson(),
|
||||||
'mangaHomeDisplayType': mangaHomeDisplayType.index,
|
'mangaHomeDisplayType': mangaHomeDisplayType.index,
|
||||||
'appFontFamily': appFontFamily
|
'appFontFamily': appFontFamily,
|
||||||
|
'mangaGridSize': mangaGridSize,
|
||||||
|
'animeGridSize': animeGridSize
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,5 +1,5 @@
|
||||||
import 'package:isar/isar.dart';
|
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';
|
part 'source.g.dart';
|
||||||
|
|
||||||
@collection
|
@collection
|
||||||
|
|
@ -53,6 +53,9 @@ class Source {
|
||||||
|
|
||||||
String? additionalParams;
|
String? additionalParams;
|
||||||
|
|
||||||
|
@enumerated
|
||||||
|
SourceCodeLanguage sourceCodeLanguage = SourceCodeLanguage.dart;
|
||||||
|
|
||||||
Source(
|
Source(
|
||||||
{this.id = 0,
|
{this.id = 0,
|
||||||
this.name = '',
|
this.name = '',
|
||||||
|
|
@ -104,6 +107,7 @@ class Source {
|
||||||
version = json['version'];
|
version = json['version'];
|
||||||
versionLast = json['versionLast'];
|
versionLast = json['versionLast'];
|
||||||
additionalParams = json['additionalParams'] ?? "";
|
additionalParams = json['additionalParams'] ?? "";
|
||||||
|
sourceCodeLanguage = SourceCodeLanguage.values[json['sourceCodeLanguage']];
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
Map<String, dynamic> toJson() => {
|
||||||
|
|
@ -131,6 +135,7 @@ class Source {
|
||||||
'version': version,
|
'version': version,
|
||||||
'versionLast': versionLast,
|
'versionLast': versionLast,
|
||||||
'additionalParams': additionalParams,
|
'additionalParams': additionalParams,
|
||||||
|
'sourceCodeLanguage': sourceCodeLanguage.index
|
||||||
};
|
};
|
||||||
|
|
||||||
bool get isTorrent => (typeSource?.toLowerCase() ?? "") == "torrent";
|
bool get isTorrent => (typeSource?.toLowerCase() ?? "") == "torrent";
|
||||||
|
|
@ -149,3 +154,5 @@ class Source {
|
||||||
additionalParams: additionalParams);
|
additionalParams: additionalParams);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum SourceCodeLanguage { dart, javascript }
|
||||||
|
|
|
||||||
|
|
@ -117,23 +117,29 @@ const SourceSchema = CollectionSchema(
|
||||||
name: r'sourceCode',
|
name: r'sourceCode',
|
||||||
type: IsarType.string,
|
type: IsarType.string,
|
||||||
),
|
),
|
||||||
r'sourceCodeUrl': PropertySchema(
|
r'sourceCodeLanguage': PropertySchema(
|
||||||
id: 20,
|
id: 20,
|
||||||
|
name: r'sourceCodeLanguage',
|
||||||
|
type: IsarType.byte,
|
||||||
|
enumMap: _SourcesourceCodeLanguageEnumValueMap,
|
||||||
|
),
|
||||||
|
r'sourceCodeUrl': PropertySchema(
|
||||||
|
id: 21,
|
||||||
name: r'sourceCodeUrl',
|
name: r'sourceCodeUrl',
|
||||||
type: IsarType.string,
|
type: IsarType.string,
|
||||||
),
|
),
|
||||||
r'typeSource': PropertySchema(
|
r'typeSource': PropertySchema(
|
||||||
id: 21,
|
id: 22,
|
||||||
name: r'typeSource',
|
name: r'typeSource',
|
||||||
type: IsarType.string,
|
type: IsarType.string,
|
||||||
),
|
),
|
||||||
r'version': PropertySchema(
|
r'version': PropertySchema(
|
||||||
id: 22,
|
id: 23,
|
||||||
name: r'version',
|
name: r'version',
|
||||||
type: IsarType.string,
|
type: IsarType.string,
|
||||||
),
|
),
|
||||||
r'versionLast': PropertySchema(
|
r'versionLast': PropertySchema(
|
||||||
id: 23,
|
id: 24,
|
||||||
name: r'versionLast',
|
name: r'versionLast',
|
||||||
type: IsarType.string,
|
type: IsarType.string,
|
||||||
)
|
)
|
||||||
|
|
@ -277,10 +283,11 @@ void _sourceSerialize(
|
||||||
writer.writeBool(offsets[17], object.lastUsed);
|
writer.writeBool(offsets[17], object.lastUsed);
|
||||||
writer.writeString(offsets[18], object.name);
|
writer.writeString(offsets[18], object.name);
|
||||||
writer.writeString(offsets[19], object.sourceCode);
|
writer.writeString(offsets[19], object.sourceCode);
|
||||||
writer.writeString(offsets[20], object.sourceCodeUrl);
|
writer.writeByte(offsets[20], object.sourceCodeLanguage.index);
|
||||||
writer.writeString(offsets[21], object.typeSource);
|
writer.writeString(offsets[21], object.sourceCodeUrl);
|
||||||
writer.writeString(offsets[22], object.version);
|
writer.writeString(offsets[22], object.typeSource);
|
||||||
writer.writeString(offsets[23], object.versionLast);
|
writer.writeString(offsets[23], object.version);
|
||||||
|
writer.writeString(offsets[24], object.versionLast);
|
||||||
}
|
}
|
||||||
|
|
||||||
Source _sourceDeserialize(
|
Source _sourceDeserialize(
|
||||||
|
|
@ -310,11 +317,14 @@ Source _sourceDeserialize(
|
||||||
lastUsed: reader.readBoolOrNull(offsets[17]),
|
lastUsed: reader.readBoolOrNull(offsets[17]),
|
||||||
name: reader.readStringOrNull(offsets[18]),
|
name: reader.readStringOrNull(offsets[18]),
|
||||||
sourceCode: reader.readStringOrNull(offsets[19]),
|
sourceCode: reader.readStringOrNull(offsets[19]),
|
||||||
sourceCodeUrl: reader.readStringOrNull(offsets[20]),
|
sourceCodeUrl: reader.readStringOrNull(offsets[21]),
|
||||||
typeSource: reader.readStringOrNull(offsets[21]),
|
typeSource: reader.readStringOrNull(offsets[22]),
|
||||||
version: reader.readStringOrNull(offsets[22]),
|
version: reader.readStringOrNull(offsets[23]),
|
||||||
versionLast: reader.readStringOrNull(offsets[23]),
|
versionLast: reader.readStringOrNull(offsets[24]),
|
||||||
);
|
);
|
||||||
|
object.sourceCodeLanguage = _SourcesourceCodeLanguageValueEnumMap[
|
||||||
|
reader.readByteOrNull(offsets[20])] ??
|
||||||
|
SourceCodeLanguage.dart;
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -366,18 +376,31 @@ P _sourceDeserializeProp<P>(
|
||||||
case 19:
|
case 19:
|
||||||
return (reader.readStringOrNull(offset)) as P;
|
return (reader.readStringOrNull(offset)) as P;
|
||||||
case 20:
|
case 20:
|
||||||
return (reader.readStringOrNull(offset)) as P;
|
return (_SourcesourceCodeLanguageValueEnumMap[
|
||||||
|
reader.readByteOrNull(offset)] ??
|
||||||
|
SourceCodeLanguage.dart) as P;
|
||||||
case 21:
|
case 21:
|
||||||
return (reader.readStringOrNull(offset)) as P;
|
return (reader.readStringOrNull(offset)) as P;
|
||||||
case 22:
|
case 22:
|
||||||
return (reader.readStringOrNull(offset)) as P;
|
return (reader.readStringOrNull(offset)) as P;
|
||||||
case 23:
|
case 23:
|
||||||
return (reader.readStringOrNull(offset)) as P;
|
return (reader.readStringOrNull(offset)) as P;
|
||||||
|
case 24:
|
||||||
|
return (reader.readStringOrNull(offset)) as P;
|
||||||
default:
|
default:
|
||||||
throw IsarError('Unknown property with id $propertyId');
|
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) {
|
Id _sourceGetId(Source object) {
|
||||||
return object.id ?? Isar.autoIncrement;
|
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() {
|
QueryBuilder<Source, Source, QAfterFilterCondition> sourceCodeUrlIsNull() {
|
||||||
return QueryBuilder.apply(this, (query) {
|
return QueryBuilder.apply(this, (query) {
|
||||||
return query.addFilterCondition(const FilterCondition.isNull(
|
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() {
|
QueryBuilder<Source, Source, QAfterSortBy> sortBySourceCodeUrl() {
|
||||||
return QueryBuilder.apply(this, (query) {
|
return QueryBuilder.apply(this, (query) {
|
||||||
return query.addSortBy(r'sourceCodeUrl', Sort.asc);
|
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() {
|
QueryBuilder<Source, Source, QAfterSortBy> thenBySourceCodeUrl() {
|
||||||
return QueryBuilder.apply(this, (query) {
|
return QueryBuilder.apply(this, (query) {
|
||||||
return query.addSortBy(r'sourceCodeUrl', Sort.asc);
|
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(
|
QueryBuilder<Source, Source, QDistinct> distinctBySourceCodeUrl(
|
||||||
{bool caseSensitive = true}) {
|
{bool caseSensitive = true}) {
|
||||||
return QueryBuilder.apply(this, (query) {
|
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() {
|
QueryBuilder<Source, String?, QQueryOperations> sourceCodeUrlProperty() {
|
||||||
return QueryBuilder.apply(this, (query) {
|
return QueryBuilder.apply(this, (query) {
|
||||||
return query.addPropertyName(r'sourceCodeUrl');
|
return query.addPropertyName(r'sourceCodeUrl');
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
import 'package:mangayomi/eval/javascript/http.dart';
|
||||||
|
|
||||||
class Video {
|
class Video {
|
||||||
String url;
|
String url;
|
||||||
String quality;
|
String quality;
|
||||||
|
|
@ -8,6 +10,24 @@ class Video {
|
||||||
|
|
||||||
Video(this.url, this.quality, this.originalUrl,
|
Video(this.url, this.quality, this.originalUrl,
|
||||||
{this.headers, this.subtitles, this.audios});
|
{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 {
|
class Track {
|
||||||
|
|
@ -19,4 +39,5 @@ class Track {
|
||||||
file = json['file'];
|
file = json['file'];
|
||||||
label = json['label'];
|
label = json['label'];
|
||||||
}
|
}
|
||||||
|
Map<String, dynamic> toJson() => {'file': file, 'label': label};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ part of 'state_provider.dart';
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
String _$subtitleSettingsStateHash() =>
|
String _$subtitleSettingsStateHash() =>
|
||||||
r'4f668c79675772a76d80585db43d041675d0d178';
|
r'4b89ea55392e662651d5aeee4dfce2fcd23ac0e7';
|
||||||
|
|
||||||
/// See also [SubtitleSettingsState].
|
/// See also [SubtitleSettingsState].
|
||||||
@ProviderFor(SubtitleSettingsState)
|
@ProviderFor(SubtitleSettingsState)
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import 'package:cached_network_image/cached_network_image.dart';
|
import 'package:cached_network_image/cached_network_image.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:mangayomi/eval/model/source_preference.dart';
|
import 'package:mangayomi/eval/dart/model/source_preference.dart';
|
||||||
import 'package:mangayomi/main.dart';
|
import 'package:mangayomi/main.dart';
|
||||||
import 'package:mangayomi/models/source.dart';
|
import 'package:mangayomi/models/source.dart';
|
||||||
import 'package:mangayomi/modules/browse/extension/providers/extension_preferences_providers.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> {
|
class _ExtensionDetailState extends ConsumerState<ExtensionDetail> {
|
||||||
late Source source = widget.source;
|
late Source source = widget.source;
|
||||||
late List<SourcePreference> sourcePreference =
|
List<SourcePreference> sourcePreference = [];
|
||||||
getSourcePreference(source: source)
|
@override
|
||||||
.map((e) => getSourcePreferenceEntry(e.key!, source.id!))
|
void initState() {
|
||||||
.toList();
|
getSourcePreferenceAsync(source: source).then((value) {
|
||||||
|
if (mounted) {
|
||||||
|
setState(() {
|
||||||
|
sourcePreference = value
|
||||||
|
.map((e) => getSourcePreferenceEntry(e.key!, source.id!))
|
||||||
|
.toList();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import 'package:isar/isar.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/main.dart';
|
||||||
import 'package:mangayomi/models/source.dart';
|
import 'package:mangayomi/models/source.dart';
|
||||||
import 'package:mangayomi/services/get_source_preference.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;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'package:dart_eval/stdlib/core.dart';
|
import 'package:dart_eval/stdlib/core.dart';
|
||||||
import 'package:mangayomi/eval/compiler/compiler.dart';
|
import 'package:mangayomi/eval/dart/compiler/compiler.dart';
|
||||||
import 'package:mangayomi/eval/runtime/runtime.dart';
|
import 'package:mangayomi/eval/dart/runtime/runtime.dart';
|
||||||
import 'package:mangayomi/main.dart';
|
import 'package:mangayomi/main.dart';
|
||||||
import 'package:mangayomi/models/source.dart';
|
import 'package:mangayomi/models/source.dart';
|
||||||
import 'package:mangayomi/modules/more/settings/browse/providers/browse_state_provider.dart';
|
import 'package:mangayomi/modules/more/settings/browse/providers/browse_state_provider.dart';
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import 'package:flutter/material.dart';
|
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/models/source.dart';
|
||||||
import 'package:mangayomi/modules/browse/extension/providers/extension_preferences_providers.dart';
|
import 'package:mangayomi/modules/browse/extension/providers/extension_preferences_providers.dart';
|
||||||
import 'package:mangayomi/modules/manga/detail/widgets/chapter_filter_list_tile_widget.dart';
|
import 'package:mangayomi/modules/manga/detail/widgets/chapter_filter_list_tile_widget.dart';
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,8 @@ import 'dart:typed_data';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:isar/isar.dart';
|
import 'package:isar/isar.dart';
|
||||||
import 'package:mangayomi/eval/model/m_manga.dart';
|
import 'package:mangayomi/eval/dart/model/m_manga.dart';
|
||||||
import 'package:mangayomi/eval/model/m_pages.dart';
|
import 'package:mangayomi/eval/dart/model/m_pages.dart';
|
||||||
import 'package:mangayomi/main.dart';
|
import 'package:mangayomi/main.dart';
|
||||||
import 'package:mangayomi/models/manga.dart';
|
import 'package:mangayomi/models/manga.dart';
|
||||||
import 'package:mangayomi/modules/manga/home/manga_home_screen.dart';
|
import 'package:mangayomi/modules/manga/home/manga_home_screen.dart';
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,14 @@
|
||||||
// ignore_for_file: use_build_context_synchronously
|
// ignore_for_file: use_build_context_synchronously
|
||||||
|
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
import 'dart:math';
|
||||||
import 'package:bot_toast/bot_toast.dart';
|
import 'package:bot_toast/bot_toast.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:isar/isar.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/main.dart';
|
||||||
import 'package:mangayomi/models/category.dart';
|
import 'package:mangayomi/models/category.dart';
|
||||||
import 'package:mangayomi/models/chapter.dart';
|
import 'package:mangayomi/models/chapter.dart';
|
||||||
|
|
@ -692,6 +694,7 @@ class _LibraryScreenState extends ConsumerState<LibraryScreen>
|
||||||
language: language,
|
language: language,
|
||||||
mangaIdsList: mangaIdsList,
|
mangaIdsList: mangaIdsList,
|
||||||
localSource: localSource,
|
localSource: localSource,
|
||||||
|
isManga: widget.isManga,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -765,6 +768,7 @@ class _LibraryScreenState extends ConsumerState<LibraryScreen>
|
||||||
language: language,
|
language: language,
|
||||||
mangaIdsList: mangaIdsList,
|
mangaIdsList: mangaIdsList,
|
||||||
localSource: localSource,
|
localSource: localSource,
|
||||||
|
isManga: widget.isManga,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -1345,7 +1349,7 @@ class _LibraryScreenState extends ConsumerState<LibraryScreen>
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(left: 20, top: 10),
|
padding: const EdgeInsets.only(left: 20, right: 20, top: 10),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
Text(l10n.display_mode),
|
Text(l10n.display_mode),
|
||||||
|
|
@ -1408,8 +1412,63 @@ class _LibraryScreenState extends ConsumerState<LibraryScreen>
|
||||||
// ),
|
// ),
|
||||||
).toList()),
|
).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(
|
||||||
padding: const EdgeInsets.only(left: 20, top: 10),
|
padding: const EdgeInsets.only(left: 20, right: 20, top: 10),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
Text(l10n.badges),
|
Text(l10n.badges),
|
||||||
|
|
@ -1469,7 +1528,7 @@ class _LibraryScreenState extends ConsumerState<LibraryScreen>
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(left: 20, top: 10),
|
padding: const EdgeInsets.only(left: 20, right: 20, top: 10),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [Text(l10n.tabs)],
|
children: [Text(l10n.tabs)],
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -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
|
@riverpod
|
||||||
class MangaFilterDownloadedState extends _$MangaFilterDownloadedState {
|
class MangaFilterDownloadedState extends _$MangaFilterDownloadedState {
|
||||||
@override
|
@override
|
||||||
|
|
|
||||||
|
|
@ -196,6 +196,151 @@ class _LibraryDisplayTypeStateProviderElement
|
||||||
Settings get settings => (origin as LibraryDisplayTypeStateProvider).settings;
|
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() =>
|
String _$mangaFilterDownloadedStateHash() =>
|
||||||
r'9c07e64580061bf2cbf892ef679274913aaa3b20';
|
r'9c07e64580061bf2cbf892ef679274913aaa3b20';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import 'package:mangayomi/main.dart';
|
||||||
import 'package:mangayomi/models/download.dart';
|
import 'package:mangayomi/models/download.dart';
|
||||||
import 'package:mangayomi/modules/history/providers/isar_providers.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/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/modules/manga/reader/providers/push_router.dart';
|
||||||
import 'package:mangayomi/models/manga.dart';
|
import 'package:mangayomi/models/manga.dart';
|
||||||
import 'package:mangayomi/utils/extensions/build_context_extensions.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/manga_image_card_widget.dart';
|
||||||
import 'package:mangayomi/modules/widgets/progress_center.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 isCoverOnlyGrid;
|
||||||
final bool isComfortableGrid;
|
final bool isComfortableGrid;
|
||||||
final List<int> mangaIdsList;
|
final List<int> mangaIdsList;
|
||||||
|
|
@ -29,6 +33,7 @@ class LibraryGridViewWidget extends StatelessWidget {
|
||||||
final bool downloadedChapter;
|
final bool downloadedChapter;
|
||||||
final bool continueReaderBtn;
|
final bool continueReaderBtn;
|
||||||
final bool localSource;
|
final bool localSource;
|
||||||
|
final bool isManga;
|
||||||
const LibraryGridViewWidget(
|
const LibraryGridViewWidget(
|
||||||
{super.key,
|
{super.key,
|
||||||
required this.entriesManga,
|
required this.entriesManga,
|
||||||
|
|
@ -38,271 +43,332 @@ class LibraryGridViewWidget extends StatelessWidget {
|
||||||
required this.downloadedChapter,
|
required this.downloadedChapter,
|
||||||
required this.continueReaderBtn,
|
required this.continueReaderBtn,
|
||||||
required this.mangaIdsList,
|
required this.mangaIdsList,
|
||||||
required this.localSource});
|
required this.localSource,
|
||||||
|
required this.isManga});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<LibraryGridViewWidget> createState() => _LibraryGridViewWidgetState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _LibraryGridViewWidgetState extends State<LibraryGridViewWidget> {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return GridViewWidget(
|
return Consumer(builder: (context, ref, child) {
|
||||||
childAspectRatio: isComfortableGrid ? 0.642 : 0.69,
|
final isLongPressed = ref.watch(isLongPressedMangaStateProvider);
|
||||||
itemCount: entriesManga.length,
|
final isManga = widget.isManga;
|
||||||
itemBuilder: (context, index) {
|
final height = ref.watch(isManga
|
||||||
final entry = entriesManga[index];
|
? mangaCardheightStateProvider
|
||||||
return Consumer(builder: (context, ref, child) {
|
: animeCardheightStateProvider);
|
||||||
bool isLocalArchive = entry.isLocalArchive ?? false;
|
final gridSize =
|
||||||
final isLongPressed = ref.watch(isLongPressedMangaStateProvider);
|
ref.watch(libraryGridSizeStateProvider(isManga: isManga));
|
||||||
return Padding(
|
return GridViewWidget(
|
||||||
padding: const EdgeInsets.all(2),
|
gridSize: gridSize,
|
||||||
child: CoverViewWidget(
|
childAspectRatio: widget.isComfortableGrid ? 0.642 : 0.69,
|
||||||
isLongPressed: mangaIdsList.contains(entry.id),
|
itemCount: widget.entriesManga.length,
|
||||||
bottomTextWidget: BottomTextWidget(
|
itemBuilder: (context, index) {
|
||||||
maxLines: 1,
|
final entry = widget.entriesManga[index];
|
||||||
text: entry.name!,
|
|
||||||
isComfortableGrid: isComfortableGrid,
|
return Builder(builder: (context) {
|
||||||
),
|
bool isLocalArchive = entry.isLocalArchive ?? false;
|
||||||
isComfortableGrid: isComfortableGrid,
|
return SizedBox(
|
||||||
image: entry.customCoverImage != null
|
height: height +
|
||||||
? MemoryImage(entry.customCoverImage as Uint8List)
|
(widget.isComfortableGrid &&
|
||||||
as ImageProvider
|
(gridSize != null && gridSize != 0)
|
||||||
: CachedNetworkImageProvider(
|
? 22
|
||||||
toImgUrl(entry.customCoverFromTracker ?? entry.imageUrl!),
|
: 0),
|
||||||
headers: entry.isLocalArchive!
|
child: MeasureWidgetSizeSync(
|
||||||
? null
|
onCalculateSize: (size) {
|
||||||
: ref.watch(headersProvider(
|
if (size != null) {
|
||||||
source: entry.source!, lang: entry.lang!)),
|
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: () {
|
isComfortableGrid: widget.isComfortableGrid,
|
||||||
if (isLongPressed) {
|
image: entry.customCoverImage != null
|
||||||
ref.read(mangasListStateProvider.notifier).update(entry);
|
? MemoryImage(entry.customCoverImage as Uint8List)
|
||||||
} else {
|
as ImageProvider
|
||||||
pushToMangaReaderDetail(
|
: CachedNetworkImageProvider(
|
||||||
archiveId: isLocalArchive ? entry.id : null,
|
toImgUrl(entry.customCoverFromTracker ??
|
||||||
context: context,
|
entry.imageUrl!),
|
||||||
lang: entry.lang!,
|
headers: entry.isLocalArchive!
|
||||||
mangaM: entry,
|
? null
|
||||||
source: entry.source!);
|
: ref.watch(headersProvider(
|
||||||
}
|
source: entry.source!, lang: entry.lang!)),
|
||||||
},
|
|
||||||
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),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
)),
|
onTap: () {
|
||||||
if (language && entry.lang!.isNotEmpty)
|
if (isLongPressed) {
|
||||||
Positioned(
|
ref
|
||||||
top: 0,
|
.read(mangasListStateProvider.notifier)
|
||||||
right: 0,
|
.update(entry);
|
||||||
child: Padding(
|
} else {
|
||||||
padding: const EdgeInsets.all(5),
|
pushToMangaReaderDetail(
|
||||||
child: Container(
|
archiveId: isLocalArchive ? entry.id : null,
|
||||||
color: context.themeData.cardColor,
|
context: context,
|
||||||
child: Container(
|
lang: entry.lang!,
|
||||||
decoration: BoxDecoration(
|
mangaM: entry,
|
||||||
borderRadius: const BorderRadius.only(
|
source: entry.source!);
|
||||||
topLeft: Radius.circular(3),
|
}
|
||||||
bottomLeft: Radius.circular(3)),
|
},
|
||||||
color: Theme.of(context).hintColor,
|
onLongPress: () {
|
||||||
),
|
if (!isLongPressed) {
|
||||||
child: Padding(
|
ref
|
||||||
padding:
|
.read(mangasListStateProvider.notifier)
|
||||||
const EdgeInsets.only(left: 3, right: 3),
|
.update(entry);
|
||||||
child: Text(
|
|
||||||
entry.lang!.toUpperCase(),
|
ref
|
||||||
style: const TextStyle(color: Colors.white),
|
.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 (widget.language && entry.lang!.isNotEmpty)
|
||||||
)),
|
Positioned(
|
||||||
],
|
top: 0,
|
||||||
),
|
right: 0,
|
||||||
if (!isComfortableGrid && !isCoverOnlyGrid)
|
child: Padding(
|
||||||
BottomTextWidget(text: entry.name!),
|
padding: const EdgeInsets.all(5),
|
||||||
if (continueReaderBtn)
|
child: Container(
|
||||||
Positioned(
|
color: context.themeData.cardColor,
|
||||||
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(
|
child: Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.circular(5),
|
borderRadius: const BorderRadius.only(
|
||||||
color: context.primaryColor
|
topLeft: Radius.circular(3),
|
||||||
.withOpacity(0.9),
|
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);
|
),
|
||||||
},
|
if (!widget.isComfortableGrid && !widget.isCoverOnlyGrid)
|
||||||
loading: () {
|
BottomTextWidget(text: entry.name!),
|
||||||
return const ProgressCenter();
|
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();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
)))
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
25
lib/modules/library/widgets/measure_widget_sync.dart
Normal file
25
lib/modules/library/widgets/measure_widget_sync.dart
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -8,7 +8,7 @@ import 'package:flutter/rendering.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:isar/isar.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/main.dart';
|
||||||
import 'package:mangayomi/models/chapter.dart';
|
import 'package:mangayomi/models/chapter.dart';
|
||||||
import 'package:mangayomi/models/download.dart';
|
import 'package:mangayomi/models/download.dart';
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import 'package:mangayomi/eval/model/m_bridge.dart';
|
import 'package:mangayomi/eval/dart/model/m_bridge.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/main.dart';
|
||||||
import 'package:mangayomi/models/chapter.dart';
|
import 'package:mangayomi/models/chapter.dart';
|
||||||
import 'package:mangayomi/models/manga.dart';
|
import 'package:mangayomi/models/manga.dart';
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,13 @@ import 'dart:io';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:mangayomi/eval/model/m_manga.dart';
|
import 'package:mangayomi/eval/dart/model/m_manga.dart';
|
||||||
import 'package:mangayomi/eval/model/m_pages.dart';
|
import 'package:mangayomi/eval/dart/model/m_pages.dart';
|
||||||
import 'package:mangayomi/models/settings.dart';
|
import 'package:mangayomi/models/settings.dart';
|
||||||
import 'package:mangayomi/models/source.dart';
|
import 'package:mangayomi/models/source.dart';
|
||||||
|
import 'package:mangayomi/modules/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/providers/state_provider.dart';
|
||||||
import 'package:mangayomi/modules/manga/home/widget/filter_widget.dart';
|
import 'package:mangayomi/modules/manga/home/widget/filter_widget.dart';
|
||||||
import 'package:mangayomi/modules/widgets/listview_widget.dart';
|
import 'package:mangayomi/modules/widgets/listview_widget.dart';
|
||||||
|
|
@ -119,11 +122,19 @@ class _MangaHomeScreenState extends ConsumerState<MangaHomeScreen> {
|
||||||
AsyncValue<MPages?>? _getManga;
|
AsyncValue<MPages?>? _getManga;
|
||||||
int _length = 0;
|
int _length = 0;
|
||||||
bool _isFiltering = false;
|
bool _isFiltering = false;
|
||||||
|
List<dynamic> filterList = [];
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
getFilterList(source: widget.source).then((value) => setState(() {
|
||||||
|
filterList = value;
|
||||||
|
}));
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final supportsLatest =
|
final supportsLatest =
|
||||||
ref.watch(supportsLatestProvider(source: widget.source));
|
ref.watch(supportsLatestProvider(source: widget.source));
|
||||||
final filterList = getFilterList(source: widget.source);
|
|
||||||
if (_selectedIndex == 2 && (_isSearch && _query.isNotEmpty) ||
|
if (_selectedIndex == 2 && (_isSearch && _query.isNotEmpty) ||
|
||||||
_isFiltering) {
|
_isFiltering) {
|
||||||
_getManga = ref.watch(searchProvider(
|
_getManga = ref.watch(searchProvider(
|
||||||
|
|
@ -328,8 +339,7 @@ class _MangaHomeScreenState extends ConsumerState<MangaHomeScreen> {
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
setState(() {
|
setState(() {
|
||||||
filters = getFilterList(
|
filters = filterList;
|
||||||
source: widget.source);
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
child: Text(l10n.reset),
|
child: Text(l10n.reset),
|
||||||
|
|
@ -521,23 +531,56 @@ class _MangaHomeScreenState extends ConsumerState<MangaHomeScreen> {
|
||||||
manga: _mangaList[index],
|
manga: _mangaList[index],
|
||||||
source: widget.source);
|
source: widget.source);
|
||||||
})
|
})
|
||||||
: GridViewWidget(
|
: Consumer(builder: (context, ref, child) {
|
||||||
controller: _scrollController,
|
final gridSize = ref.watch(
|
||||||
itemCount: _length + 1,
|
libraryGridSizeStateProvider(
|
||||||
childAspectRatio:
|
isManga: widget.source.isManga!));
|
||||||
isComfortableGrid ? 0.642 : 0.69,
|
final height = ref.watch(widget.source.isManga!
|
||||||
itemBuilder: (context, index) {
|
? mangaCardheightStateProvider
|
||||||
if (index == _length) {
|
: animeCardheightStateProvider);
|
||||||
return buildProgressIndicator();
|
return GridViewWidget(
|
||||||
}
|
gridSize: gridSize,
|
||||||
return MangaHomeImageCard(
|
controller: _scrollController,
|
||||||
isManga: widget.source.isManga ?? true,
|
itemCount: _length + 1,
|
||||||
manga: _mangaList[index],
|
childAspectRatio:
|
||||||
source: widget.source,
|
isComfortableGrid ? 0.642 : 0.69,
|
||||||
isComfortableGrid: isComfortableGrid,
|
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,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
})),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import 'package:flutter/material.dart';
|
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';
|
import 'package:mangayomi/utils/extensions/build_context_extensions.dart';
|
||||||
|
|
||||||
class FilterWidget extends StatelessWidget {
|
class FilterWidget extends StatelessWidget {
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,8 @@ import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:go_router/go_router.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/main.dart';
|
||||||
import 'package:mangayomi/messages/generated.dart';
|
|
||||||
import 'package:mangayomi/models/chapter.dart';
|
import 'package:mangayomi/models/chapter.dart';
|
||||||
import 'package:mangayomi/models/manga.dart';
|
import 'package:mangayomi/models/manga.dart';
|
||||||
import 'package:mangayomi/models/settings.dart';
|
import 'package:mangayomi/models/settings.dart';
|
||||||
|
|
@ -984,8 +983,6 @@ class _MangaChapterPageGalleryState
|
||||||
}
|
}
|
||||||
|
|
||||||
void _initCurrentIndex() async {
|
void _initCurrentIndex() async {
|
||||||
await finalizeRust();
|
|
||||||
await initializeRust();
|
|
||||||
final readerMode = _readerController.getReaderMode();
|
final readerMode = _readerController.getReaderMode();
|
||||||
_uChapDataPreload.addAll(_chapterUrlModel.uChapDataPreload);
|
_uChapDataPreload.addAll(_chapterUrlModel.uChapDataPreload);
|
||||||
_readerController.setMangaHistoryUpdate();
|
_readerController.setMangaHistoryUpdate();
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import 'dart:io';
|
||||||
import 'package:file_picker/file_picker.dart';
|
import 'package:file_picker/file_picker.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:mangayomi/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/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/auto_backup.dart';
|
||||||
import 'package:mangayomi/modules/more/backup_and_restore/providers/backup.dart';
|
import 'package:mangayomi/modules/more/backup_and_restore/providers/backup.dart';
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import 'package:archive/archive_io.dart';
|
||||||
import 'package:bot_toast/bot_toast.dart';
|
import 'package:bot_toast/bot_toast.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:isar/isar.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/main.dart';
|
||||||
import 'package:mangayomi/models/category.dart';
|
import 'package:mangayomi/models/category.dart';
|
||||||
import 'package:mangayomi/models/chapter.dart';
|
import 'package:mangayomi/models/chapter.dart';
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,8 @@ import 'dart:convert';
|
||||||
import 'package:archive/archive_io.dart';
|
import 'package:archive/archive_io.dart';
|
||||||
import 'package:bot_toast/bot_toast.dart';
|
import 'package:bot_toast/bot_toast.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:mangayomi/eval/model/m_bridge.dart';
|
import 'package:mangayomi/eval/dart/model/m_bridge.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/main.dart';
|
||||||
import 'package:mangayomi/models/category.dart';
|
import 'package:mangayomi/models/category.dart';
|
||||||
import 'package:mangayomi/models/chapter.dart';
|
import 'package:mangayomi/models/chapter.dart';
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ part of 'app_font_family.dart';
|
||||||
// RiverpodGenerator
|
// RiverpodGenerator
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
String _$appFontFamilyHash() => r'500f9cd0c0b0dd27d7026c4aa029c33fed337430';
|
String _$appFontFamilyHash() => r'7f115012111256848d806e47382db1f8abcff5ec';
|
||||||
|
|
||||||
/// See also [AppFontFamily].
|
/// See also [AppFontFamily].
|
||||||
@ProviderFor(AppFontFamily)
|
@ProviderFor(AppFontFamily)
|
||||||
|
|
|
||||||
|
|
@ -46,12 +46,9 @@ class CoverViewWidget extends StatelessWidget {
|
||||||
children: children,
|
children: children,
|
||||||
)
|
)
|
||||||
: Ink.image(
|
: Ink.image(
|
||||||
height: 200,
|
|
||||||
fit: BoxFit.cover,
|
fit: BoxFit.cover,
|
||||||
image: image!,
|
image: image!,
|
||||||
child: Stack(
|
child: Stack(children: children),
|
||||||
children: children,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
)),
|
)),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -6,27 +6,32 @@ class GridViewWidget extends StatelessWidget {
|
||||||
final bool reverse;
|
final bool reverse;
|
||||||
final double? childAspectRatio;
|
final double? childAspectRatio;
|
||||||
final Widget? Function(BuildContext, int) itemBuilder;
|
final Widget? Function(BuildContext, int) itemBuilder;
|
||||||
|
final int? gridSize;
|
||||||
const GridViewWidget(
|
const GridViewWidget(
|
||||||
{super.key,
|
{super.key,
|
||||||
this.controller,
|
this.controller,
|
||||||
required this.itemCount,
|
required this.itemCount,
|
||||||
required this.itemBuilder,
|
required this.itemBuilder,
|
||||||
this.reverse = false,
|
this.reverse = false,
|
||||||
this.childAspectRatio = 0.69});
|
this.childAspectRatio = 0.69,
|
||||||
|
this.gridSize});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Container(
|
return Container(
|
||||||
color: Theme.of(context).scaffoldBackgroundColor,
|
color: Theme.of(context).scaffoldBackgroundColor,
|
||||||
child: GridView.builder(
|
child: GridView.builder(
|
||||||
padding: const EdgeInsets.only(top: 13),
|
padding: const EdgeInsets.only(top: 13),
|
||||||
controller: controller,
|
controller: controller,
|
||||||
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
|
gridDelegate: (gridSize == null || gridSize == 0)
|
||||||
childAspectRatio: childAspectRatio!,
|
? SliverGridDelegateWithMaxCrossAxisExtent(
|
||||||
maxCrossAxisExtent: 220,
|
childAspectRatio: childAspectRatio!,
|
||||||
),
|
maxCrossAxisExtent: 220,
|
||||||
itemCount: itemCount,
|
)
|
||||||
itemBuilder: itemBuilder),
|
: SliverGridDelegateWithFixedCrossAxisCount(
|
||||||
);
|
crossAxisCount: gridSize!,
|
||||||
|
childAspectRatio: childAspectRatio!),
|
||||||
|
itemCount: itemCount,
|
||||||
|
itemBuilder: itemBuilder));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:isar/isar.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/main.dart';
|
||||||
import 'package:mangayomi/models/manga.dart';
|
import 'package:mangayomi/models/manga.dart';
|
||||||
import 'package:mangayomi/models/settings.dart';
|
import 'package:mangayomi/models/settings.dart';
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
// ignore_for_file: depend_on_referenced_packages
|
// ignore_for_file: depend_on_referenced_packages
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'package:isar/isar.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/main.dart';
|
||||||
import 'package:mangayomi/models/category.dart';
|
import 'package:mangayomi/models/category.dart';
|
||||||
import 'package:mangayomi/models/chapter.dart';
|
import 'package:mangayomi/models/chapter.dart';
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'package:html/dom.dart';
|
import 'package:html/dom.dart';
|
||||||
import 'package:http_interceptor/http_interceptor.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:mangayomi/models/video.dart';
|
||||||
import 'package:html/parser.dart' as parser;
|
import 'package:html/parser.dart' as parser;
|
||||||
import 'package:mangayomi/services/http/interceptor.dart';
|
import 'package:mangayomi/services/http/interceptor.dart';
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,18 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
import 'package:mangayomi/eval/bridge/m_source.dart';
|
import 'package:mangayomi/eval/dart/bridge/m_source.dart';
|
||||||
import 'package:mangayomi/eval/compiler/compiler.dart';
|
import 'package:mangayomi/eval/dart/compiler/compiler.dart';
|
||||||
import 'package:mangayomi/eval/model/m_provider.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/main.dart';
|
||||||
import 'package:mangayomi/messages/generated.dart';
|
|
||||||
import 'package:mangayomi/models/chapter.dart';
|
import 'package:mangayomi/models/chapter.dart';
|
||||||
import 'package:mangayomi/models/settings.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/archive_reader/providers/archive_reader_providers.dart';
|
||||||
import 'package:mangayomi/modules/manga/reader/reader_view.dart';
|
import 'package:mangayomi/modules/manga/reader/reader_view.dart';
|
||||||
import 'package:mangayomi/providers/storage_provider.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/sources/utils/utils.dart';
|
||||||
import 'package:mangayomi/utils/reg_exp_matcher.dart';
|
import 'package:mangayomi/utils/reg_exp_matcher.dart';
|
||||||
import 'package:mangayomi/modules/more/providers/incognito_mode_state_provider.dart';
|
import 'package:mangayomi/modules/more/providers/incognito_mode_state_provider.dart';
|
||||||
|
|
@ -62,16 +63,18 @@ Future<GetChapterPagesModel> getChapterPages(
|
||||||
isarPageUrls.first.urls!.isNotEmpty) {
|
isarPageUrls.first.urls!.isNotEmpty) {
|
||||||
pageUrls = isarPageUrls.first.urls!;
|
pageUrls = isarPageUrls.first.urls!;
|
||||||
} else {
|
} else {
|
||||||
await finalizeRust();
|
if (source.sourceCodeLanguage == SourceCodeLanguage.dart) {
|
||||||
await initializeRust();
|
final bytecode = compilerEval(
|
||||||
final bytecode =
|
useTestSourceCode ? testSourceCode : source.sourceCode!);
|
||||||
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
|
|
||||||
|
|
||||||
final runtime = runtimeEval(bytecode);
|
final runtime = runtimeEval(bytecode);
|
||||||
|
|
||||||
var res = await runtime.executeLib('package:mangayomi/main.dart', 'main',
|
var res = await runtime.executeLib('package:mangayomi/main.dart',
|
||||||
[$MSource.wrap(source.toMSource())]);
|
'main', [$MSource.wrap(source.toMSource())]);
|
||||||
pageUrls = (await (res as MProvider).getPageList(chapter.url!));
|
pageUrls = (await (res as MProvider).getPageList(chapter.url!));
|
||||||
|
} else {
|
||||||
|
pageUrls = await JsExtensionService(source).getPageList(chapter.url!);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ part of 'get_chapter_pages.dart';
|
||||||
// RiverpodGenerator
|
// RiverpodGenerator
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
String _$getChapterPagesHash() => r'aa95d95504a7f52e22bd3886782a9ef4443453e9';
|
String _$getChapterPagesHash() => r'e637b2e307606818eae08438d3c98aaec0ae0a00';
|
||||||
|
|
||||||
/// Copied from Dart SDK
|
/// Copied from Dart SDK
|
||||||
class _SystemHash {
|
class _SystemHash {
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'package:mangayomi/eval/bridge/m_source.dart';
|
import 'package:mangayomi/eval/dart/bridge/m_source.dart';
|
||||||
import 'package:mangayomi/eval/model/m_manga.dart';
|
import 'package:mangayomi/eval/javascript/service.dart';
|
||||||
import 'package:mangayomi/eval/compiler/compiler.dart';
|
import 'package:mangayomi/eval/dart/model/m_manga.dart';
|
||||||
import 'package:mangayomi/eval/model/m_provider.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/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:mangayomi/sources/source_test.dart';
|
||||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||||
part 'get_detail.g.dart';
|
part 'get_detail.g.dart';
|
||||||
|
|
@ -16,17 +17,21 @@ Future<MManga> getDetail(
|
||||||
required Source source,
|
required Source source,
|
||||||
}) async {
|
}) async {
|
||||||
MManga? mangadetail;
|
MManga? mangadetail;
|
||||||
final bytecode =
|
if (source.sourceCodeLanguage == SourceCodeLanguage.dart) {
|
||||||
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
|
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',
|
var res = await runtime.executeLib('package:mangayomi/main.dart', 'main',
|
||||||
[$MSource.wrap(source.toMSource())]);
|
[$MSource.wrap(source.toMSource())]);
|
||||||
try {
|
try {
|
||||||
mangadetail = await (res as MProvider).getDetail(url);
|
mangadetail = await (res as MProvider).getDetail(url);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw Exception(e);
|
throw Exception(e);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mangadetail = await JsExtensionService(source).getDetail(url);
|
||||||
}
|
}
|
||||||
return mangadetail;
|
return mangadetail;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ part of 'get_detail.dart';
|
||||||
// RiverpodGenerator
|
// RiverpodGenerator
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
String _$getDetailHash() => r'a1808953ca93c379c91b3e280a298c0852cebb34';
|
String _$getDetailHash() => r'a3e63c6d6a5ad9eccea268080f5506344677032b';
|
||||||
|
|
||||||
/// Copied from Dart SDK
|
/// Copied from Dart SDK
|
||||||
class _SystemHash {
|
class _SystemHash {
|
||||||
|
|
|
||||||
|
|
@ -1,28 +1,32 @@
|
||||||
import 'package:dart_eval/dart_eval_bridge.dart';
|
import 'package:dart_eval/dart_eval_bridge.dart';
|
||||||
import 'package:mangayomi/eval/bridge/m_source.dart';
|
import 'package:mangayomi/eval/dart/bridge/m_source.dart';
|
||||||
import 'package:mangayomi/eval/compiler/compiler.dart';
|
import 'package:mangayomi/eval/dart/compiler/compiler.dart';
|
||||||
import 'package:mangayomi/eval/model/m_provider.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/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:mangayomi/sources/source_test.dart';
|
||||||
|
|
||||||
List<dynamic> getFilterList({required Source source}) {
|
Future<List<dynamic>> getFilterList({required Source source}) async {
|
||||||
List<dynamic> filterList = [];
|
List<dynamic> filterList = [];
|
||||||
|
if (source.sourceCodeLanguage == SourceCodeLanguage.dart) {
|
||||||
|
try {
|
||||||
|
final bytecode =
|
||||||
|
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
|
||||||
|
|
||||||
try {
|
final runtime = runtimeEval(bytecode);
|
||||||
final bytecode =
|
|
||||||
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
|
|
||||||
|
|
||||||
final runtime = runtimeEval(bytecode);
|
var res = runtime.executeLib('package:mangayomi/main.dart', 'main',
|
||||||
|
[$MSource.wrap(source.toMSource())]);
|
||||||
var res = runtime.executeLib('package:mangayomi/main.dart', 'main',
|
filterList = (res as MProvider)
|
||||||
[$MSource.wrap(source.toMSource())]);
|
.getFilterList()
|
||||||
filterList = (res as MProvider)
|
.map((e) => e is $Value ? e.$reified : e)
|
||||||
.getFilterList()
|
.toList();
|
||||||
.map((e) => e is $Value ? e.$reified : e)
|
} catch (_) {
|
||||||
.toList();
|
return [];
|
||||||
} catch (_) {
|
}
|
||||||
return [];
|
} else {
|
||||||
|
filterList = (await JsExtensionService(source).getFilterList()).filters;
|
||||||
}
|
}
|
||||||
|
|
||||||
return filterList;
|
return filterList;
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'package:mangayomi/eval/bridge/m_source.dart';
|
import 'package:mangayomi/eval/dart/bridge/m_source.dart';
|
||||||
import 'package:mangayomi/eval/model/m_pages.dart';
|
import 'package:mangayomi/eval/javascript/service.dart';
|
||||||
import 'package:mangayomi/eval/compiler/compiler.dart';
|
import 'package:mangayomi/eval/dart/model/m_pages.dart';
|
||||||
import 'package:mangayomi/eval/model/m_provider.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/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:mangayomi/sources/source_test.dart';
|
||||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||||
part 'get_latest_updates.g.dart';
|
part 'get_latest_updates.g.dart';
|
||||||
|
|
@ -16,19 +17,22 @@ Future<MPages?> getLatestUpdates(
|
||||||
required int page,
|
required int page,
|
||||||
}) async {
|
}) async {
|
||||||
MPages? latestUpdatesManga;
|
MPages? latestUpdatesManga;
|
||||||
|
if (source.sourceCodeLanguage == SourceCodeLanguage.dart) {
|
||||||
|
try {
|
||||||
|
final bytecode =
|
||||||
|
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
|
||||||
|
|
||||||
try {
|
final runtime = runtimeEval(bytecode);
|
||||||
final bytecode =
|
|
||||||
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
|
|
||||||
|
|
||||||
final runtime = runtimeEval(bytecode);
|
var res = await runtime.executeLib('package:mangayomi/main.dart', 'main',
|
||||||
|
[$MSource.wrap(source.toMSource())]);
|
||||||
var res = await runtime.executeLib('package:mangayomi/main.dart', 'main',
|
latestUpdatesManga = await (res as MProvider).getLatestUpdates(page);
|
||||||
[$MSource.wrap(source.toMSource())]);
|
} catch (e) {
|
||||||
latestUpdatesManga = await (res as MProvider).getLatestUpdates(page);
|
throw Exception(e);
|
||||||
} catch (e) {
|
}
|
||||||
throw Exception(e);
|
} else {
|
||||||
|
latestUpdatesManga =
|
||||||
|
await JsExtensionService(source).getLatestUpdates(page);
|
||||||
}
|
}
|
||||||
|
|
||||||
return latestUpdatesManga;
|
return latestUpdatesManga;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ part of 'get_latest_updates.dart';
|
||||||
// RiverpodGenerator
|
// RiverpodGenerator
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
String _$getLatestUpdatesHash() => r'288b2ce3b2e79c1924c8e2a312282900fd9e645f';
|
String _$getLatestUpdatesHash() => r'89ccdaf3b19ee84b2d61fd66301ef6d6eefbe797';
|
||||||
|
|
||||||
/// Copied from Dart SDK
|
/// Copied from Dart SDK
|
||||||
class _SystemHash {
|
class _SystemHash {
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'package:mangayomi/eval/bridge/m_source.dart';
|
import 'package:mangayomi/eval/dart/bridge/m_source.dart';
|
||||||
import 'package:mangayomi/eval/model/m_pages.dart';
|
import 'package:mangayomi/eval/javascript/service.dart';
|
||||||
import 'package:mangayomi/eval/compiler/compiler.dart';
|
import 'package:mangayomi/eval/dart/model/m_pages.dart';
|
||||||
import 'package:mangayomi/eval/model/m_provider.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/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:mangayomi/sources/source_test.dart';
|
||||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||||
part 'get_popular.g.dart';
|
part 'get_popular.g.dart';
|
||||||
|
|
@ -16,18 +17,21 @@ Future<MPages?> getPopular(
|
||||||
required int page,
|
required int page,
|
||||||
}) async {
|
}) async {
|
||||||
MPages? popularManga;
|
MPages? popularManga;
|
||||||
|
if (source.sourceCodeLanguage == SourceCodeLanguage.dart) {
|
||||||
|
try {
|
||||||
|
final bytecode =
|
||||||
|
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
|
||||||
|
|
||||||
try {
|
final runtime = runtimeEval(bytecode);
|
||||||
final bytecode =
|
|
||||||
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
|
|
||||||
|
|
||||||
final runtime = runtimeEval(bytecode);
|
var res = runtime.executeLib('package:mangayomi/main.dart', 'main',
|
||||||
|
[$MSource.wrap(source.toMSource())]);
|
||||||
var res = runtime.executeLib('package:mangayomi/main.dart', 'main',
|
popularManga = await (res as MProvider).getPopular(page);
|
||||||
[$MSource.wrap(source.toMSource())]);
|
} catch (e) {
|
||||||
popularManga = await (res as MProvider).getPopular(page);
|
throw Exception(e);
|
||||||
} catch (e) {
|
}
|
||||||
throw Exception(e);
|
} else {
|
||||||
|
popularManga = await JsExtensionService(source).getPopular(page);
|
||||||
}
|
}
|
||||||
|
|
||||||
return popularManga;
|
return popularManga;
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ part of 'get_popular.dart';
|
||||||
// RiverpodGenerator
|
// RiverpodGenerator
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
String _$getPopularHash() => r'd78a01ea5854ad3f592e713e4f4052929774e78e';
|
String _$getPopularHash() => r'81c132dc4a1dc78a5bedb69eb33a7f6fdb9bff16';
|
||||||
|
|
||||||
/// Copied from Dart SDK
|
/// Copied from Dart SDK
|
||||||
class _SystemHash {
|
class _SystemHash {
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
import 'package:mangayomi/eval/bridge/m_source.dart';
|
import 'package:mangayomi/eval/dart/bridge/m_source.dart';
|
||||||
import 'package:mangayomi/eval/compiler/compiler.dart';
|
import 'package:mangayomi/eval/dart/compiler/compiler.dart';
|
||||||
import 'package:mangayomi/eval/model/m_provider.dart';
|
import 'package:mangayomi/eval/dart/model/m_provider.dart';
|
||||||
import 'package:mangayomi/models/source.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:mangayomi/sources/source_test.dart';
|
||||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||||
part 'get_source_baseurl.g.dart';
|
part 'get_source_baseurl.g.dart';
|
||||||
|
|
@ -10,19 +10,20 @@ part 'get_source_baseurl.g.dart';
|
||||||
@riverpod
|
@riverpod
|
||||||
String sourceBaseUrl(SourceBaseUrlRef ref, {required Source source}) {
|
String sourceBaseUrl(SourceBaseUrlRef ref, {required Source source}) {
|
||||||
String? baseUrl;
|
String? baseUrl;
|
||||||
|
if (source.sourceCodeLanguage == SourceCodeLanguage.dart) {
|
||||||
|
try {
|
||||||
|
final bytecode =
|
||||||
|
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
|
||||||
|
|
||||||
try {
|
final runtime = runtimeEval(bytecode);
|
||||||
final bytecode =
|
|
||||||
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
|
|
||||||
|
|
||||||
final runtime = runtimeEval(bytecode);
|
var res = runtime.executeLib('package:mangayomi/main.dart', 'main',
|
||||||
|
[$MSource.wrap(source.toMSource())]);
|
||||||
var res = runtime.executeLib('package:mangayomi/main.dart', 'main',
|
baseUrl = (res as MProvider).baseUrl;
|
||||||
[$MSource.wrap(source.toMSource())]);
|
} catch (e) {
|
||||||
baseUrl = (res as MProvider).baseUrl;
|
baseUrl = source.baseUrl;
|
||||||
} catch (e) {
|
}
|
||||||
baseUrl = source.baseUrl;
|
} else {}
|
||||||
}
|
|
||||||
if (baseUrl == null || baseUrl.isEmpty) {
|
if (baseUrl == null || baseUrl.isEmpty) {
|
||||||
baseUrl = source.baseUrl;
|
baseUrl = source.baseUrl;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ part of 'get_source_baseurl.dart';
|
||||||
// RiverpodGenerator
|
// RiverpodGenerator
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
String _$sourceBaseUrlHash() => r'232addc3559f2b77974224a5ed8813eee9a0ba8e';
|
String _$sourceBaseUrlHash() => r'1e4352256b54a61220c09e719e2d0fa907bf6cd9';
|
||||||
|
|
||||||
/// Copied from Dart SDK
|
/// Copied from Dart SDK
|
||||||
class _SystemHash {
|
class _SystemHash {
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
import 'package:dart_eval/dart_eval_bridge.dart';
|
import 'package:dart_eval/dart_eval_bridge.dart';
|
||||||
import 'package:mangayomi/eval/bridge/m_source.dart';
|
import 'package:mangayomi/eval/dart/bridge/m_source.dart';
|
||||||
import 'package:mangayomi/eval/compiler/compiler.dart';
|
import 'package:mangayomi/eval/dart/compiler/compiler.dart';
|
||||||
import 'package:mangayomi/eval/model/m_provider.dart';
|
import 'package:mangayomi/eval/javascript/service.dart';
|
||||||
import 'package:mangayomi/eval/model/source_preference.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/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> getSourcePreference({required Source source}) {
|
||||||
List<SourcePreference> sourcePreference = [];
|
List<SourcePreference> sourcePreference = [];
|
||||||
|
|
@ -26,3 +27,28 @@ List<SourcePreference> getSourcePreference({required Source source}) {
|
||||||
|
|
||||||
return sourcePreference;
|
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;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,11 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'package:mangayomi/eval/bridge/m_source.dart';
|
import 'package:mangayomi/eval/dart/bridge/m_source.dart';
|
||||||
import 'package:mangayomi/eval/model/m_provider.dart';
|
import 'package:mangayomi/eval/dart/model/m_provider.dart';
|
||||||
import 'package:mangayomi/eval/compiler/compiler.dart';
|
import 'package:mangayomi/eval/dart/compiler/compiler.dart';
|
||||||
import 'package:mangayomi/messages/generated.dart';
|
|
||||||
import 'package:mangayomi/models/chapter.dart';
|
import 'package:mangayomi/models/chapter.dart';
|
||||||
import 'package:mangayomi/models/video.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/providers/storage_provider.dart';
|
||||||
import 'package:mangayomi/services/torrent_server.dart';
|
import 'package:mangayomi/services/torrent_server.dart';
|
||||||
import 'package:mangayomi/sources/utils/utils.dart';
|
import 'package:mangayomi/sources/utils/utils.dart';
|
||||||
|
|
@ -37,8 +36,7 @@ Future<(List<Video>, bool, String?)> getVideoList(
|
||||||
await MTorrentServer().getTorrentPlaylist(episode.url!);
|
await MTorrentServer().getTorrentPlaylist(episode.url!);
|
||||||
return (videos, false, infohash);
|
return (videos, false, infohash);
|
||||||
}
|
}
|
||||||
await finalizeRust();
|
|
||||||
await initializeRust();
|
|
||||||
final bytecode =
|
final bytecode =
|
||||||
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
|
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ part of 'get_video_list.dart';
|
||||||
// RiverpodGenerator
|
// RiverpodGenerator
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
String _$getVideoListHash() => r'dd1908b1174efac883d05862ea55febf09ad976c';
|
String _$getVideoListHash() => r'dd53ef51fd6c729a985644336d467507e5c7923d';
|
||||||
|
|
||||||
/// Copied from Dart SDK
|
/// Copied from Dart SDK
|
||||||
class _SystemHash {
|
class _SystemHash {
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:http_interceptor/http_interceptor.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:async';
|
||||||
import 'dart:io';
|
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:mangayomi/main.dart';
|
||||||
import 'package:flutter_inappwebview/flutter_inappwebview.dart'
|
import 'package:flutter_inappwebview/flutter_inappwebview.dart'
|
||||||
as flutter_inappwebview;
|
as flutter_inappwebview;
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,12 @@
|
||||||
import 'package:mangayomi/eval/bridge/m_source.dart';
|
import 'dart:convert';
|
||||||
import 'package:mangayomi/eval/model/filter.dart';
|
import 'package:mangayomi/eval/dart/bridge/m_source.dart';
|
||||||
import 'package:mangayomi/eval/model/m_pages.dart';
|
import 'package:mangayomi/eval/javascript/service.dart';
|
||||||
import 'package:mangayomi/eval/compiler/compiler.dart';
|
import 'package:mangayomi/eval/dart/model/filter.dart';
|
||||||
import 'package:mangayomi/eval/model/m_provider.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/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:mangayomi/sources/source_test.dart';
|
||||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||||
part 'search.g.dart';
|
part 'search.g.dart';
|
||||||
|
|
@ -16,16 +18,21 @@ Future<MPages?> search(SearchRef ref,
|
||||||
required int page,
|
required int page,
|
||||||
required List<dynamic> filterList}) async {
|
required List<dynamic> filterList}) async {
|
||||||
MPages? manga;
|
MPages? manga;
|
||||||
final bytecode =
|
if (source.sourceCodeLanguage == SourceCodeLanguage.dart) {
|
||||||
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
|
final bytecode =
|
||||||
final runtime = runtimeEval(bytecode);
|
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
|
||||||
var res = runtime.executeLib('package:mangayomi/main.dart', 'main',
|
final runtime = runtimeEval(bytecode);
|
||||||
[$MSource.wrap(source.toMSource())]);
|
var res = runtime.executeLib('package:mangayomi/main.dart', 'main',
|
||||||
try {
|
[$MSource.wrap(source.toMSource())]);
|
||||||
manga =
|
try {
|
||||||
await (res as MProvider).search(query, page, FilterList(filterList));
|
manga =
|
||||||
} catch (e) {
|
await (res as MProvider).search(query, page, FilterList(filterList));
|
||||||
throw Exception(e);
|
} catch (e) {
|
||||||
|
throw Exception(e);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
manga = await JsExtensionService(source)
|
||||||
|
.search(query, page, jsonEncode(filterValuesListToJson(filterList)));
|
||||||
}
|
}
|
||||||
return manga;
|
return manga;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ part of 'search.dart';
|
||||||
// RiverpodGenerator
|
// RiverpodGenerator
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
String _$searchHash() => r'685e379023d83ede702d76696d64fccb803e5549';
|
String _$searchHash() => r'aa2fdda26ef0178495a18e0dec5a4bd7f9792fc7';
|
||||||
|
|
||||||
/// Copied from Dart SDK
|
/// Copied from Dart SDK
|
||||||
class _SystemHash {
|
class _SystemHash {
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,13 @@
|
||||||
import 'package:mangayomi/eval/bridge/m_source.dart';
|
import 'dart:convert';
|
||||||
import 'package:mangayomi/eval/model/filter.dart';
|
|
||||||
import 'package:mangayomi/eval/model/m_pages.dart';
|
import 'package:mangayomi/eval/dart/bridge/m_source.dart';
|
||||||
import 'package:mangayomi/eval/compiler/compiler.dart';
|
import 'package:mangayomi/eval/javascript/service.dart';
|
||||||
import 'package:mangayomi/eval/model/m_provider.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/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:mangayomi/sources/source_test.dart';
|
||||||
|
|
||||||
Future<MPages?> search(
|
Future<MPages?> search(
|
||||||
|
|
@ -13,16 +16,21 @@ Future<MPages?> search(
|
||||||
required int page,
|
required int page,
|
||||||
required List<dynamic> filterList}) async {
|
required List<dynamic> filterList}) async {
|
||||||
MPages? manga;
|
MPages? manga;
|
||||||
final bytecode =
|
if (source.sourceCodeLanguage == SourceCodeLanguage.dart) {
|
||||||
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
|
final bytecode =
|
||||||
final runtime = runtimeEval(bytecode);
|
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
|
||||||
var res = runtime.executeLib('package:mangayomi/main.dart', 'main',
|
final runtime = runtimeEval(bytecode);
|
||||||
[$MSource.wrap(source.toMSource())]);
|
var res = runtime.executeLib('package:mangayomi/main.dart', 'main',
|
||||||
try {
|
[$MSource.wrap(source.toMSource())]);
|
||||||
manga =
|
try {
|
||||||
await (res as MProvider).search(query, page, FilterList(filterList));
|
manga =
|
||||||
} catch (e) {
|
await (res as MProvider).search(query, page, FilterList(filterList));
|
||||||
throw Exception(e);
|
} catch (e) {
|
||||||
|
throw Exception(e);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
manga = await JsExtensionService(source)
|
||||||
|
.search(query, page, jsonEncode(filterValuesListToJson(filterList)));
|
||||||
}
|
}
|
||||||
return manga;
|
return manga;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
import 'package:mangayomi/eval/bridge/m_source.dart';
|
import 'package:mangayomi/eval/dart/bridge/m_source.dart';
|
||||||
import 'package:mangayomi/eval/compiler/compiler.dart';
|
import 'package:mangayomi/eval/dart/compiler/compiler.dart';
|
||||||
import 'package:mangayomi/eval/model/m_provider.dart';
|
import 'package:mangayomi/eval/dart/model/m_provider.dart';
|
||||||
import 'package:mangayomi/models/source.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:mangayomi/sources/source_test.dart';
|
||||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||||
part 'supports_latest.g.dart';
|
part 'supports_latest.g.dart';
|
||||||
|
|
@ -10,19 +10,21 @@ part 'supports_latest.g.dart';
|
||||||
@riverpod
|
@riverpod
|
||||||
bool supportsLatest(SupportsLatestRef ref, {required Source source}) {
|
bool supportsLatest(SupportsLatestRef ref, {required Source source}) {
|
||||||
bool? supportsLatest;
|
bool? supportsLatest;
|
||||||
|
if (source.sourceCodeLanguage == SourceCodeLanguage.dart) {
|
||||||
|
try {
|
||||||
|
final bytecode =
|
||||||
|
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
|
||||||
|
|
||||||
try {
|
final runtime = runtimeEval(bytecode);
|
||||||
final bytecode =
|
|
||||||
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
|
|
||||||
|
|
||||||
final runtime = runtimeEval(bytecode);
|
var res = runtime.executeLib('package:mangayomi/main.dart', 'main',
|
||||||
|
[$MSource.wrap(source.toMSource())]);
|
||||||
var res = runtime.executeLib('package:mangayomi/main.dart', 'main',
|
supportsLatest = (res as MProvider).supportsLatest;
|
||||||
[$MSource.wrap(source.toMSource())]);
|
} catch (e) {
|
||||||
supportsLatest = (res as MProvider).supportsLatest;
|
supportsLatest = true;
|
||||||
} catch (e) {
|
}
|
||||||
|
} else {
|
||||||
supportsLatest = true;
|
supportsLatest = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return supportsLatest;
|
return supportsLatest;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue