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:html/dom.dart';
|
||||
import 'package:mangayomi/eval/bridge/element.dart';
|
||||
import 'package:mangayomi/eval/model/document.dart';
|
||||
import 'package:mangayomi/eval/model/element.dart';
|
||||
import 'package:mangayomi/eval/dart/bridge/element.dart';
|
||||
import 'package:mangayomi/eval/dart/model/document.dart';
|
||||
import 'package:mangayomi/eval/dart/model/element.dart';
|
||||
|
||||
class $MDocument implements MDocument, $Instance {
|
||||
$MDocument.wrap(this.$value) : _superclass = $Object($value);
|
||||
|
|
@ -131,6 +131,17 @@ class $MDocument implements MDocument, $Instance {
|
|||
false)
|
||||
]),
|
||||
),
|
||||
'attr': BridgeMethodDef(
|
||||
BridgeFunctionDef(
|
||||
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)),
|
||||
params: [
|
||||
BridgeParameter(
|
||||
'attr',
|
||||
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string),
|
||||
nullable: true),
|
||||
false)
|
||||
]),
|
||||
),
|
||||
},
|
||||
wrap: true);
|
||||
|
||||
|
|
@ -182,6 +193,8 @@ class $MDocument implements MDocument, $Instance {
|
|||
return __xpath;
|
||||
case 'xpathFirst':
|
||||
return __xpathFirst;
|
||||
case 'attr':
|
||||
return __attr;
|
||||
default:
|
||||
return _superclass.$getProperty(runtime, identifier);
|
||||
}
|
||||
|
|
@ -257,6 +270,13 @@ class $MDocument implements MDocument, $Instance {
|
|||
return res == null ? const $null() : $String(res);
|
||||
}
|
||||
|
||||
static const $Function __attr = $Function(_attr);
|
||||
static $Value? _attr(
|
||||
final Runtime runtime, final $Value? target, final List<$Value?> args) {
|
||||
final res = (target!.$value as MDocument).attr(args[0]?.$value ?? "");
|
||||
return res == null ? const $null() : $String(res);
|
||||
}
|
||||
|
||||
@override
|
||||
List<MElement>? select(String selector) => $value.select(selector);
|
||||
|
||||
|
|
@ -277,6 +297,9 @@ class $MDocument implements MDocument, $Instance {
|
|||
List<MElement>? getElementsByTagName(String localNames) =>
|
||||
$value.getElementsByTagName(localNames);
|
||||
|
||||
@override
|
||||
String? attr(String attr) => $value.attr(attr);
|
||||
|
||||
@override
|
||||
MElement? getElementById(String id) => $value.getElementById(id);
|
||||
|
||||
|
|
@ -2,7 +2,7 @@ import 'package:dart_eval/dart_eval.dart';
|
|||
import 'package:dart_eval/dart_eval_bridge.dart';
|
||||
import 'package:dart_eval/stdlib/core.dart';
|
||||
import 'package:html/dom.dart';
|
||||
import 'package:mangayomi/eval/model/element.dart';
|
||||
import 'package:mangayomi/eval/dart/model/element.dart';
|
||||
|
||||
class $MElement implements MElement, $Instance {
|
||||
$MElement.wrap(this.$value) : _superclass = $Object($value);
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
import 'package:dart_eval/dart_eval.dart';
|
||||
import 'package:dart_eval/dart_eval_bridge.dart';
|
||||
import 'package:dart_eval/stdlib/core.dart';
|
||||
import 'package:mangayomi/eval/model/filter.dart';
|
||||
import 'package:mangayomi/eval/dart/model/filter.dart';
|
||||
|
||||
class $FilterList implements FilterList, $Instance {
|
||||
$FilterList.wrap(this.$value) : _superclass = $Object($value);
|
||||
|
|
@ -71,6 +71,11 @@ class $FilterList implements FilterList, $Instance {
|
|||
|
||||
@override
|
||||
set filters(List<dynamic> filters) {}
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
}
|
||||
|
||||
class $SelectFilter implements SelectFilter, $Instance {
|
||||
|
|
@ -113,26 +118,26 @@ class $SelectFilter implements SelectFilter, $Instance {
|
|||
|
||||
static $Value? $new(Runtime runtime, $Value? target, List<$Value?> args) {
|
||||
return $SelectFilter.wrap(SelectFilter(
|
||||
args[0]!.$value,
|
||||
args[1]!.$value,
|
||||
args[2]!.$value,
|
||||
(args[3]!.$value as List).map((e) {
|
||||
if (e is $Value) {
|
||||
final value = e.$reified;
|
||||
if (value is Map) {
|
||||
Map<String, dynamic> map = {};
|
||||
map = value.map((key, value) => MapEntry(key.toString(), value));
|
||||
if (map['type'] == 'SelectOption') {
|
||||
final filter = map['filter'] as Map;
|
||||
return SelectFilterOption.fromJson(
|
||||
filter.map((key, value) => MapEntry(key.toString(), value)));
|
||||
args[0]!.$value,
|
||||
args[1]!.$value,
|
||||
args[2]!.$value,
|
||||
(args[3]!.$value as List).map((e) {
|
||||
if (e is $Value) {
|
||||
final value = e.$reified;
|
||||
if (value is Map) {
|
||||
Map<String, dynamic> map = {};
|
||||
map = value.map((key, value) => MapEntry(key.toString(), value));
|
||||
if (map['type'] == 'SelectOption') {
|
||||
final filter = map['filter'] as Map;
|
||||
return SelectFilterOption.fromJson(filter
|
||||
.map((key, value) => MapEntry(key.toString(), value)));
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
return e;
|
||||
}).toList(),
|
||||
));
|
||||
return e;
|
||||
}).toList(),
|
||||
null));
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
@ -188,6 +193,12 @@ class $SelectFilter implements SelectFilter, $Instance {
|
|||
@override
|
||||
int get state => $value.state;
|
||||
|
||||
@override
|
||||
String? get typeName => $value.typeName;
|
||||
|
||||
@override
|
||||
set typeName(String? typeName) {}
|
||||
|
||||
@override
|
||||
List<dynamic> get values => $value.values;
|
||||
|
||||
|
|
@ -202,6 +213,11 @@ class $SelectFilter implements SelectFilter, $Instance {
|
|||
|
||||
@override
|
||||
set values(List<dynamic> values) {}
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
}
|
||||
|
||||
class $SelectFilterOption implements SelectFilterOption, $Instance {
|
||||
|
|
@ -230,7 +246,7 @@ class $SelectFilterOption implements SelectFilterOption, $Instance {
|
|||
|
||||
static $Value? $new(Runtime runtime, $Value? target, List<$Value?> args) {
|
||||
return $SelectFilterOption
|
||||
.wrap(SelectFilterOption(args[0]!.$value, args[1]!.$value));
|
||||
.wrap(SelectFilterOption(args[0]!.$value, args[1]!.$value, null));
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
@ -276,11 +292,22 @@ class $SelectFilterOption implements SelectFilterOption, $Instance {
|
|||
@override
|
||||
String get name => $value.name;
|
||||
|
||||
@override
|
||||
String? get typeName => $value.typeName;
|
||||
|
||||
@override
|
||||
set typeName(String? typeName) {}
|
||||
|
||||
@override
|
||||
set name(String name) {}
|
||||
|
||||
@override
|
||||
set value(String value) {}
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
}
|
||||
|
||||
class $SeparatorFilter implements SeparatorFilter, $Instance {
|
||||
|
|
@ -304,7 +331,8 @@ class $SeparatorFilter implements SeparatorFilter, $Instance {
|
|||
wrap: true);
|
||||
|
||||
static $Value? $new(Runtime runtime, $Value? target, List<$Value?> args) {
|
||||
return $SeparatorFilter.wrap(SeparatorFilter(type: args[0]?.$value ?? ''));
|
||||
return $SeparatorFilter
|
||||
.wrap(SeparatorFilter(null, type: args[0]?.$value ?? ''));
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
@ -342,8 +370,19 @@ class $SeparatorFilter implements SeparatorFilter, $Instance {
|
|||
@override
|
||||
String? get type => $value.type ?? '';
|
||||
|
||||
@override
|
||||
String? get typeName => $value.typeName;
|
||||
|
||||
@override
|
||||
set typeName(String? typeName) {}
|
||||
|
||||
@override
|
||||
set type(String? type) {}
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
}
|
||||
|
||||
class $HeaderFilter implements HeaderFilter, $Instance {
|
||||
|
|
@ -372,7 +411,7 @@ class $HeaderFilter implements HeaderFilter, $Instance {
|
|||
|
||||
static $Value? $new(Runtime runtime, $Value? target, List<$Value?> args) {
|
||||
return $HeaderFilter
|
||||
.wrap(HeaderFilter(args[0]!.$value, type: args[1]?.$value ?? ''));
|
||||
.wrap(HeaderFilter(args[0]!.$value, null, type: args[1]?.$value ?? ''));
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
@ -423,6 +462,17 @@ class $HeaderFilter implements HeaderFilter, $Instance {
|
|||
|
||||
@override
|
||||
String? get type => $value.type ?? '';
|
||||
|
||||
@override
|
||||
String? get typeName => $value.typeName;
|
||||
|
||||
@override
|
||||
set typeName(String? typeName) {}
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
}
|
||||
|
||||
class $TextFilter implements TextFilter, $Instance {
|
||||
|
|
@ -450,7 +500,7 @@ class $TextFilter implements TextFilter, $Instance {
|
|||
wrap: true);
|
||||
|
||||
static $Value? $new(Runtime runtime, $Value? target, List<$Value?> args) {
|
||||
return $TextFilter.wrap(TextFilter(args[0]!.$value, args[1]!.$value));
|
||||
return $TextFilter.wrap(TextFilter(args[0]!.$value, args[1]!.$value, null));
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
@ -502,6 +552,12 @@ class $TextFilter implements TextFilter, $Instance {
|
|||
@override
|
||||
String get state => $value.state;
|
||||
|
||||
@override
|
||||
String? get typeName => $value.typeName;
|
||||
|
||||
@override
|
||||
set typeName(String? typeName) {}
|
||||
|
||||
@override
|
||||
set type(String? type) {}
|
||||
|
||||
|
|
@ -510,6 +566,11 @@ class $TextFilter implements TextFilter, $Instance {
|
|||
|
||||
@override
|
||||
set state(String state) {}
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
}
|
||||
|
||||
class $SortFilter implements SortFilter, $Instance {
|
||||
|
|
@ -550,13 +611,14 @@ class $SortFilter implements SortFilter, $Instance {
|
|||
|
||||
static $Value? $new(Runtime runtime, $Value? target, List<$Value?> args) {
|
||||
return $SortFilter.wrap(SortFilter(
|
||||
args[0]!.$value,
|
||||
args[1]!.$value,
|
||||
args[2]!.$value,
|
||||
(args[3]!.$value as List)
|
||||
.map((e) => SelectFilterOption(e.$reified.name, e.$reified.value))
|
||||
.toList(),
|
||||
));
|
||||
args[0]!.$value,
|
||||
args[1]!.$value,
|
||||
args[2]!.$value,
|
||||
(args[3]!.$value as List)
|
||||
.map((e) =>
|
||||
SelectFilterOption(e.$reified.name, e.$reified.value, null))
|
||||
.toList(),
|
||||
null));
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
@ -615,6 +677,12 @@ class $SortFilter implements SortFilter, $Instance {
|
|||
@override
|
||||
List<dynamic> get values => $value.values;
|
||||
|
||||
@override
|
||||
String? get typeName => $value.typeName;
|
||||
|
||||
@override
|
||||
set typeName(String? typeName) {}
|
||||
|
||||
@override
|
||||
set type(String? type) {}
|
||||
|
||||
|
|
@ -626,6 +694,11 @@ class $SortFilter implements SortFilter, $Instance {
|
|||
|
||||
@override
|
||||
set values(List<dynamic> values) {}
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
}
|
||||
|
||||
class $SortState implements SortState, $Instance {
|
||||
|
|
@ -655,7 +728,7 @@ class $SortState implements SortState, $Instance {
|
|||
wrap: true);
|
||||
|
||||
static $Value? $new(Runtime runtime, $Value? target, List<$Value?> args) {
|
||||
return $SortState.wrap(SortState(args[0]!.$value, args[1]!.$value));
|
||||
return $SortState.wrap(SortState(args[0]!.$value, args[1]!.$value, null));
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
@ -701,11 +774,22 @@ class $SortState implements SortState, $Instance {
|
|||
@override
|
||||
bool get ascending => $value.ascending;
|
||||
|
||||
@override
|
||||
String? get typeName => $value.typeName;
|
||||
|
||||
@override
|
||||
set typeName(String? typeName) {}
|
||||
|
||||
@override
|
||||
set ascending(bool ascending) {}
|
||||
|
||||
@override
|
||||
set index(int index) {}
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
}
|
||||
|
||||
class $TriStateFilter implements TriStateFilter, $Instance {
|
||||
|
|
@ -744,7 +828,7 @@ class $TriStateFilter implements TriStateFilter, $Instance {
|
|||
|
||||
static $Value? $new(Runtime runtime, $Value? target, List<$Value?> args) {
|
||||
return $TriStateFilter.wrap(TriStateFilter(
|
||||
args[2]?.$value ?? '', args[0]!.$value, args[1]!.$value,
|
||||
args[2]?.$value ?? '', args[0]!.$value, args[1]!.$value, null,
|
||||
state: args[3]?.$value ?? 0));
|
||||
}
|
||||
|
||||
|
|
@ -808,6 +892,12 @@ class $TriStateFilter implements TriStateFilter, $Instance {
|
|||
@override
|
||||
String get value => $value.value;
|
||||
|
||||
@override
|
||||
String? get typeName => $value.typeName;
|
||||
|
||||
@override
|
||||
set typeName(String? typeName) {}
|
||||
|
||||
@override
|
||||
set state(int state) {}
|
||||
|
||||
|
|
@ -816,6 +906,11 @@ class $TriStateFilter implements TriStateFilter, $Instance {
|
|||
|
||||
@override
|
||||
set value(String value) {}
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
}
|
||||
|
||||
class $GroupFilter implements GroupFilter, $Instance {
|
||||
|
|
@ -874,7 +969,8 @@ class $GroupFilter implements GroupFilter, $Instance {
|
|||
return value;
|
||||
}
|
||||
return e;
|
||||
}).toList()));
|
||||
}).toList(),
|
||||
null));
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
@ -927,6 +1023,12 @@ class $GroupFilter implements GroupFilter, $Instance {
|
|||
@override
|
||||
List<dynamic> get state => $value.state;
|
||||
|
||||
@override
|
||||
String? get typeName => $value.typeName;
|
||||
|
||||
@override
|
||||
set typeName(String? typeName) {}
|
||||
|
||||
@override
|
||||
set type(String? type) {}
|
||||
|
||||
|
|
@ -935,6 +1037,11 @@ class $GroupFilter implements GroupFilter, $Instance {
|
|||
|
||||
@override
|
||||
set state(List<dynamic> state) {}
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
}
|
||||
|
||||
class $CheckBoxFilter implements CheckBoxFilter, $Instance {
|
||||
|
|
@ -973,7 +1080,7 @@ class $CheckBoxFilter implements CheckBoxFilter, $Instance {
|
|||
|
||||
static $Value? $new(Runtime runtime, $Value? target, List<$Value?> args) {
|
||||
return $CheckBoxFilter.wrap(CheckBoxFilter(
|
||||
args[2]?.$value ?? '', args[0]!.$value, args[1]!.$value,
|
||||
args[2]?.$value ?? '', args[0]!.$value, args[1]!.$value, null,
|
||||
state: args[3]?.$value ?? false));
|
||||
}
|
||||
|
||||
|
|
@ -1037,6 +1144,12 @@ class $CheckBoxFilter implements CheckBoxFilter, $Instance {
|
|||
@override
|
||||
String get value => $value.value;
|
||||
|
||||
@override
|
||||
String? get typeName => $value.typeName;
|
||||
|
||||
@override
|
||||
set typeName(String? typeName) {}
|
||||
|
||||
@override
|
||||
set type(String? type) {}
|
||||
|
||||
|
|
@ -1045,4 +1158,9 @@ class $CheckBoxFilter implements CheckBoxFilter, $Instance {
|
|||
|
||||
@override
|
||||
set value(String value) {}
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
}
|
||||
|
|
@ -4,8 +4,8 @@ import 'package:dart_eval/dart_eval_bridge.dart';
|
|||
import 'package:dart_eval/stdlib/core.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:http_interceptor/http_interceptor.dart';
|
||||
import 'package:mangayomi/eval/bridge/m_source.dart';
|
||||
import 'package:mangayomi/eval/model/m_bridge.dart';
|
||||
import 'package:mangayomi/eval/dart/bridge/m_source.dart';
|
||||
import 'package:mangayomi/eval/dart/model/m_bridge.dart';
|
||||
import 'package:mangayomi/services/http/interceptor.dart';
|
||||
|
||||
/// dart_eval wrapper for [InterceptedClient]
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
import 'package:dart_eval/dart_eval.dart';
|
||||
import 'package:dart_eval/dart_eval_bridge.dart';
|
||||
import 'package:dart_eval/stdlib/core.dart';
|
||||
import 'package:mangayomi/eval/model/m_chapter.dart';
|
||||
import 'package:mangayomi/eval/dart/model/m_chapter.dart';
|
||||
|
||||
class $MChapter implements MChapter, $Instance {
|
||||
$MChapter.wrap(this.$value) : _superclass = $Object($value);
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
import 'package:dart_eval/dart_eval.dart';
|
||||
import 'package:dart_eval/dart_eval_bridge.dart';
|
||||
import 'package:dart_eval/stdlib/core.dart';
|
||||
import 'package:mangayomi/eval/bridge/m_chapter.dart';
|
||||
import 'package:mangayomi/eval/bridge/m_status.dart';
|
||||
import 'package:mangayomi/eval/model/m_chapter.dart';
|
||||
import 'package:mangayomi/eval/model/m_manga.dart';
|
||||
import 'package:mangayomi/eval/dart/bridge/m_chapter.dart';
|
||||
import 'package:mangayomi/eval/dart/bridge/m_status.dart';
|
||||
import 'package:mangayomi/eval/dart/model/m_chapter.dart';
|
||||
import 'package:mangayomi/eval/dart/model/m_manga.dart';
|
||||
import 'package:mangayomi/models/manga.dart';
|
||||
|
||||
class $MManga implements MManga, $Instance {
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
import 'package:dart_eval/dart_eval.dart';
|
||||
import 'package:dart_eval/dart_eval_bridge.dart';
|
||||
import 'package:dart_eval/stdlib/core.dart';
|
||||
import 'package:mangayomi/eval/bridge/m_manga.dart';
|
||||
import 'package:mangayomi/eval/model/m_manga.dart';
|
||||
import 'package:mangayomi/eval/model/m_pages.dart';
|
||||
import 'package:mangayomi/eval/dart/bridge/m_manga.dart';
|
||||
import 'package:mangayomi/eval/dart/model/m_manga.dart';
|
||||
import 'package:mangayomi/eval/dart/model/m_pages.dart';
|
||||
|
||||
class $MPages implements MPages, $Instance {
|
||||
$MPages.wrap(this.$value) : _superclass = $Object($value);
|
||||
|
|
@ -2,18 +2,18 @@ import 'dart:convert';
|
|||
import 'package:dart_eval/dart_eval.dart';
|
||||
import 'package:dart_eval/dart_eval_bridge.dart';
|
||||
import 'package:dart_eval/stdlib/core.dart';
|
||||
import 'package:mangayomi/eval/bridge/document.dart';
|
||||
import 'package:mangayomi/eval/bridge/filter.dart';
|
||||
import 'package:mangayomi/eval/bridge/m_manga.dart';
|
||||
import 'package:mangayomi/eval/bridge/m_pages.dart';
|
||||
import 'package:mangayomi/eval/bridge/m_status.dart';
|
||||
import 'package:mangayomi/eval/bridge/m_track.dart';
|
||||
import 'package:mangayomi/eval/bridge/m_video.dart';
|
||||
import 'package:mangayomi/eval/model/filter.dart';
|
||||
import 'package:mangayomi/eval/model/m_bridge.dart';
|
||||
import 'package:mangayomi/eval/model/m_pages.dart';
|
||||
import 'package:mangayomi/eval/model/m_manga.dart';
|
||||
import 'package:mangayomi/eval/model/m_provider.dart';
|
||||
import 'package:mangayomi/eval/dart/bridge/document.dart';
|
||||
import 'package:mangayomi/eval/dart/bridge/filter.dart';
|
||||
import 'package:mangayomi/eval/dart/bridge/m_manga.dart';
|
||||
import 'package:mangayomi/eval/dart/bridge/m_pages.dart';
|
||||
import 'package:mangayomi/eval/dart/bridge/m_status.dart';
|
||||
import 'package:mangayomi/eval/dart/bridge/m_track.dart';
|
||||
import 'package:mangayomi/eval/dart/bridge/m_video.dart';
|
||||
import 'package:mangayomi/eval/dart/model/filter.dart';
|
||||
import 'package:mangayomi/eval/dart/model/m_bridge.dart';
|
||||
import 'package:mangayomi/eval/dart/model/m_pages.dart';
|
||||
import 'package:mangayomi/eval/dart/model/m_manga.dart';
|
||||
import 'package:mangayomi/eval/dart/model/m_provider.dart';
|
||||
import 'package:mangayomi/models/video.dart';
|
||||
import 'package:mangayomi/modules/browse/extension/providers/extension_preferences_providers.dart';
|
||||
import 'package:mangayomi/services/boa_js.dart';
|
||||
|
|
@ -1025,8 +1025,8 @@ class $MProvider extends MProvider with $Bridge<MProvider> {
|
|||
_toValueList(List filters) {
|
||||
return (filters).map((e) {
|
||||
if (e is SelectFilter) {
|
||||
return $SelectFilter.wrap(
|
||||
SelectFilter(e.type, e.name, e.state, _toValueList(e.values)));
|
||||
return $SelectFilter.wrap(SelectFilter(
|
||||
e.type, e.name, e.state, _toValueList(e.values), e.typeName));
|
||||
} else if (e is TextFilter) {
|
||||
return $TextFilter.wrap(e);
|
||||
} else if (e is HeaderFilter) {
|
||||
|
|
@ -1038,8 +1038,8 @@ class $MProvider extends MProvider with $Bridge<MProvider> {
|
|||
} else if (e is SeparatorFilter) {
|
||||
return $SeparatorFilter.wrap(e);
|
||||
} else if (e is SortFilter) {
|
||||
return $SortFilter
|
||||
.wrap(SortFilter(e.type, e.name, e.state, _toValueList(e.values)));
|
||||
return $SortFilter.wrap(SortFilter(
|
||||
e.type, e.name, e.state, _toValueList(e.values), e.typeName));
|
||||
} else if (e is SortState) {
|
||||
return $SortState.wrap(e);
|
||||
} else if (e is CheckBoxFilter) {
|
||||
|
|
@ -1047,8 +1047,8 @@ class $MProvider extends MProvider with $Bridge<MProvider> {
|
|||
} else if (e is SelectFilterOption) {
|
||||
return $SelectFilterOption.wrap(e);
|
||||
} else if (e is GroupFilter) {
|
||||
return $GroupFilter
|
||||
.wrap(GroupFilter(e.type, e.name, _toValueList(e.state)));
|
||||
return $GroupFilter.wrap(
|
||||
GroupFilter(e.type, e.name, _toValueList(e.state), e.typeName));
|
||||
}
|
||||
return e;
|
||||
}).toList();
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
import 'package:dart_eval/dart_eval.dart';
|
||||
import 'package:dart_eval/dart_eval_bridge.dart';
|
||||
import 'package:dart_eval/stdlib/core.dart';
|
||||
import 'package:mangayomi/eval/model/m_source.dart';
|
||||
import 'package:mangayomi/eval/dart/model/m_source.dart';
|
||||
|
||||
class $MSource implements MSource, $Instance {
|
||||
$MSource.wrap(this.$value) : _superclass = $Object($value);
|
||||
|
|
@ -76,4 +76,9 @@ class $MTrack implements Track, $Instance {
|
|||
|
||||
@override
|
||||
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_bridge.dart';
|
||||
import 'package:dart_eval/stdlib/core.dart';
|
||||
import 'package:mangayomi/eval/bridge/m_track.dart';
|
||||
import 'package:mangayomi/eval/dart/bridge/m_track.dart';
|
||||
import 'package:mangayomi/models/video.dart';
|
||||
|
||||
class $MVideo implements Video, $Instance {
|
||||
|
|
@ -139,4 +139,9 @@ class $MVideo implements Video, $Instance {
|
|||
|
||||
@override
|
||||
set audios(List? audios) {}
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
}
|
||||
|
|
@ -2,7 +2,7 @@ import 'package:dart_eval/dart_eval.dart';
|
|||
import 'package:dart_eval/dart_eval_bridge.dart';
|
||||
import 'package:dart_eval/stdlib/core.dart';
|
||||
import 'package:isar/isar.dart';
|
||||
import 'package:mangayomi/eval/model/source_preference.dart';
|
||||
import 'package:mangayomi/eval/dart/model/source_preference.dart';
|
||||
|
||||
class $CheckBoxPreference implements SourcePreference, $Instance {
|
||||
$CheckBoxPreference.wrap(this.$value) : _superclass = $Object($value);
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import 'dart:typed_data';
|
||||
import 'package:dart_eval/dart_eval.dart';
|
||||
import 'package:mangayomi/eval/plugin.dart';
|
||||
import 'package:mangayomi/eval/dart/plugin.dart';
|
||||
|
||||
Uint8List compilerEval(String code) {
|
||||
late Compiler compiler = Compiler();
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
import 'package:html/dom.dart';
|
||||
import 'package:mangayomi/eval/model/element.dart';
|
||||
import 'package:mangayomi/eval/dart/model/element.dart';
|
||||
import 'package:mangayomi/utils/extensions/dom_extensions.dart';
|
||||
|
||||
class MDocument {
|
||||
|
|
@ -55,4 +55,8 @@ class MDocument {
|
|||
MElement? selectFirst(String selector) {
|
||||
return MElement(_document?.selectFirst(selector));
|
||||
}
|
||||
|
||||
String? attr(String attr) {
|
||||
return _document?.attr(attr);
|
||||
}
|
||||
}
|
||||
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:js_packer/js_packer.dart';
|
||||
import 'package:json_path/json_path.dart';
|
||||
import 'package:mangayomi/eval/model/document.dart';
|
||||
import 'package:mangayomi/eval/dart/model/document.dart';
|
||||
import 'package:mangayomi/models/manga.dart';
|
||||
import 'package:mangayomi/services/anime_extractors/dood_extractor.dart';
|
||||
import 'package:mangayomi/services/anime_extractors/filemoon.dart';
|
||||
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/model/m_pages.dart';
|
||||
import 'package:mangayomi/eval/model/m_manga.dart';
|
||||
import 'package:mangayomi/eval/dart/model/filter.dart';
|
||||
import 'package:mangayomi/eval/dart/model/m_pages.dart';
|
||||
import 'package:mangayomi/eval/dart/model/m_manga.dart';
|
||||
import 'package:mangayomi/models/video.dart';
|
||||
|
||||
abstract class MProvider {
|
||||
|
|
@ -1,18 +1,18 @@
|
|||
import 'package:dart_eval/dart_eval.dart';
|
||||
import 'package:dart_eval/dart_eval_bridge.dart';
|
||||
import 'package:mangayomi/eval/bridge/document.dart';
|
||||
import 'package:mangayomi/eval/bridge/element.dart';
|
||||
import 'package:mangayomi/eval/bridge/http.dart';
|
||||
import 'package:mangayomi/eval/bridge/m_chapter.dart';
|
||||
import 'package:mangayomi/eval/bridge/filter.dart';
|
||||
import 'package:mangayomi/eval/bridge/m_pages.dart';
|
||||
import 'package:mangayomi/eval/bridge/m_status.dart';
|
||||
import 'package:mangayomi/eval/bridge/m_provider.dart';
|
||||
import 'package:mangayomi/eval/bridge/m_manga.dart';
|
||||
import 'package:mangayomi/eval/bridge/m_source.dart';
|
||||
import 'package:mangayomi/eval/bridge/m_track.dart';
|
||||
import 'package:mangayomi/eval/bridge/m_video.dart';
|
||||
import 'package:mangayomi/eval/bridge/source_preference.dart';
|
||||
import 'package:mangayomi/eval/dart/bridge/document.dart';
|
||||
import 'package:mangayomi/eval/dart/bridge/element.dart';
|
||||
import 'package:mangayomi/eval/dart/bridge/http.dart';
|
||||
import 'package:mangayomi/eval/dart/bridge/m_chapter.dart';
|
||||
import 'package:mangayomi/eval/dart/bridge/filter.dart';
|
||||
import 'package:mangayomi/eval/dart/bridge/m_pages.dart';
|
||||
import 'package:mangayomi/eval/dart/bridge/m_status.dart';
|
||||
import 'package:mangayomi/eval/dart/bridge/m_provider.dart';
|
||||
import 'package:mangayomi/eval/dart/bridge/m_manga.dart';
|
||||
import 'package:mangayomi/eval/dart/bridge/m_source.dart';
|
||||
import 'package:mangayomi/eval/dart/bridge/m_track.dart';
|
||||
import 'package:mangayomi/eval/dart/bridge/m_video.dart';
|
||||
import 'package:mangayomi/eval/dart/bridge/source_preference.dart';
|
||||
|
||||
class MEvalPlugin extends EvalPlugin {
|
||||
@override
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import 'dart:typed_data';
|
||||
import 'package:dart_eval/dart_eval.dart';
|
||||
import 'package:mangayomi/eval/plugin.dart';
|
||||
import 'package:mangayomi/eval/dart/plugin.dart';
|
||||
|
||||
Runtime runtimeEval(Uint8List bytecode) {
|
||||
final runtime = Runtime(bytecode.buffer.asByteData());
|
||||
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": "النص",
|
||||
"border": "الحدود",
|
||||
"background": "الخلفية",
|
||||
"no_subtite_warning_message": "لا تؤثر لأنه لا توجد مسارات ترجمة في هذا الفيديو"
|
||||
"no_subtite_warning_message": "لا تؤثر لأنه لا توجد مسارات ترجمة في هذا الفيديو",
|
||||
"grid_size": "حجم الشبكة",
|
||||
"n_per_row": "{n} في الصف الواحد"
|
||||
}
|
||||
|
|
@ -317,5 +317,7 @@
|
|||
"text": "Text",
|
||||
"border": "Rand",
|
||||
"background": "Hintergrund",
|
||||
"no_subtite_warning_message": "Hat keine Wirkung, da in diesem Video keine Untertitelspuren vorhanden sind"
|
||||
"no_subtite_warning_message": "Hat keine Wirkung, da in diesem Video keine Untertitelspuren vorhanden sind",
|
||||
"grid_size": "Rastergröße",
|
||||
"n_per_row": "{n} pro Zeile"
|
||||
}
|
||||
|
|
@ -319,5 +319,7 @@
|
|||
"text": "Text",
|
||||
"border": "Border",
|
||||
"background": "Background",
|
||||
"no_subtite_warning_message": "Has no effect because there aren't any subtitle tracks in this video"
|
||||
"no_subtite_warning_message": "Has no effect because there aren't any subtitle tracks in this video",
|
||||
"grid_size": "Grid size",
|
||||
"n_per_row": "{n} per row"
|
||||
}
|
||||
|
|
@ -317,5 +317,7 @@
|
|||
"text": "Texto",
|
||||
"border": "Borde",
|
||||
"background": "Fondo",
|
||||
"no_subtite_warning_message": "No tiene efecto porque no hay pistas de subtítulos en este vídeo"
|
||||
"no_subtite_warning_message": "No tiene efecto porque no hay pistas de subtítulos en este vídeo",
|
||||
"grid_size": "Tamaño de la cuadrícula",
|
||||
"n_per_row": "{n} por fila"
|
||||
}
|
||||
|
|
@ -317,5 +317,7 @@
|
|||
"text": "Texto",
|
||||
"border": "Borde",
|
||||
"background": "Fondo",
|
||||
"no_subtite_warning_message": "No tiene efecto porque no hay pistas de subtítulos en este video"
|
||||
"no_subtite_warning_message": "No tiene efecto porque no hay pistas de subtítulos en este video",
|
||||
"grid_size": "Tamaño de la cuadrícula",
|
||||
"n_per_row": "{n} por fila"
|
||||
}
|
||||
|
|
@ -318,5 +318,7 @@
|
|||
"text": "Texte",
|
||||
"border": "Bordure",
|
||||
"background": "Arrière-plan",
|
||||
"no_subtite_warning_message": "N'a aucun effet car il n'y a pas de pistes de sous-titres dans cette vidéo"
|
||||
"no_subtite_warning_message": "N'a aucun effet car il n'y a pas de pistes de sous-titres dans cette vidéo",
|
||||
"grid_size": "Taille de la grille",
|
||||
"n_per_row": "{n} par ligne"
|
||||
}
|
||||
|
|
@ -317,5 +317,7 @@
|
|||
"text": "Teks",
|
||||
"border": "Batas",
|
||||
"background": "Latar Belakang",
|
||||
"no_subtite_warning_message": "Tidak berpengaruh karena tidak ada trek subtitle dalam video ini"
|
||||
"no_subtite_warning_message": "Tidak berpengaruh karena tidak ada trek subtitle dalam video ini",
|
||||
"grid_size": "Ukuran Grid",
|
||||
"n_per_row": "{n} per baris"
|
||||
}
|
||||
|
|
@ -317,5 +317,7 @@
|
|||
"text": "Testo",
|
||||
"border": "Bordo",
|
||||
"background": "Sfondo",
|
||||
"no_subtite_warning_message": "Non ha effetto perché non ci sono tracce sottotitoli in questo video"
|
||||
"no_subtite_warning_message": "Non ha effetto perché non ci sono tracce sottotitoli in questo video",
|
||||
"grid_size": "Dimensione griglia",
|
||||
"n_per_row": "{n} per riga"
|
||||
}
|
||||
|
|
@ -317,5 +317,7 @@
|
|||
"text": "Texto",
|
||||
"border": "Borda",
|
||||
"background": "Fundo",
|
||||
"no_subtite_warning_message": "Não tem efeito porque não há faixas de legendas neste vídeo"
|
||||
"no_subtite_warning_message": "Não tem efeito porque não há faixas de legendas neste vídeo",
|
||||
"grid_size": "Tamanho da grade",
|
||||
"n_per_row": "{n} por linha"
|
||||
}
|
||||
|
|
@ -317,5 +317,7 @@
|
|||
"text": "Texto",
|
||||
"border": "Borda",
|
||||
"background": "Fundo",
|
||||
"no_subtite_warning_message": "Não tem efeito porque não há faixas de legenda neste vídeo"
|
||||
"no_subtite_warning_message": "Não tem efeito porque não há faixas de legenda neste vídeo",
|
||||
"grid_size": "Tamanho da grade",
|
||||
"n_per_row": "{n} por linha"
|
||||
}
|
||||
|
|
@ -317,5 +317,7 @@
|
|||
"text": "Текст",
|
||||
"border": "Граница",
|
||||
"background": "Фон",
|
||||
"no_subtite_warning_message": "Не имеет эффекта, потому что в этом видео нет субтитров"
|
||||
"no_subtite_warning_message": "Не имеет эффекта, потому что в этом видео нет субтитров",
|
||||
"grid_size": "Размер сетки",
|
||||
"n_per_row": "{n} в ряд"
|
||||
}
|
||||
|
|
@ -317,5 +317,7 @@
|
|||
"text": "Metin",
|
||||
"border": "Kenarlık",
|
||||
"background": "Arka Plan",
|
||||
"no_subtite_warning_message": "Bu videoda altyazı parçaları olmadığı için etkisi yok"
|
||||
"no_subtite_warning_message": "Bu videoda altyazı parçaları olmadığı için etkisi yok",
|
||||
"grid_size": "Kılavuz Boyutu",
|
||||
"n_per_row": "{n} satır başına"
|
||||
}
|
||||
|
|
@ -319,5 +319,7 @@
|
|||
"text": "文本",
|
||||
"border": "边框",
|
||||
"background": "背景",
|
||||
"no_subtite_warning_message": "由于此视频中没有字幕轨道,因此无效。"
|
||||
"no_subtite_warning_message": "由于此视频中没有字幕轨道,因此无效。",
|
||||
"grid_size": "网格大小",
|
||||
"n_per_row": "{n} 每行"
|
||||
}
|
||||
|
|
@ -179,6 +179,10 @@ class Settings {
|
|||
|
||||
String? appFontFamily;
|
||||
|
||||
int? mangaGridSize;
|
||||
|
||||
int? animeGridSize;
|
||||
|
||||
Settings(
|
||||
{this.id = 227,
|
||||
this.displayType = DisplayType.compactGrid,
|
||||
|
|
@ -257,7 +261,9 @@ class Settings {
|
|||
this.colorFilterBlendMode = ColorFilterBlendMode.none,
|
||||
this.playerSubtitleSettings,
|
||||
this.mangaHomeDisplayType = DisplayType.comfortableGrid,
|
||||
this.appFontFamily});
|
||||
this.appFontFamily,
|
||||
this.mangaGridSize,
|
||||
this.animeGridSize});
|
||||
|
||||
Settings.fromJson(Map<String, dynamic> json) {
|
||||
animatePageTransitions = json['animatePageTransitions'];
|
||||
|
|
@ -398,6 +404,8 @@ class Settings {
|
|||
: null;
|
||||
mangaHomeDisplayType = DisplayType.values[json['mangaHomeDisplayType']];
|
||||
appFontFamily = json['appFontFamily'];
|
||||
mangaGridSize = json['mangaGridSize'];
|
||||
animeGridSize = json['animeGridSize'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
|
|
@ -502,7 +510,9 @@ class Settings {
|
|||
if (playerSubtitleSettings != null)
|
||||
'playerSubtitleSettings': playerSubtitleSettings!.toJson(),
|
||||
'mangaHomeDisplayType': mangaHomeDisplayType.index,
|
||||
'appFontFamily': appFontFamily
|
||||
'appFontFamily': appFontFamily,
|
||||
'mangaGridSize': mangaGridSize,
|
||||
'animeGridSize': animeGridSize
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,5 +1,5 @@
|
|||
import 'package:isar/isar.dart';
|
||||
import 'package:mangayomi/eval/model/m_source.dart';
|
||||
import 'package:mangayomi/eval/dart/model/m_source.dart';
|
||||
part 'source.g.dart';
|
||||
|
||||
@collection
|
||||
|
|
@ -53,6 +53,9 @@ class Source {
|
|||
|
||||
String? additionalParams;
|
||||
|
||||
@enumerated
|
||||
SourceCodeLanguage sourceCodeLanguage = SourceCodeLanguage.dart;
|
||||
|
||||
Source(
|
||||
{this.id = 0,
|
||||
this.name = '',
|
||||
|
|
@ -104,6 +107,7 @@ class Source {
|
|||
version = json['version'];
|
||||
versionLast = json['versionLast'];
|
||||
additionalParams = json['additionalParams'] ?? "";
|
||||
sourceCodeLanguage = SourceCodeLanguage.values[json['sourceCodeLanguage']];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
|
|
@ -131,6 +135,7 @@ class Source {
|
|||
'version': version,
|
||||
'versionLast': versionLast,
|
||||
'additionalParams': additionalParams,
|
||||
'sourceCodeLanguage': sourceCodeLanguage.index
|
||||
};
|
||||
|
||||
bool get isTorrent => (typeSource?.toLowerCase() ?? "") == "torrent";
|
||||
|
|
@ -149,3 +154,5 @@ class Source {
|
|||
additionalParams: additionalParams);
|
||||
}
|
||||
}
|
||||
|
||||
enum SourceCodeLanguage { dart, javascript }
|
||||
|
|
|
|||
|
|
@ -117,23 +117,29 @@ const SourceSchema = CollectionSchema(
|
|||
name: r'sourceCode',
|
||||
type: IsarType.string,
|
||||
),
|
||||
r'sourceCodeUrl': PropertySchema(
|
||||
r'sourceCodeLanguage': PropertySchema(
|
||||
id: 20,
|
||||
name: r'sourceCodeLanguage',
|
||||
type: IsarType.byte,
|
||||
enumMap: _SourcesourceCodeLanguageEnumValueMap,
|
||||
),
|
||||
r'sourceCodeUrl': PropertySchema(
|
||||
id: 21,
|
||||
name: r'sourceCodeUrl',
|
||||
type: IsarType.string,
|
||||
),
|
||||
r'typeSource': PropertySchema(
|
||||
id: 21,
|
||||
id: 22,
|
||||
name: r'typeSource',
|
||||
type: IsarType.string,
|
||||
),
|
||||
r'version': PropertySchema(
|
||||
id: 22,
|
||||
id: 23,
|
||||
name: r'version',
|
||||
type: IsarType.string,
|
||||
),
|
||||
r'versionLast': PropertySchema(
|
||||
id: 23,
|
||||
id: 24,
|
||||
name: r'versionLast',
|
||||
type: IsarType.string,
|
||||
)
|
||||
|
|
@ -277,10 +283,11 @@ void _sourceSerialize(
|
|||
writer.writeBool(offsets[17], object.lastUsed);
|
||||
writer.writeString(offsets[18], object.name);
|
||||
writer.writeString(offsets[19], object.sourceCode);
|
||||
writer.writeString(offsets[20], object.sourceCodeUrl);
|
||||
writer.writeString(offsets[21], object.typeSource);
|
||||
writer.writeString(offsets[22], object.version);
|
||||
writer.writeString(offsets[23], object.versionLast);
|
||||
writer.writeByte(offsets[20], object.sourceCodeLanguage.index);
|
||||
writer.writeString(offsets[21], object.sourceCodeUrl);
|
||||
writer.writeString(offsets[22], object.typeSource);
|
||||
writer.writeString(offsets[23], object.version);
|
||||
writer.writeString(offsets[24], object.versionLast);
|
||||
}
|
||||
|
||||
Source _sourceDeserialize(
|
||||
|
|
@ -310,11 +317,14 @@ Source _sourceDeserialize(
|
|||
lastUsed: reader.readBoolOrNull(offsets[17]),
|
||||
name: reader.readStringOrNull(offsets[18]),
|
||||
sourceCode: reader.readStringOrNull(offsets[19]),
|
||||
sourceCodeUrl: reader.readStringOrNull(offsets[20]),
|
||||
typeSource: reader.readStringOrNull(offsets[21]),
|
||||
version: reader.readStringOrNull(offsets[22]),
|
||||
versionLast: reader.readStringOrNull(offsets[23]),
|
||||
sourceCodeUrl: reader.readStringOrNull(offsets[21]),
|
||||
typeSource: reader.readStringOrNull(offsets[22]),
|
||||
version: reader.readStringOrNull(offsets[23]),
|
||||
versionLast: reader.readStringOrNull(offsets[24]),
|
||||
);
|
||||
object.sourceCodeLanguage = _SourcesourceCodeLanguageValueEnumMap[
|
||||
reader.readByteOrNull(offsets[20])] ??
|
||||
SourceCodeLanguage.dart;
|
||||
return object;
|
||||
}
|
||||
|
||||
|
|
@ -366,18 +376,31 @@ P _sourceDeserializeProp<P>(
|
|||
case 19:
|
||||
return (reader.readStringOrNull(offset)) as P;
|
||||
case 20:
|
||||
return (reader.readStringOrNull(offset)) as P;
|
||||
return (_SourcesourceCodeLanguageValueEnumMap[
|
||||
reader.readByteOrNull(offset)] ??
|
||||
SourceCodeLanguage.dart) as P;
|
||||
case 21:
|
||||
return (reader.readStringOrNull(offset)) as P;
|
||||
case 22:
|
||||
return (reader.readStringOrNull(offset)) as P;
|
||||
case 23:
|
||||
return (reader.readStringOrNull(offset)) as P;
|
||||
case 24:
|
||||
return (reader.readStringOrNull(offset)) as P;
|
||||
default:
|
||||
throw IsarError('Unknown property with id $propertyId');
|
||||
}
|
||||
}
|
||||
|
||||
const _SourcesourceCodeLanguageEnumValueMap = {
|
||||
'dart': 0,
|
||||
'javascript': 1,
|
||||
};
|
||||
const _SourcesourceCodeLanguageValueEnumMap = {
|
||||
0: SourceCodeLanguage.dart,
|
||||
1: SourceCodeLanguage.javascript,
|
||||
};
|
||||
|
||||
Id _sourceGetId(Source object) {
|
||||
return object.id ?? Isar.autoIncrement;
|
||||
}
|
||||
|
|
@ -2366,6 +2389,61 @@ extension SourceQueryFilter on QueryBuilder<Source, Source, QFilterCondition> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QAfterFilterCondition> sourceCodeLanguageEqualTo(
|
||||
SourceCodeLanguage value) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(FilterCondition.equalTo(
|
||||
property: r'sourceCodeLanguage',
|
||||
value: value,
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QAfterFilterCondition>
|
||||
sourceCodeLanguageGreaterThan(
|
||||
SourceCodeLanguage value, {
|
||||
bool include = false,
|
||||
}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(FilterCondition.greaterThan(
|
||||
include: include,
|
||||
property: r'sourceCodeLanguage',
|
||||
value: value,
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QAfterFilterCondition>
|
||||
sourceCodeLanguageLessThan(
|
||||
SourceCodeLanguage value, {
|
||||
bool include = false,
|
||||
}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(FilterCondition.lessThan(
|
||||
include: include,
|
||||
property: r'sourceCodeLanguage',
|
||||
value: value,
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QAfterFilterCondition> sourceCodeLanguageBetween(
|
||||
SourceCodeLanguage lower,
|
||||
SourceCodeLanguage upper, {
|
||||
bool includeLower = true,
|
||||
bool includeUpper = true,
|
||||
}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(FilterCondition.between(
|
||||
property: r'sourceCodeLanguage',
|
||||
lower: lower,
|
||||
includeLower: includeLower,
|
||||
upper: upper,
|
||||
includeUpper: includeUpper,
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QAfterFilterCondition> sourceCodeUrlIsNull() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(const FilterCondition.isNull(
|
||||
|
|
@ -3197,6 +3275,18 @@ extension SourceQuerySortBy on QueryBuilder<Source, Source, QSortBy> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QAfterSortBy> sortBySourceCodeLanguage() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(r'sourceCodeLanguage', Sort.asc);
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QAfterSortBy> sortBySourceCodeLanguageDesc() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(r'sourceCodeLanguage', Sort.desc);
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QAfterSortBy> sortBySourceCodeUrl() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(r'sourceCodeUrl', Sort.asc);
|
||||
|
|
@ -3499,6 +3589,18 @@ extension SourceQuerySortThenBy on QueryBuilder<Source, Source, QSortThenBy> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QAfterSortBy> thenBySourceCodeLanguage() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(r'sourceCodeLanguage', Sort.asc);
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QAfterSortBy> thenBySourceCodeLanguageDesc() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(r'sourceCodeLanguage', Sort.desc);
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QAfterSortBy> thenBySourceCodeUrl() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(r'sourceCodeUrl', Sort.asc);
|
||||
|
|
@ -3682,6 +3784,12 @@ extension SourceQueryWhereDistinct on QueryBuilder<Source, Source, QDistinct> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QDistinct> distinctBySourceCodeLanguage() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addDistinctBy(r'sourceCodeLanguage');
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QDistinct> distinctBySourceCodeUrl(
|
||||
{bool caseSensitive = true}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
|
|
@ -3839,6 +3947,13 @@ extension SourceQueryProperty on QueryBuilder<Source, Source, QQueryProperty> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, SourceCodeLanguage, QQueryOperations>
|
||||
sourceCodeLanguageProperty() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addPropertyName(r'sourceCodeLanguage');
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, String?, QQueryOperations> sourceCodeUrlProperty() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addPropertyName(r'sourceCodeUrl');
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import 'package:mangayomi/eval/javascript/http.dart';
|
||||
|
||||
class Video {
|
||||
String url;
|
||||
String quality;
|
||||
|
|
@ -8,6 +10,24 @@ class Video {
|
|||
|
||||
Video(this.url, this.quality, this.originalUrl,
|
||||
{this.headers, this.subtitles, this.audios});
|
||||
factory Video.fromJson(Map<String, dynamic> json) {
|
||||
return Video(json['url'], json['quality'], json['originalUrl'],
|
||||
headers: (json['headers'] as Map?).toMapStringString,
|
||||
subtitles: json['subtitles'] != null
|
||||
? (json['subtitles'] as List).map((e) => Track.fromJson(e)).toList()
|
||||
: [],
|
||||
audios: json['audios'] != null
|
||||
? (json['audios'] as List).map((e) => Track.fromJson(e)).toList()
|
||||
: []);
|
||||
}
|
||||
Map<String, dynamic> toJson() => {
|
||||
'url': url,
|
||||
'quality': quality,
|
||||
'originalUrl': originalUrl,
|
||||
'headers': headers,
|
||||
'subtitles': subtitles?.map((e) => toJson()),
|
||||
'audios': audios?.map((e) => toJson()),
|
||||
};
|
||||
}
|
||||
|
||||
class Track {
|
||||
|
|
@ -19,4 +39,5 @@ class Track {
|
|||
file = json['file'];
|
||||
label = json['label'];
|
||||
}
|
||||
Map<String, dynamic> toJson() => {'file': file, 'label': label};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ part of 'state_provider.dart';
|
|||
// **************************************************************************
|
||||
|
||||
String _$subtitleSettingsStateHash() =>
|
||||
r'4f668c79675772a76d80585db43d041675d0d178';
|
||||
r'4b89ea55392e662651d5aeee4dfce2fcd23ac0e7';
|
||||
|
||||
/// See also [SubtitleSettingsState].
|
||||
@ProviderFor(SubtitleSettingsState)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:mangayomi/eval/model/source_preference.dart';
|
||||
import 'package:mangayomi/eval/dart/model/source_preference.dart';
|
||||
import 'package:mangayomi/main.dart';
|
||||
import 'package:mangayomi/models/source.dart';
|
||||
import 'package:mangayomi/modules/browse/extension/providers/extension_preferences_providers.dart';
|
||||
|
|
@ -21,10 +21,21 @@ class ExtensionDetail extends ConsumerStatefulWidget {
|
|||
|
||||
class _ExtensionDetailState extends ConsumerState<ExtensionDetail> {
|
||||
late Source source = widget.source;
|
||||
late List<SourcePreference> sourcePreference =
|
||||
getSourcePreference(source: source)
|
||||
.map((e) => getSourcePreferenceEntry(e.key!, source.id!))
|
||||
.toList();
|
||||
List<SourcePreference> sourcePreference = [];
|
||||
@override
|
||||
void initState() {
|
||||
getSourcePreferenceAsync(source: source).then((value) {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
sourcePreference = value
|
||||
.map((e) => getSourcePreferenceEntry(e.key!, source.id!))
|
||||
.toList();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import 'package:isar/isar.dart';
|
||||
import 'package:mangayomi/eval/model/source_preference.dart';
|
||||
import 'package:mangayomi/eval/dart/model/source_preference.dart';
|
||||
import 'package:mangayomi/main.dart';
|
||||
import 'package:mangayomi/models/source.dart';
|
||||
import 'package:mangayomi/services/get_source_preference.dart';
|
||||
|
|
@ -85,3 +85,37 @@ void setSourcePreferenceStringValue(int sourceId, String key, String value) {
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
Future<dynamic> getPreferenceValueAsync(int sourceId, String key) async {
|
||||
final sourcePreference = await getSourcePreferenceEntryAsync(key, sourceId);
|
||||
|
||||
if (sourcePreference.listPreference != null) {
|
||||
final pref = sourcePreference.listPreference!;
|
||||
return pref.entryValues![pref.valueIndex!];
|
||||
} else if (sourcePreference.checkBoxPreference != null) {
|
||||
return sourcePreference.checkBoxPreference!.value;
|
||||
} else if (sourcePreference.switchPreferenceCompat != null) {
|
||||
return sourcePreference.switchPreferenceCompat!.value;
|
||||
} else if (sourcePreference.editTextPreference != null) {
|
||||
return sourcePreference.editTextPreference!.value;
|
||||
}
|
||||
return sourcePreference.multiSelectListPreference!.values;
|
||||
}
|
||||
|
||||
Future<SourcePreference> getSourcePreferenceEntryAsync(
|
||||
String key, int sourceId) async {
|
||||
SourcePreference? sourcePreference = isar.sourcePreferences
|
||||
.filter()
|
||||
.sourceIdEqualTo(sourceId)
|
||||
.keyEqualTo(key)
|
||||
.findFirstSync();
|
||||
if (sourcePreference == null) {
|
||||
final source = isar.sources.getSync(sourceId)!;
|
||||
sourcePreference = (await getSourcePreferenceAsync(source: source))
|
||||
.firstWhere((element) => element.key == key,
|
||||
orElse: () => throw "Error when getting source preference");
|
||||
setPreferenceSetting(sourcePreference, source);
|
||||
}
|
||||
|
||||
return sourcePreference;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import 'dart:convert';
|
||||
import 'package:dart_eval/stdlib/core.dart';
|
||||
import 'package:mangayomi/eval/compiler/compiler.dart';
|
||||
import 'package:mangayomi/eval/runtime/runtime.dart';
|
||||
import 'package:mangayomi/eval/dart/compiler/compiler.dart';
|
||||
import 'package:mangayomi/eval/dart/runtime/runtime.dart';
|
||||
import 'package:mangayomi/main.dart';
|
||||
import 'package:mangayomi/models/source.dart';
|
||||
import 'package:mangayomi/modules/more/settings/browse/providers/browse_state_provider.dart';
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:mangayomi/eval/model/source_preference.dart';
|
||||
import 'package:mangayomi/eval/dart/model/source_preference.dart';
|
||||
import 'package:mangayomi/models/source.dart';
|
||||
import 'package:mangayomi/modules/browse/extension/providers/extension_preferences_providers.dart';
|
||||
import 'package:mangayomi/modules/manga/detail/widgets/chapter_filter_list_tile_widget.dart';
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@ import 'dart:typed_data';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:isar/isar.dart';
|
||||
import 'package:mangayomi/eval/model/m_manga.dart';
|
||||
import 'package:mangayomi/eval/model/m_pages.dart';
|
||||
import 'package:mangayomi/eval/dart/model/m_manga.dart';
|
||||
import 'package:mangayomi/eval/dart/model/m_pages.dart';
|
||||
import 'package:mangayomi/main.dart';
|
||||
import 'package:mangayomi/models/manga.dart';
|
||||
import 'package:mangayomi/modules/manga/home/manga_home_screen.dart';
|
||||
|
|
|
|||
|
|
@ -1,12 +1,14 @@
|
|||
// ignore_for_file: use_build_context_synchronously
|
||||
|
||||
import 'dart:io';
|
||||
import 'dart:math';
|
||||
import 'package:bot_toast/bot_toast.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:isar/isar.dart';
|
||||
import 'package:mangayomi/eval/model/m_bridge.dart';
|
||||
import 'package:mangayomi/eval/dart/model/m_bridge.dart';
|
||||
import 'package:mangayomi/main.dart';
|
||||
import 'package:mangayomi/models/category.dart';
|
||||
import 'package:mangayomi/models/chapter.dart';
|
||||
|
|
@ -692,6 +694,7 @@ class _LibraryScreenState extends ConsumerState<LibraryScreen>
|
|||
language: language,
|
||||
mangaIdsList: mangaIdsList,
|
||||
localSource: localSource,
|
||||
isManga: widget.isManga,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
@ -765,6 +768,7 @@ class _LibraryScreenState extends ConsumerState<LibraryScreen>
|
|||
language: language,
|
||||
mangaIdsList: mangaIdsList,
|
||||
localSource: localSource,
|
||||
isManga: widget.isManga,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
@ -1345,7 +1349,7 @@ class _LibraryScreenState extends ConsumerState<LibraryScreen>
|
|||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 20, top: 10),
|
||||
padding: const EdgeInsets.only(left: 20, right: 20, top: 10),
|
||||
child: Row(
|
||||
children: [
|
||||
Text(l10n.display_mode),
|
||||
|
|
@ -1408,8 +1412,63 @@ class _LibraryScreenState extends ConsumerState<LibraryScreen>
|
|||
// ),
|
||||
).toList()),
|
||||
),
|
||||
Consumer(
|
||||
builder: (context, ref, child) {
|
||||
final gridSize = ref.watch(libraryGridSizeStateProvider(
|
||||
isManga: widget.isManga)) ??
|
||||
0;
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(left: 8, right: 8, top: 10),
|
||||
child: Row(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 20),
|
||||
child: Column(
|
||||
children: [
|
||||
Text(context.l10n.grid_size),
|
||||
Text(gridSize == 0
|
||||
? context.l10n.default0
|
||||
: context.l10n.n_per_row(gridSize.toString()))
|
||||
],
|
||||
),
|
||||
),
|
||||
Flexible(
|
||||
flex: 7,
|
||||
child: SliderTheme(
|
||||
data: SliderTheme.of(context).copyWith(
|
||||
overlayShape: const RoundSliderOverlayShape(
|
||||
overlayRadius: 5.0),
|
||||
),
|
||||
child: Slider(
|
||||
min: 0.0,
|
||||
max: 7,
|
||||
divisions: max(7, 0),
|
||||
value: gridSize.toDouble(),
|
||||
onChanged: (value) {
|
||||
HapticFeedback.vibrate();
|
||||
ref
|
||||
.read(libraryGridSizeStateProvider(
|
||||
isManga: widget.isManga)
|
||||
.notifier)
|
||||
.set(value.toInt());
|
||||
},
|
||||
onChangeEnd: (value) {
|
||||
ref
|
||||
.read(libraryGridSizeStateProvider(
|
||||
isManga: widget.isManga)
|
||||
.notifier)
|
||||
.set(value.toInt(), end: true);
|
||||
},
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 20, top: 10),
|
||||
padding: const EdgeInsets.only(left: 20, right: 20, top: 10),
|
||||
child: Row(
|
||||
children: [
|
||||
Text(l10n.badges),
|
||||
|
|
@ -1469,7 +1528,7 @@ class _LibraryScreenState extends ConsumerState<LibraryScreen>
|
|||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 20, top: 10),
|
||||
padding: const EdgeInsets.only(left: 20, right: 20, top: 10),
|
||||
child: Row(
|
||||
children: [Text(l10n.tabs)],
|
||||
),
|
||||
|
|
|
|||
|
|
@ -42,6 +42,35 @@ class LibraryDisplayTypeState extends _$LibraryDisplayTypeState {
|
|||
}
|
||||
}
|
||||
|
||||
@riverpod
|
||||
class LibraryGridSizeState extends _$LibraryGridSizeState {
|
||||
@override
|
||||
int? build({required bool isManga}) {
|
||||
return isManga ? settings.mangaGridSize : settings.animeGridSize;
|
||||
}
|
||||
|
||||
Settings get settings {
|
||||
return isar.settings.getSync(227)!;
|
||||
}
|
||||
|
||||
void set(int? value, {bool end = false}) {
|
||||
Settings appSettings = Settings();
|
||||
|
||||
state = value;
|
||||
if (end) {
|
||||
if (isManga) {
|
||||
appSettings = settings..mangaGridSize = value;
|
||||
} else {
|
||||
appSettings = settings..animeGridSize = value;
|
||||
}
|
||||
|
||||
isar.writeTxnSync(() {
|
||||
isar.settings.putSync(appSettings);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@riverpod
|
||||
class MangaFilterDownloadedState extends _$MangaFilterDownloadedState {
|
||||
@override
|
||||
|
|
|
|||
|
|
@ -196,6 +196,151 @@ class _LibraryDisplayTypeStateProviderElement
|
|||
Settings get settings => (origin as LibraryDisplayTypeStateProvider).settings;
|
||||
}
|
||||
|
||||
String _$libraryGridSizeStateHash() =>
|
||||
r'a4e55ef92f9387c2588679c5e2f23ef689e5d593';
|
||||
|
||||
abstract class _$LibraryGridSizeState
|
||||
extends BuildlessAutoDisposeNotifier<int?> {
|
||||
late final bool isManga;
|
||||
|
||||
int? build({
|
||||
required bool isManga,
|
||||
});
|
||||
}
|
||||
|
||||
/// See also [LibraryGridSizeState].
|
||||
@ProviderFor(LibraryGridSizeState)
|
||||
const libraryGridSizeStateProvider = LibraryGridSizeStateFamily();
|
||||
|
||||
/// See also [LibraryGridSizeState].
|
||||
class LibraryGridSizeStateFamily extends Family<int?> {
|
||||
/// See also [LibraryGridSizeState].
|
||||
const LibraryGridSizeStateFamily();
|
||||
|
||||
/// See also [LibraryGridSizeState].
|
||||
LibraryGridSizeStateProvider call({
|
||||
required bool isManga,
|
||||
}) {
|
||||
return LibraryGridSizeStateProvider(
|
||||
isManga: isManga,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
LibraryGridSizeStateProvider getProviderOverride(
|
||||
covariant LibraryGridSizeStateProvider provider,
|
||||
) {
|
||||
return call(
|
||||
isManga: provider.isManga,
|
||||
);
|
||||
}
|
||||
|
||||
static const Iterable<ProviderOrFamily>? _dependencies = null;
|
||||
|
||||
@override
|
||||
Iterable<ProviderOrFamily>? get dependencies => _dependencies;
|
||||
|
||||
static const Iterable<ProviderOrFamily>? _allTransitiveDependencies = null;
|
||||
|
||||
@override
|
||||
Iterable<ProviderOrFamily>? get allTransitiveDependencies =>
|
||||
_allTransitiveDependencies;
|
||||
|
||||
@override
|
||||
String? get name => r'libraryGridSizeStateProvider';
|
||||
}
|
||||
|
||||
/// See also [LibraryGridSizeState].
|
||||
class LibraryGridSizeStateProvider
|
||||
extends AutoDisposeNotifierProviderImpl<LibraryGridSizeState, int?> {
|
||||
/// See also [LibraryGridSizeState].
|
||||
LibraryGridSizeStateProvider({
|
||||
required bool isManga,
|
||||
}) : this._internal(
|
||||
() => LibraryGridSizeState()..isManga = isManga,
|
||||
from: libraryGridSizeStateProvider,
|
||||
name: r'libraryGridSizeStateProvider',
|
||||
debugGetCreateSourceHash:
|
||||
const bool.fromEnvironment('dart.vm.product')
|
||||
? null
|
||||
: _$libraryGridSizeStateHash,
|
||||
dependencies: LibraryGridSizeStateFamily._dependencies,
|
||||
allTransitiveDependencies:
|
||||
LibraryGridSizeStateFamily._allTransitiveDependencies,
|
||||
isManga: isManga,
|
||||
);
|
||||
|
||||
LibraryGridSizeStateProvider._internal(
|
||||
super._createNotifier, {
|
||||
required super.name,
|
||||
required super.dependencies,
|
||||
required super.allTransitiveDependencies,
|
||||
required super.debugGetCreateSourceHash,
|
||||
required super.from,
|
||||
required this.isManga,
|
||||
}) : super.internal();
|
||||
|
||||
final bool isManga;
|
||||
|
||||
@override
|
||||
int? runNotifierBuild(
|
||||
covariant LibraryGridSizeState notifier,
|
||||
) {
|
||||
return notifier.build(
|
||||
isManga: isManga,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Override overrideWith(LibraryGridSizeState Function() create) {
|
||||
return ProviderOverride(
|
||||
origin: this,
|
||||
override: LibraryGridSizeStateProvider._internal(
|
||||
() => create()..isManga = isManga,
|
||||
from: from,
|
||||
name: null,
|
||||
dependencies: null,
|
||||
allTransitiveDependencies: null,
|
||||
debugGetCreateSourceHash: null,
|
||||
isManga: isManga,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
AutoDisposeNotifierProviderElement<LibraryGridSizeState, int?>
|
||||
createElement() {
|
||||
return _LibraryGridSizeStateProviderElement(this);
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return other is LibraryGridSizeStateProvider && other.isManga == isManga;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
var hash = _SystemHash.combine(0, runtimeType.hashCode);
|
||||
hash = _SystemHash.combine(hash, isManga.hashCode);
|
||||
|
||||
return _SystemHash.finish(hash);
|
||||
}
|
||||
}
|
||||
|
||||
mixin LibraryGridSizeStateRef on AutoDisposeNotifierProviderRef<int?> {
|
||||
/// The parameter `isManga` of this provider.
|
||||
bool get isManga;
|
||||
}
|
||||
|
||||
class _LibraryGridSizeStateProviderElement
|
||||
extends AutoDisposeNotifierProviderElement<LibraryGridSizeState, int?>
|
||||
with LibraryGridSizeStateRef {
|
||||
_LibraryGridSizeStateProviderElement(super.provider);
|
||||
|
||||
@override
|
||||
bool get isManga => (origin as LibraryGridSizeStateProvider).isManga;
|
||||
}
|
||||
|
||||
String _$mangaFilterDownloadedStateHash() =>
|
||||
r'9c07e64580061bf2cbf892ef679274913aaa3b20';
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import 'package:mangayomi/main.dart';
|
|||
import 'package:mangayomi/models/download.dart';
|
||||
import 'package:mangayomi/modules/history/providers/isar_providers.dart';
|
||||
import 'package:mangayomi/modules/library/providers/library_state_provider.dart';
|
||||
import 'package:mangayomi/modules/library/widgets/measure_widget_sync.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/providers/push_router.dart';
|
||||
import 'package:mangayomi/models/manga.dart';
|
||||
import 'package:mangayomi/utils/extensions/build_context_extensions.dart';
|
||||
|
|
@ -20,7 +21,10 @@ import 'package:mangayomi/modules/widgets/gridview_widget.dart';
|
|||
import 'package:mangayomi/modules/widgets/manga_image_card_widget.dart';
|
||||
import 'package:mangayomi/modules/widgets/progress_center.dart';
|
||||
|
||||
class LibraryGridViewWidget extends StatelessWidget {
|
||||
final animeCardheightStateProvider = StateProvider<double>((ref) => 300);
|
||||
final mangaCardheightStateProvider = StateProvider<double>((ref) => 300);
|
||||
|
||||
class LibraryGridViewWidget extends StatefulWidget {
|
||||
final bool isCoverOnlyGrid;
|
||||
final bool isComfortableGrid;
|
||||
final List<int> mangaIdsList;
|
||||
|
|
@ -29,6 +33,7 @@ class LibraryGridViewWidget extends StatelessWidget {
|
|||
final bool downloadedChapter;
|
||||
final bool continueReaderBtn;
|
||||
final bool localSource;
|
||||
final bool isManga;
|
||||
const LibraryGridViewWidget(
|
||||
{super.key,
|
||||
required this.entriesManga,
|
||||
|
|
@ -38,271 +43,332 @@ class LibraryGridViewWidget extends StatelessWidget {
|
|||
required this.downloadedChapter,
|
||||
required this.continueReaderBtn,
|
||||
required this.mangaIdsList,
|
||||
required this.localSource});
|
||||
required this.localSource,
|
||||
required this.isManga});
|
||||
|
||||
@override
|
||||
State<LibraryGridViewWidget> createState() => _LibraryGridViewWidgetState();
|
||||
}
|
||||
|
||||
class _LibraryGridViewWidgetState extends State<LibraryGridViewWidget> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GridViewWidget(
|
||||
childAspectRatio: isComfortableGrid ? 0.642 : 0.69,
|
||||
itemCount: entriesManga.length,
|
||||
itemBuilder: (context, index) {
|
||||
final entry = entriesManga[index];
|
||||
return Consumer(builder: (context, ref, child) {
|
||||
bool isLocalArchive = entry.isLocalArchive ?? false;
|
||||
final isLongPressed = ref.watch(isLongPressedMangaStateProvider);
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(2),
|
||||
child: CoverViewWidget(
|
||||
isLongPressed: mangaIdsList.contains(entry.id),
|
||||
bottomTextWidget: BottomTextWidget(
|
||||
maxLines: 1,
|
||||
text: entry.name!,
|
||||
isComfortableGrid: isComfortableGrid,
|
||||
),
|
||||
isComfortableGrid: isComfortableGrid,
|
||||
image: entry.customCoverImage != null
|
||||
? MemoryImage(entry.customCoverImage as Uint8List)
|
||||
as ImageProvider
|
||||
: CachedNetworkImageProvider(
|
||||
toImgUrl(entry.customCoverFromTracker ?? entry.imageUrl!),
|
||||
headers: entry.isLocalArchive!
|
||||
? null
|
||||
: ref.watch(headersProvider(
|
||||
source: entry.source!, lang: entry.lang!)),
|
||||
return Consumer(builder: (context, ref, child) {
|
||||
final isLongPressed = ref.watch(isLongPressedMangaStateProvider);
|
||||
final isManga = widget.isManga;
|
||||
final height = ref.watch(isManga
|
||||
? mangaCardheightStateProvider
|
||||
: animeCardheightStateProvider);
|
||||
final gridSize =
|
||||
ref.watch(libraryGridSizeStateProvider(isManga: isManga));
|
||||
return GridViewWidget(
|
||||
gridSize: gridSize,
|
||||
childAspectRatio: widget.isComfortableGrid ? 0.642 : 0.69,
|
||||
itemCount: widget.entriesManga.length,
|
||||
itemBuilder: (context, index) {
|
||||
final entry = widget.entriesManga[index];
|
||||
|
||||
return Builder(builder: (context) {
|
||||
bool isLocalArchive = entry.isLocalArchive ?? false;
|
||||
return SizedBox(
|
||||
height: height +
|
||||
(widget.isComfortableGrid &&
|
||||
(gridSize != null && gridSize != 0)
|
||||
? 22
|
||||
: 0),
|
||||
child: MeasureWidgetSizeSync(
|
||||
onCalculateSize: (size) {
|
||||
if (size != null) {
|
||||
final newHeight = size.width * 1.5;
|
||||
if (height.ceil() != newHeight.ceil()) {
|
||||
ref
|
||||
.read((isManga
|
||||
? mangaCardheightStateProvider
|
||||
: animeCardheightStateProvider)
|
||||
.notifier)
|
||||
.state = size.width * 1.5;
|
||||
}
|
||||
}
|
||||
},
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(2),
|
||||
child: CoverViewWidget(
|
||||
isLongPressed: widget.mangaIdsList.contains(entry.id),
|
||||
bottomTextWidget: BottomTextWidget(
|
||||
maxLines: 1,
|
||||
text: entry.name!,
|
||||
isComfortableGrid: widget.isComfortableGrid,
|
||||
),
|
||||
onTap: () {
|
||||
if (isLongPressed) {
|
||||
ref.read(mangasListStateProvider.notifier).update(entry);
|
||||
} else {
|
||||
pushToMangaReaderDetail(
|
||||
archiveId: isLocalArchive ? entry.id : null,
|
||||
context: context,
|
||||
lang: entry.lang!,
|
||||
mangaM: entry,
|
||||
source: entry.source!);
|
||||
}
|
||||
},
|
||||
onLongPress: () {
|
||||
if (!isLongPressed) {
|
||||
ref.read(mangasListStateProvider.notifier).update(entry);
|
||||
|
||||
ref
|
||||
.read(isLongPressedMangaStateProvider.notifier)
|
||||
.update(!isLongPressed);
|
||||
} else {
|
||||
ref.read(mangasListStateProvider.notifier).update(entry);
|
||||
}
|
||||
},
|
||||
children: [
|
||||
Stack(
|
||||
children: [
|
||||
Positioned(
|
||||
top: 0,
|
||||
left: 0,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(5),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(3),
|
||||
color: context.primaryColor,
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
if (localSource && isLocalArchive)
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: const BorderRadius.only(
|
||||
topLeft: Radius.circular(3),
|
||||
bottomLeft: Radius.circular(3)),
|
||||
color: Theme.of(context).hintColor,
|
||||
),
|
||||
child: const Padding(
|
||||
padding:
|
||||
EdgeInsets.only(left: 3, right: 3),
|
||||
child: Text(
|
||||
"Local",
|
||||
style: TextStyle(color: Colors.white),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (downloadedChapter)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(right: 5),
|
||||
child: Consumer(
|
||||
builder: (context, ref, child) {
|
||||
List nbrDown = [];
|
||||
isar.txnSync(() {
|
||||
for (var i = 0;
|
||||
i < entry.chapters.length;
|
||||
i++) {
|
||||
final entries = isar.downloads
|
||||
.filter()
|
||||
.idIsNotNull()
|
||||
.chapterIdEqualTo(entry.chapters
|
||||
.toList()[i]
|
||||
.id)
|
||||
.findAllSync();
|
||||
|
||||
if (entries.isNotEmpty &&
|
||||
entries.first.isDownload!) {
|
||||
nbrDown.add(entries.first);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (nbrDown.isNotEmpty) {
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius:
|
||||
const BorderRadius.only(
|
||||
topLeft:
|
||||
Radius.circular(3),
|
||||
bottomLeft:
|
||||
Radius.circular(3)),
|
||||
color:
|
||||
Theme.of(context).hintColor,
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
left: 3, right: 3),
|
||||
child: Text(
|
||||
nbrDown.length.toString(),
|
||||
style: const TextStyle(
|
||||
color: Colors.white),
|
||||
),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return Container();
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(right: 3),
|
||||
child: Text(
|
||||
entry.chapters.length.toString(),
|
||||
style: const TextStyle(color: Colors.white),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
isComfortableGrid: widget.isComfortableGrid,
|
||||
image: entry.customCoverImage != null
|
||||
? MemoryImage(entry.customCoverImage as Uint8List)
|
||||
as ImageProvider
|
||||
: CachedNetworkImageProvider(
|
||||
toImgUrl(entry.customCoverFromTracker ??
|
||||
entry.imageUrl!),
|
||||
headers: entry.isLocalArchive!
|
||||
? null
|
||||
: ref.watch(headersProvider(
|
||||
source: entry.source!, lang: entry.lang!)),
|
||||
),
|
||||
)),
|
||||
if (language && entry.lang!.isNotEmpty)
|
||||
Positioned(
|
||||
top: 0,
|
||||
right: 0,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(5),
|
||||
child: Container(
|
||||
color: context.themeData.cardColor,
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: const BorderRadius.only(
|
||||
topLeft: Radius.circular(3),
|
||||
bottomLeft: Radius.circular(3)),
|
||||
color: Theme.of(context).hintColor,
|
||||
),
|
||||
child: Padding(
|
||||
padding:
|
||||
const EdgeInsets.only(left: 3, right: 3),
|
||||
child: Text(
|
||||
entry.lang!.toUpperCase(),
|
||||
style: const TextStyle(color: Colors.white),
|
||||
onTap: () {
|
||||
if (isLongPressed) {
|
||||
ref
|
||||
.read(mangasListStateProvider.notifier)
|
||||
.update(entry);
|
||||
} else {
|
||||
pushToMangaReaderDetail(
|
||||
archiveId: isLocalArchive ? entry.id : null,
|
||||
context: context,
|
||||
lang: entry.lang!,
|
||||
mangaM: entry,
|
||||
source: entry.source!);
|
||||
}
|
||||
},
|
||||
onLongPress: () {
|
||||
if (!isLongPressed) {
|
||||
ref
|
||||
.read(mangasListStateProvider.notifier)
|
||||
.update(entry);
|
||||
|
||||
ref
|
||||
.read(isLongPressedMangaStateProvider.notifier)
|
||||
.update(!isLongPressed);
|
||||
} else {
|
||||
ref
|
||||
.read(mangasListStateProvider.notifier)
|
||||
.update(entry);
|
||||
}
|
||||
},
|
||||
children: [
|
||||
Stack(
|
||||
children: [
|
||||
Positioned(
|
||||
top: 0,
|
||||
left: 0,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(5),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(3),
|
||||
color: context.primaryColor,
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
if (widget.localSource && isLocalArchive)
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius:
|
||||
const BorderRadius.only(
|
||||
topLeft: Radius.circular(3),
|
||||
bottomLeft:
|
||||
Radius.circular(3)),
|
||||
color: Theme.of(context).hintColor,
|
||||
),
|
||||
child: const Padding(
|
||||
padding: EdgeInsets.only(
|
||||
left: 3, right: 3),
|
||||
child: Text(
|
||||
"Local",
|
||||
style: TextStyle(
|
||||
color: Colors.white),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (widget.downloadedChapter)
|
||||
Padding(
|
||||
padding:
|
||||
const EdgeInsets.only(right: 5),
|
||||
child: Consumer(
|
||||
builder: (context, ref, child) {
|
||||
List nbrDown = [];
|
||||
isar.txnSync(() {
|
||||
for (var i = 0;
|
||||
i < entry.chapters.length;
|
||||
i++) {
|
||||
final entries = isar.downloads
|
||||
.filter()
|
||||
.idIsNotNull()
|
||||
.chapterIdEqualTo(entry
|
||||
.chapters
|
||||
.toList()[i]
|
||||
.id)
|
||||
.findAllSync();
|
||||
|
||||
if (entries.isNotEmpty &&
|
||||
entries
|
||||
.first.isDownload!) {
|
||||
nbrDown.add(entries.first);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (nbrDown.isNotEmpty) {
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius:
|
||||
const BorderRadius.only(
|
||||
topLeft:
|
||||
Radius.circular(
|
||||
3),
|
||||
bottomLeft:
|
||||
Radius.circular(
|
||||
3)),
|
||||
color: Theme.of(context)
|
||||
.hintColor,
|
||||
),
|
||||
child: Padding(
|
||||
padding:
|
||||
const EdgeInsets.only(
|
||||
left: 3, right: 3),
|
||||
child: Text(
|
||||
nbrDown.length.toString(),
|
||||
style: const TextStyle(
|
||||
color: Colors.white),
|
||||
),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return Container();
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding:
|
||||
const EdgeInsets.only(right: 3),
|
||||
child: Text(
|
||||
entry.chapters.length.toString(),
|
||||
style: const TextStyle(
|
||||
color: Colors.white),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
)),
|
||||
],
|
||||
),
|
||||
if (!isComfortableGrid && !isCoverOnlyGrid)
|
||||
BottomTextWidget(text: entry.name!),
|
||||
if (continueReaderBtn)
|
||||
Positioned(
|
||||
bottom: 0,
|
||||
right: 0,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(9),
|
||||
child: Consumer(
|
||||
builder: (context, ref, child) {
|
||||
final history = ref.watch(
|
||||
getAllHistoryStreamProvider(
|
||||
isManga: entry.isManga!));
|
||||
return history.when(
|
||||
data: (data) {
|
||||
final incognitoMode =
|
||||
ref.watch(incognitoModeStateProvider);
|
||||
final entries = data
|
||||
.where((element) =>
|
||||
element.mangaId == entry.id)
|
||||
.toList();
|
||||
if (entries.isNotEmpty && !incognitoMode) {
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
pushMangaReaderView(
|
||||
context: context,
|
||||
chapter: entries.first.chapter.value!,
|
||||
);
|
||||
},
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius:
|
||||
BorderRadius.circular(5),
|
||||
color: context.primaryColor
|
||||
.withOpacity(0.9),
|
||||
),
|
||||
child: const Padding(
|
||||
padding: EdgeInsets.all(7),
|
||||
child: Icon(
|
||||
Icons.play_arrow,
|
||||
size: 19,
|
||||
color: Colors.white,
|
||||
)),
|
||||
),
|
||||
);
|
||||
}
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
pushMangaReaderView(
|
||||
context: context,
|
||||
chapter: entry.chapters
|
||||
.toList()
|
||||
.reversed
|
||||
.toList()
|
||||
.last);
|
||||
},
|
||||
)),
|
||||
if (widget.language && entry.lang!.isNotEmpty)
|
||||
Positioned(
|
||||
top: 0,
|
||||
right: 0,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(5),
|
||||
child: Container(
|
||||
color: context.themeData.cardColor,
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
color: context.primaryColor
|
||||
.withOpacity(0.9),
|
||||
borderRadius: const BorderRadius.only(
|
||||
topLeft: Radius.circular(3),
|
||||
bottomLeft: Radius.circular(3)),
|
||||
color: Theme.of(context).hintColor,
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
left: 3, right: 3),
|
||||
child: Text(
|
||||
entry.lang!.toUpperCase(),
|
||||
style: const TextStyle(
|
||||
color: Colors.white),
|
||||
),
|
||||
),
|
||||
child: const Padding(
|
||||
padding: EdgeInsets.all(7),
|
||||
child: Icon(
|
||||
Icons.play_arrow,
|
||||
size: 19,
|
||||
color: Colors.white,
|
||||
)),
|
||||
),
|
||||
);
|
||||
},
|
||||
error: (Object error, StackTrace stackTrace) {
|
||||
return ErrorText(error);
|
||||
},
|
||||
loading: () {
|
||||
return const ProgressCenter();
|
||||
},
|
||||
);
|
||||
},
|
||||
)))
|
||||
],
|
||||
),
|
||||
);
|
||||
});
|
||||
},
|
||||
);
|
||||
),
|
||||
)),
|
||||
],
|
||||
),
|
||||
if (!widget.isComfortableGrid && !widget.isCoverOnlyGrid)
|
||||
BottomTextWidget(text: entry.name!),
|
||||
if (widget.continueReaderBtn)
|
||||
Positioned(
|
||||
bottom: 0,
|
||||
right: 0,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(9),
|
||||
child: Consumer(
|
||||
builder: (context, ref, child) {
|
||||
final history = ref.watch(
|
||||
getAllHistoryStreamProvider(
|
||||
isManga: entry.isManga!));
|
||||
return history.when(
|
||||
data: (data) {
|
||||
final incognitoMode = ref
|
||||
.watch(incognitoModeStateProvider);
|
||||
final entries = data
|
||||
.where((element) =>
|
||||
element.mangaId == entry.id)
|
||||
.toList();
|
||||
if (entries.isNotEmpty &&
|
||||
!incognitoMode) {
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
pushMangaReaderView(
|
||||
context: context,
|
||||
chapter: entries
|
||||
.first.chapter.value!,
|
||||
);
|
||||
},
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius:
|
||||
BorderRadius.circular(5),
|
||||
color: context.primaryColor
|
||||
.withOpacity(0.9),
|
||||
),
|
||||
child: const Padding(
|
||||
padding: EdgeInsets.all(7),
|
||||
child: Icon(
|
||||
Icons.play_arrow,
|
||||
size: 19,
|
||||
color: Colors.white,
|
||||
)),
|
||||
),
|
||||
);
|
||||
}
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
pushMangaReaderView(
|
||||
context: context,
|
||||
chapter: entry.chapters
|
||||
.toList()
|
||||
.reversed
|
||||
.toList()
|
||||
.last);
|
||||
},
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius:
|
||||
BorderRadius.circular(5),
|
||||
color: context.primaryColor
|
||||
.withOpacity(0.9),
|
||||
),
|
||||
child: const Padding(
|
||||
padding: EdgeInsets.all(7),
|
||||
child: Icon(
|
||||
Icons.play_arrow,
|
||||
size: 19,
|
||||
color: Colors.white,
|
||||
)),
|
||||
),
|
||||
);
|
||||
},
|
||||
error: (Object error,
|
||||
StackTrace stackTrace) {
|
||||
return ErrorText(error);
|
||||
},
|
||||
loading: () {
|
||||
return const ProgressCenter();
|
||||
},
|
||||
);
|
||||
},
|
||||
)))
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
});
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
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:go_router/go_router.dart';
|
||||
import 'package:isar/isar.dart';
|
||||
import 'package:mangayomi/eval/model/m_bridge.dart';
|
||||
import 'package:mangayomi/eval/dart/model/m_bridge.dart';
|
||||
import 'package:mangayomi/main.dart';
|
||||
import 'package:mangayomi/models/chapter.dart';
|
||||
import 'package:mangayomi/models/download.dart';
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import 'package:mangayomi/eval/model/m_bridge.dart';
|
||||
import 'package:mangayomi/eval/model/m_manga.dart';
|
||||
import 'package:mangayomi/eval/dart/model/m_bridge.dart';
|
||||
import 'package:mangayomi/eval/dart/model/m_manga.dart';
|
||||
import 'package:mangayomi/main.dart';
|
||||
import 'package:mangayomi/models/chapter.dart';
|
||||
import 'package:mangayomi/models/manga.dart';
|
||||
|
|
|
|||
|
|
@ -3,10 +3,13 @@ import 'dart:io';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:mangayomi/eval/model/m_manga.dart';
|
||||
import 'package:mangayomi/eval/model/m_pages.dart';
|
||||
import 'package:mangayomi/eval/dart/model/m_manga.dart';
|
||||
import 'package:mangayomi/eval/dart/model/m_pages.dart';
|
||||
import 'package:mangayomi/models/settings.dart';
|
||||
import 'package:mangayomi/models/source.dart';
|
||||
import 'package:mangayomi/modules/library/providers/library_state_provider.dart';
|
||||
import 'package:mangayomi/modules/library/widgets/library_gridview_widget.dart';
|
||||
import 'package:mangayomi/modules/library/widgets/measure_widget_sync.dart';
|
||||
import 'package:mangayomi/modules/manga/home/providers/state_provider.dart';
|
||||
import 'package:mangayomi/modules/manga/home/widget/filter_widget.dart';
|
||||
import 'package:mangayomi/modules/widgets/listview_widget.dart';
|
||||
|
|
@ -119,11 +122,19 @@ class _MangaHomeScreenState extends ConsumerState<MangaHomeScreen> {
|
|||
AsyncValue<MPages?>? _getManga;
|
||||
int _length = 0;
|
||||
bool _isFiltering = false;
|
||||
List<dynamic> filterList = [];
|
||||
@override
|
||||
void initState() {
|
||||
getFilterList(source: widget.source).then((value) => setState(() {
|
||||
filterList = value;
|
||||
}));
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final supportsLatest =
|
||||
ref.watch(supportsLatestProvider(source: widget.source));
|
||||
final filterList = getFilterList(source: widget.source);
|
||||
if (_selectedIndex == 2 && (_isSearch && _query.isNotEmpty) ||
|
||||
_isFiltering) {
|
||||
_getManga = ref.watch(searchProvider(
|
||||
|
|
@ -328,8 +339,7 @@ class _MangaHomeScreenState extends ConsumerState<MangaHomeScreen> {
|
|||
TextButton(
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
filters = getFilterList(
|
||||
source: widget.source);
|
||||
filters = filterList;
|
||||
});
|
||||
},
|
||||
child: Text(l10n.reset),
|
||||
|
|
@ -521,23 +531,56 @@ class _MangaHomeScreenState extends ConsumerState<MangaHomeScreen> {
|
|||
manga: _mangaList[index],
|
||||
source: widget.source);
|
||||
})
|
||||
: GridViewWidget(
|
||||
controller: _scrollController,
|
||||
itemCount: _length + 1,
|
||||
childAspectRatio:
|
||||
isComfortableGrid ? 0.642 : 0.69,
|
||||
itemBuilder: (context, index) {
|
||||
if (index == _length) {
|
||||
return buildProgressIndicator();
|
||||
}
|
||||
return MangaHomeImageCard(
|
||||
isManga: widget.source.isManga ?? true,
|
||||
manga: _mangaList[index],
|
||||
source: widget.source,
|
||||
isComfortableGrid: isComfortableGrid,
|
||||
);
|
||||
},
|
||||
)),
|
||||
: Consumer(builder: (context, ref, child) {
|
||||
final gridSize = ref.watch(
|
||||
libraryGridSizeStateProvider(
|
||||
isManga: widget.source.isManga!));
|
||||
final height = ref.watch(widget.source.isManga!
|
||||
? mangaCardheightStateProvider
|
||||
: animeCardheightStateProvider);
|
||||
return GridViewWidget(
|
||||
gridSize: gridSize,
|
||||
controller: _scrollController,
|
||||
itemCount: _length + 1,
|
||||
childAspectRatio:
|
||||
isComfortableGrid ? 0.642 : 0.69,
|
||||
itemBuilder: (context, index) {
|
||||
if (index == _length) {
|
||||
return buildProgressIndicator();
|
||||
}
|
||||
return SizedBox(
|
||||
height: height +
|
||||
(isComfortableGrid &&
|
||||
(gridSize != null &&
|
||||
gridSize != 0)
|
||||
? 22
|
||||
: 0),
|
||||
child: MeasureWidgetSizeSync(
|
||||
onCalculateSize: (size) {
|
||||
if (size != null) {
|
||||
final newHeight = size.width * 1.5;
|
||||
if (height.ceil() !=
|
||||
newHeight.ceil()) {
|
||||
ref
|
||||
.read((widget.source.isManga!
|
||||
? mangaCardheightStateProvider
|
||||
: animeCardheightStateProvider)
|
||||
.notifier)
|
||||
.state = size.width * 1.5;
|
||||
}
|
||||
}
|
||||
},
|
||||
child: MangaHomeImageCard(
|
||||
isManga: widget.source.isManga ?? true,
|
||||
manga: _mangaList[index],
|
||||
source: widget.source,
|
||||
isComfortableGrid: isComfortableGrid,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
})),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:mangayomi/eval/model/filter.dart';
|
||||
import 'package:mangayomi/eval/dart/model/filter.dart';
|
||||
import 'package:mangayomi/utils/extensions/build_context_extensions.dart';
|
||||
|
||||
class FilterWidget extends StatelessWidget {
|
||||
|
|
|
|||
|
|
@ -8,9 +8,8 @@ import 'package:flutter/services.dart';
|
|||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:mangayomi/eval/model/m_bridge.dart';
|
||||
import 'package:mangayomi/eval/dart/model/m_bridge.dart';
|
||||
import 'package:mangayomi/main.dart';
|
||||
import 'package:mangayomi/messages/generated.dart';
|
||||
import 'package:mangayomi/models/chapter.dart';
|
||||
import 'package:mangayomi/models/manga.dart';
|
||||
import 'package:mangayomi/models/settings.dart';
|
||||
|
|
@ -984,8 +983,6 @@ class _MangaChapterPageGalleryState
|
|||
}
|
||||
|
||||
void _initCurrentIndex() async {
|
||||
await finalizeRust();
|
||||
await initializeRust();
|
||||
final readerMode = _readerController.getReaderMode();
|
||||
_uChapDataPreload.addAll(_chapterUrlModel.uChapDataPreload);
|
||||
_readerController.setMangaHistoryUpdate();
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import 'dart:io';
|
|||
import 'package:file_picker/file_picker.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:mangayomi/eval/model/m_bridge.dart';
|
||||
import 'package:mangayomi/eval/dart/model/m_bridge.dart';
|
||||
import 'package:mangayomi/modules/manga/detail/widgets/chapter_filter_list_tile_widget.dart';
|
||||
import 'package:mangayomi/modules/more/backup_and_restore/providers/auto_backup.dart';
|
||||
import 'package:mangayomi/modules/more/backup_and_restore/providers/backup.dart';
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import 'package:archive/archive_io.dart';
|
|||
import 'package:bot_toast/bot_toast.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:isar/isar.dart';
|
||||
import 'package:mangayomi/eval/model/source_preference.dart';
|
||||
import 'package:mangayomi/eval/dart/model/source_preference.dart';
|
||||
import 'package:mangayomi/main.dart';
|
||||
import 'package:mangayomi/models/category.dart';
|
||||
import 'package:mangayomi/models/chapter.dart';
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@ import 'dart:convert';
|
|||
import 'package:archive/archive_io.dart';
|
||||
import 'package:bot_toast/bot_toast.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:mangayomi/eval/model/m_bridge.dart';
|
||||
import 'package:mangayomi/eval/model/source_preference.dart';
|
||||
import 'package:mangayomi/eval/dart/model/m_bridge.dart';
|
||||
import 'package:mangayomi/eval/dart/model/source_preference.dart';
|
||||
import 'package:mangayomi/main.dart';
|
||||
import 'package:mangayomi/models/category.dart';
|
||||
import 'package:mangayomi/models/chapter.dart';
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ part of 'app_font_family.dart';
|
|||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$appFontFamilyHash() => r'500f9cd0c0b0dd27d7026c4aa029c33fed337430';
|
||||
String _$appFontFamilyHash() => r'7f115012111256848d806e47382db1f8abcff5ec';
|
||||
|
||||
/// See also [AppFontFamily].
|
||||
@ProviderFor(AppFontFamily)
|
||||
|
|
|
|||
|
|
@ -46,12 +46,9 @@ class CoverViewWidget extends StatelessWidget {
|
|||
children: children,
|
||||
)
|
||||
: Ink.image(
|
||||
height: 200,
|
||||
fit: BoxFit.cover,
|
||||
image: image!,
|
||||
child: Stack(
|
||||
children: children,
|
||||
),
|
||||
child: Stack(children: children),
|
||||
),
|
||||
)),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -6,27 +6,32 @@ class GridViewWidget extends StatelessWidget {
|
|||
final bool reverse;
|
||||
final double? childAspectRatio;
|
||||
final Widget? Function(BuildContext, int) itemBuilder;
|
||||
final int? gridSize;
|
||||
const GridViewWidget(
|
||||
{super.key,
|
||||
this.controller,
|
||||
required this.itemCount,
|
||||
required this.itemBuilder,
|
||||
this.reverse = false,
|
||||
this.childAspectRatio = 0.69});
|
||||
this.childAspectRatio = 0.69,
|
||||
this.gridSize});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
color: Theme.of(context).scaffoldBackgroundColor,
|
||||
child: GridView.builder(
|
||||
padding: const EdgeInsets.only(top: 13),
|
||||
controller: controller,
|
||||
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
|
||||
childAspectRatio: childAspectRatio!,
|
||||
maxCrossAxisExtent: 220,
|
||||
),
|
||||
itemCount: itemCount,
|
||||
itemBuilder: itemBuilder),
|
||||
);
|
||||
color: Theme.of(context).scaffoldBackgroundColor,
|
||||
child: GridView.builder(
|
||||
padding: const EdgeInsets.only(top: 13),
|
||||
controller: controller,
|
||||
gridDelegate: (gridSize == null || gridSize == 0)
|
||||
? SliverGridDelegateWithMaxCrossAxisExtent(
|
||||
childAspectRatio: childAspectRatio!,
|
||||
maxCrossAxisExtent: 220,
|
||||
)
|
||||
: SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: gridSize!,
|
||||
childAspectRatio: childAspectRatio!),
|
||||
itemCount: itemCount,
|
||||
itemBuilder: itemBuilder));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import 'package:flutter/material.dart';
|
|||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:isar/isar.dart';
|
||||
import 'package:mangayomi/eval/model/m_manga.dart';
|
||||
import 'package:mangayomi/eval/dart/model/m_manga.dart';
|
||||
import 'package:mangayomi/main.dart';
|
||||
import 'package:mangayomi/models/manga.dart';
|
||||
import 'package:mangayomi/models/settings.dart';
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// ignore_for_file: depend_on_referenced_packages
|
||||
import 'dart:io';
|
||||
import 'package:isar/isar.dart';
|
||||
import 'package:mangayomi/eval/model/source_preference.dart';
|
||||
import 'package:mangayomi/eval/dart/model/source_preference.dart';
|
||||
import 'package:mangayomi/main.dart';
|
||||
import 'package:mangayomi/models/category.dart';
|
||||
import 'package:mangayomi/models/chapter.dart';
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import 'dart:convert';
|
||||
import 'package:html/dom.dart';
|
||||
import 'package:http_interceptor/http_interceptor.dart';
|
||||
import 'package:mangayomi/eval/model/m_bridge.dart';
|
||||
import 'package:mangayomi/eval/dart/model/m_bridge.dart';
|
||||
import 'package:mangayomi/models/video.dart';
|
||||
import 'package:html/parser.dart' as parser;
|
||||
import 'package:mangayomi/services/http/interceptor.dart';
|
||||
|
|
|
|||
|
|
@ -1,17 +1,18 @@
|
|||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
import 'dart:typed_data';
|
||||
import 'package:mangayomi/eval/bridge/m_source.dart';
|
||||
import 'package:mangayomi/eval/compiler/compiler.dart';
|
||||
import 'package:mangayomi/eval/model/m_provider.dart';
|
||||
import 'package:mangayomi/eval/dart/bridge/m_source.dart';
|
||||
import 'package:mangayomi/eval/dart/compiler/compiler.dart';
|
||||
import 'package:mangayomi/eval/javascript/service.dart';
|
||||
import 'package:mangayomi/eval/dart/model/m_provider.dart';
|
||||
import 'package:mangayomi/main.dart';
|
||||
import 'package:mangayomi/messages/generated.dart';
|
||||
import 'package:mangayomi/models/chapter.dart';
|
||||
import 'package:mangayomi/models/settings.dart';
|
||||
import 'package:mangayomi/models/source.dart';
|
||||
import 'package:mangayomi/modules/manga/archive_reader/providers/archive_reader_providers.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/reader_view.dart';
|
||||
import 'package:mangayomi/providers/storage_provider.dart';
|
||||
import 'package:mangayomi/eval/runtime/runtime.dart';
|
||||
import 'package:mangayomi/eval/dart/runtime/runtime.dart';
|
||||
import 'package:mangayomi/sources/utils/utils.dart';
|
||||
import 'package:mangayomi/utils/reg_exp_matcher.dart';
|
||||
import 'package:mangayomi/modules/more/providers/incognito_mode_state_provider.dart';
|
||||
|
|
@ -62,16 +63,18 @@ Future<GetChapterPagesModel> getChapterPages(
|
|||
isarPageUrls.first.urls!.isNotEmpty) {
|
||||
pageUrls = isarPageUrls.first.urls!;
|
||||
} else {
|
||||
await finalizeRust();
|
||||
await initializeRust();
|
||||
final bytecode =
|
||||
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
|
||||
if (source.sourceCodeLanguage == SourceCodeLanguage.dart) {
|
||||
final bytecode = compilerEval(
|
||||
useTestSourceCode ? testSourceCode : source.sourceCode!);
|
||||
|
||||
final runtime = runtimeEval(bytecode);
|
||||
final runtime = runtimeEval(bytecode);
|
||||
|
||||
var res = await runtime.executeLib('package:mangayomi/main.dart', 'main',
|
||||
[$MSource.wrap(source.toMSource())]);
|
||||
pageUrls = (await (res as MProvider).getPageList(chapter.url!));
|
||||
var res = await runtime.executeLib('package:mangayomi/main.dart',
|
||||
'main', [$MSource.wrap(source.toMSource())]);
|
||||
pageUrls = (await (res as MProvider).getPageList(chapter.url!));
|
||||
} else {
|
||||
pageUrls = await JsExtensionService(source).getPageList(chapter.url!);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ part of 'get_chapter_pages.dart';
|
|||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$getChapterPagesHash() => r'aa95d95504a7f52e22bd3886782a9ef4443453e9';
|
||||
String _$getChapterPagesHash() => r'e637b2e307606818eae08438d3c98aaec0ae0a00';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
import 'dart:async';
|
||||
import 'package:mangayomi/eval/bridge/m_source.dart';
|
||||
import 'package:mangayomi/eval/model/m_manga.dart';
|
||||
import 'package:mangayomi/eval/compiler/compiler.dart';
|
||||
import 'package:mangayomi/eval/model/m_provider.dart';
|
||||
import 'package:mangayomi/eval/dart/bridge/m_source.dart';
|
||||
import 'package:mangayomi/eval/javascript/service.dart';
|
||||
import 'package:mangayomi/eval/dart/model/m_manga.dart';
|
||||
import 'package:mangayomi/eval/dart/compiler/compiler.dart';
|
||||
import 'package:mangayomi/eval/dart/model/m_provider.dart';
|
||||
import 'package:mangayomi/models/source.dart';
|
||||
import 'package:mangayomi/eval/runtime/runtime.dart';
|
||||
import 'package:mangayomi/eval/dart/runtime/runtime.dart';
|
||||
import 'package:mangayomi/sources/source_test.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
part 'get_detail.g.dart';
|
||||
|
|
@ -16,17 +17,21 @@ Future<MManga> getDetail(
|
|||
required Source source,
|
||||
}) async {
|
||||
MManga? mangadetail;
|
||||
final bytecode =
|
||||
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
|
||||
if (source.sourceCodeLanguage == SourceCodeLanguage.dart) {
|
||||
final bytecode =
|
||||
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
|
||||
|
||||
final runtime = runtimeEval(bytecode);
|
||||
final runtime = runtimeEval(bytecode);
|
||||
|
||||
var res = await runtime.executeLib('package:mangayomi/main.dart', 'main',
|
||||
[$MSource.wrap(source.toMSource())]);
|
||||
try {
|
||||
mangadetail = await (res as MProvider).getDetail(url);
|
||||
} catch (e) {
|
||||
throw Exception(e);
|
||||
var res = await runtime.executeLib('package:mangayomi/main.dart', 'main',
|
||||
[$MSource.wrap(source.toMSource())]);
|
||||
try {
|
||||
mangadetail = await (res as MProvider).getDetail(url);
|
||||
} catch (e) {
|
||||
throw Exception(e);
|
||||
}
|
||||
} else {
|
||||
mangadetail = await JsExtensionService(source).getDetail(url);
|
||||
}
|
||||
return mangadetail;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ part of 'get_detail.dart';
|
|||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$getDetailHash() => r'a1808953ca93c379c91b3e280a298c0852cebb34';
|
||||
String _$getDetailHash() => r'a3e63c6d6a5ad9eccea268080f5506344677032b';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
|
|
|||
|
|
@ -1,28 +1,32 @@
|
|||
import 'package:dart_eval/dart_eval_bridge.dart';
|
||||
import 'package:mangayomi/eval/bridge/m_source.dart';
|
||||
import 'package:mangayomi/eval/compiler/compiler.dart';
|
||||
import 'package:mangayomi/eval/model/m_provider.dart';
|
||||
import 'package:mangayomi/eval/dart/bridge/m_source.dart';
|
||||
import 'package:mangayomi/eval/dart/compiler/compiler.dart';
|
||||
import 'package:mangayomi/eval/javascript/service.dart';
|
||||
import 'package:mangayomi/eval/dart/model/m_provider.dart';
|
||||
import 'package:mangayomi/models/source.dart';
|
||||
import 'package:mangayomi/eval/runtime/runtime.dart';
|
||||
import 'package:mangayomi/eval/dart/runtime/runtime.dart';
|
||||
import 'package:mangayomi/sources/source_test.dart';
|
||||
|
||||
List<dynamic> getFilterList({required Source source}) {
|
||||
Future<List<dynamic>> getFilterList({required Source source}) async {
|
||||
List<dynamic> filterList = [];
|
||||
if (source.sourceCodeLanguage == SourceCodeLanguage.dart) {
|
||||
try {
|
||||
final bytecode =
|
||||
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
|
||||
|
||||
try {
|
||||
final bytecode =
|
||||
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
|
||||
final runtime = runtimeEval(bytecode);
|
||||
|
||||
final runtime = runtimeEval(bytecode);
|
||||
|
||||
var res = runtime.executeLib('package:mangayomi/main.dart', 'main',
|
||||
[$MSource.wrap(source.toMSource())]);
|
||||
filterList = (res as MProvider)
|
||||
.getFilterList()
|
||||
.map((e) => e is $Value ? e.$reified : e)
|
||||
.toList();
|
||||
} catch (_) {
|
||||
return [];
|
||||
var res = runtime.executeLib('package:mangayomi/main.dart', 'main',
|
||||
[$MSource.wrap(source.toMSource())]);
|
||||
filterList = (res as MProvider)
|
||||
.getFilterList()
|
||||
.map((e) => e is $Value ? e.$reified : e)
|
||||
.toList();
|
||||
} catch (_) {
|
||||
return [];
|
||||
}
|
||||
} else {
|
||||
filterList = (await JsExtensionService(source).getFilterList()).filters;
|
||||
}
|
||||
|
||||
return filterList;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
import 'dart:async';
|
||||
import 'package:mangayomi/eval/bridge/m_source.dart';
|
||||
import 'package:mangayomi/eval/model/m_pages.dart';
|
||||
import 'package:mangayomi/eval/compiler/compiler.dart';
|
||||
import 'package:mangayomi/eval/model/m_provider.dart';
|
||||
import 'package:mangayomi/eval/dart/bridge/m_source.dart';
|
||||
import 'package:mangayomi/eval/javascript/service.dart';
|
||||
import 'package:mangayomi/eval/dart/model/m_pages.dart';
|
||||
import 'package:mangayomi/eval/dart/compiler/compiler.dart';
|
||||
import 'package:mangayomi/eval/dart/model/m_provider.dart';
|
||||
import 'package:mangayomi/models/source.dart';
|
||||
import 'package:mangayomi/eval/runtime/runtime.dart';
|
||||
import 'package:mangayomi/eval/dart/runtime/runtime.dart';
|
||||
import 'package:mangayomi/sources/source_test.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
part 'get_latest_updates.g.dart';
|
||||
|
|
@ -16,19 +17,22 @@ Future<MPages?> getLatestUpdates(
|
|||
required int page,
|
||||
}) async {
|
||||
MPages? latestUpdatesManga;
|
||||
if (source.sourceCodeLanguage == SourceCodeLanguage.dart) {
|
||||
try {
|
||||
final bytecode =
|
||||
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
|
||||
|
||||
try {
|
||||
final bytecode =
|
||||
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
|
||||
final runtime = runtimeEval(bytecode);
|
||||
|
||||
final runtime = runtimeEval(bytecode);
|
||||
|
||||
var res = await runtime.executeLib('package:mangayomi/main.dart', 'main',
|
||||
[$MSource.wrap(source.toMSource())]);
|
||||
latestUpdatesManga = await (res as MProvider).getLatestUpdates(page);
|
||||
} catch (e) {
|
||||
throw Exception(e);
|
||||
var res = await runtime.executeLib('package:mangayomi/main.dart', 'main',
|
||||
[$MSource.wrap(source.toMSource())]);
|
||||
latestUpdatesManga = await (res as MProvider).getLatestUpdates(page);
|
||||
} catch (e) {
|
||||
throw Exception(e);
|
||||
}
|
||||
} else {
|
||||
latestUpdatesManga =
|
||||
await JsExtensionService(source).getLatestUpdates(page);
|
||||
}
|
||||
|
||||
return latestUpdatesManga;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ part of 'get_latest_updates.dart';
|
|||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$getLatestUpdatesHash() => r'288b2ce3b2e79c1924c8e2a312282900fd9e645f';
|
||||
String _$getLatestUpdatesHash() => r'89ccdaf3b19ee84b2d61fd66301ef6d6eefbe797';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
import 'dart:async';
|
||||
import 'package:mangayomi/eval/bridge/m_source.dart';
|
||||
import 'package:mangayomi/eval/model/m_pages.dart';
|
||||
import 'package:mangayomi/eval/compiler/compiler.dart';
|
||||
import 'package:mangayomi/eval/model/m_provider.dart';
|
||||
import 'package:mangayomi/eval/dart/bridge/m_source.dart';
|
||||
import 'package:mangayomi/eval/javascript/service.dart';
|
||||
import 'package:mangayomi/eval/dart/model/m_pages.dart';
|
||||
import 'package:mangayomi/eval/dart/compiler/compiler.dart';
|
||||
import 'package:mangayomi/eval/dart/model/m_provider.dart';
|
||||
import 'package:mangayomi/models/source.dart';
|
||||
import 'package:mangayomi/eval/runtime/runtime.dart';
|
||||
import 'package:mangayomi/eval/dart/runtime/runtime.dart';
|
||||
import 'package:mangayomi/sources/source_test.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
part 'get_popular.g.dart';
|
||||
|
|
@ -16,18 +17,21 @@ Future<MPages?> getPopular(
|
|||
required int page,
|
||||
}) async {
|
||||
MPages? popularManga;
|
||||
if (source.sourceCodeLanguage == SourceCodeLanguage.dart) {
|
||||
try {
|
||||
final bytecode =
|
||||
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
|
||||
|
||||
try {
|
||||
final bytecode =
|
||||
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
|
||||
final runtime = runtimeEval(bytecode);
|
||||
|
||||
final runtime = runtimeEval(bytecode);
|
||||
|
||||
var res = runtime.executeLib('package:mangayomi/main.dart', 'main',
|
||||
[$MSource.wrap(source.toMSource())]);
|
||||
popularManga = await (res as MProvider).getPopular(page);
|
||||
} catch (e) {
|
||||
throw Exception(e);
|
||||
var res = runtime.executeLib('package:mangayomi/main.dart', 'main',
|
||||
[$MSource.wrap(source.toMSource())]);
|
||||
popularManga = await (res as MProvider).getPopular(page);
|
||||
} catch (e) {
|
||||
throw Exception(e);
|
||||
}
|
||||
} else {
|
||||
popularManga = await JsExtensionService(source).getPopular(page);
|
||||
}
|
||||
|
||||
return popularManga;
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ part of 'get_popular.dart';
|
|||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$getPopularHash() => r'd78a01ea5854ad3f592e713e4f4052929774e78e';
|
||||
String _$getPopularHash() => r'81c132dc4a1dc78a5bedb69eb33a7f6fdb9bff16';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import 'package:mangayomi/eval/bridge/m_source.dart';
|
||||
import 'package:mangayomi/eval/compiler/compiler.dart';
|
||||
import 'package:mangayomi/eval/model/m_provider.dart';
|
||||
import 'package:mangayomi/eval/dart/bridge/m_source.dart';
|
||||
import 'package:mangayomi/eval/dart/compiler/compiler.dart';
|
||||
import 'package:mangayomi/eval/dart/model/m_provider.dart';
|
||||
import 'package:mangayomi/models/source.dart';
|
||||
import 'package:mangayomi/eval/runtime/runtime.dart';
|
||||
import 'package:mangayomi/eval/dart/runtime/runtime.dart';
|
||||
import 'package:mangayomi/sources/source_test.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
part 'get_source_baseurl.g.dart';
|
||||
|
|
@ -10,19 +10,20 @@ part 'get_source_baseurl.g.dart';
|
|||
@riverpod
|
||||
String sourceBaseUrl(SourceBaseUrlRef ref, {required Source source}) {
|
||||
String? baseUrl;
|
||||
if (source.sourceCodeLanguage == SourceCodeLanguage.dart) {
|
||||
try {
|
||||
final bytecode =
|
||||
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
|
||||
|
||||
try {
|
||||
final bytecode =
|
||||
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
|
||||
final runtime = runtimeEval(bytecode);
|
||||
|
||||
final runtime = runtimeEval(bytecode);
|
||||
|
||||
var res = runtime.executeLib('package:mangayomi/main.dart', 'main',
|
||||
[$MSource.wrap(source.toMSource())]);
|
||||
baseUrl = (res as MProvider).baseUrl;
|
||||
} catch (e) {
|
||||
baseUrl = source.baseUrl;
|
||||
}
|
||||
var res = runtime.executeLib('package:mangayomi/main.dart', 'main',
|
||||
[$MSource.wrap(source.toMSource())]);
|
||||
baseUrl = (res as MProvider).baseUrl;
|
||||
} catch (e) {
|
||||
baseUrl = source.baseUrl;
|
||||
}
|
||||
} else {}
|
||||
if (baseUrl == null || baseUrl.isEmpty) {
|
||||
baseUrl = source.baseUrl;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ part of 'get_source_baseurl.dart';
|
|||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$sourceBaseUrlHash() => r'232addc3559f2b77974224a5ed8813eee9a0ba8e';
|
||||
String _$sourceBaseUrlHash() => r'1e4352256b54a61220c09e719e2d0fa907bf6cd9';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
import 'package:dart_eval/dart_eval_bridge.dart';
|
||||
import 'package:mangayomi/eval/bridge/m_source.dart';
|
||||
import 'package:mangayomi/eval/compiler/compiler.dart';
|
||||
import 'package:mangayomi/eval/model/m_provider.dart';
|
||||
import 'package:mangayomi/eval/model/source_preference.dart';
|
||||
import 'package:mangayomi/eval/dart/bridge/m_source.dart';
|
||||
import 'package:mangayomi/eval/dart/compiler/compiler.dart';
|
||||
import 'package:mangayomi/eval/javascript/service.dart';
|
||||
import 'package:mangayomi/eval/dart/model/m_provider.dart';
|
||||
import 'package:mangayomi/eval/dart/model/source_preference.dart';
|
||||
import 'package:mangayomi/models/source.dart';
|
||||
import 'package:mangayomi/eval/runtime/runtime.dart';
|
||||
import 'package:mangayomi/eval/dart/runtime/runtime.dart';
|
||||
|
||||
List<SourcePreference> getSourcePreference({required Source source}) {
|
||||
List<SourcePreference> sourcePreference = [];
|
||||
|
|
@ -26,3 +27,28 @@ List<SourcePreference> getSourcePreference({required Source source}) {
|
|||
|
||||
return sourcePreference;
|
||||
}
|
||||
|
||||
Future<List<SourcePreference>> getSourcePreferenceAsync(
|
||||
{required Source source}) async {
|
||||
List<SourcePreference> sourcePreference = [];
|
||||
if (source.sourceCodeLanguage == SourceCodeLanguage.dart) {
|
||||
try {
|
||||
final bytecode = compilerEval(source.sourceCode!);
|
||||
|
||||
final runtime = runtimeEval(bytecode);
|
||||
|
||||
var res = runtime.executeLib('package:mangayomi/main.dart', 'main',
|
||||
[$MSource.wrap(source.toMSource())]);
|
||||
sourcePreference = (res as MProvider)
|
||||
.getSourcePreferences()
|
||||
.map((e) => (e is $Value ? e.$reified : e) as SourcePreference)
|
||||
.toList();
|
||||
} catch (_) {
|
||||
return [];
|
||||
}
|
||||
} else {
|
||||
sourcePreference = await JsExtensionService(source).getSourcePreferences();
|
||||
}
|
||||
|
||||
return sourcePreference;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,11 @@
|
|||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
import 'package:mangayomi/eval/bridge/m_source.dart';
|
||||
import 'package:mangayomi/eval/model/m_provider.dart';
|
||||
import 'package:mangayomi/eval/compiler/compiler.dart';
|
||||
import 'package:mangayomi/messages/generated.dart';
|
||||
import 'package:mangayomi/eval/dart/bridge/m_source.dart';
|
||||
import 'package:mangayomi/eval/dart/model/m_provider.dart';
|
||||
import 'package:mangayomi/eval/dart/compiler/compiler.dart';
|
||||
import 'package:mangayomi/models/chapter.dart';
|
||||
import 'package:mangayomi/models/video.dart';
|
||||
import 'package:mangayomi/eval/runtime/runtime.dart';
|
||||
import 'package:mangayomi/eval/dart/runtime/runtime.dart';
|
||||
import 'package:mangayomi/providers/storage_provider.dart';
|
||||
import 'package:mangayomi/services/torrent_server.dart';
|
||||
import 'package:mangayomi/sources/utils/utils.dart';
|
||||
|
|
@ -37,8 +36,7 @@ Future<(List<Video>, bool, String?)> getVideoList(
|
|||
await MTorrentServer().getTorrentPlaylist(episode.url!);
|
||||
return (videos, false, infohash);
|
||||
}
|
||||
await finalizeRust();
|
||||
await initializeRust();
|
||||
|
||||
final bytecode =
|
||||
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ part of 'get_video_list.dart';
|
|||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$getVideoListHash() => r'dd1908b1174efac883d05862ea55febf09ad976c';
|
||||
String _$getVideoListHash() => r'dd53ef51fd6c729a985644336d467507e5c7923d';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import 'package:flutter/foundation.dart';
|
||||
import 'package:http_interceptor/http_interceptor.dart';
|
||||
import 'package:mangayomi/eval/model/m_bridge.dart';
|
||||
import 'package:mangayomi/eval/dart/model/m_bridge.dart';
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
import 'package:mangayomi/eval/model/m_source.dart';
|
||||
import 'package:mangayomi/eval/dart/model/m_source.dart';
|
||||
import 'package:mangayomi/main.dart';
|
||||
import 'package:flutter_inappwebview/flutter_inappwebview.dart'
|
||||
as flutter_inappwebview;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
import 'package:mangayomi/eval/bridge/m_source.dart';
|
||||
import 'package:mangayomi/eval/model/filter.dart';
|
||||
import 'package:mangayomi/eval/model/m_pages.dart';
|
||||
import 'package:mangayomi/eval/compiler/compiler.dart';
|
||||
import 'package:mangayomi/eval/model/m_provider.dart';
|
||||
import 'dart:convert';
|
||||
import 'package:mangayomi/eval/dart/bridge/m_source.dart';
|
||||
import 'package:mangayomi/eval/javascript/service.dart';
|
||||
import 'package:mangayomi/eval/dart/model/filter.dart';
|
||||
import 'package:mangayomi/eval/dart/model/m_pages.dart';
|
||||
import 'package:mangayomi/eval/dart/compiler/compiler.dart';
|
||||
import 'package:mangayomi/eval/dart/model/m_provider.dart';
|
||||
import 'package:mangayomi/models/source.dart';
|
||||
import 'package:mangayomi/eval/runtime/runtime.dart';
|
||||
import 'package:mangayomi/eval/dart/runtime/runtime.dart';
|
||||
import 'package:mangayomi/sources/source_test.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
part 'search.g.dart';
|
||||
|
|
@ -16,16 +18,21 @@ Future<MPages?> search(SearchRef ref,
|
|||
required int page,
|
||||
required List<dynamic> filterList}) async {
|
||||
MPages? manga;
|
||||
final bytecode =
|
||||
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
|
||||
final runtime = runtimeEval(bytecode);
|
||||
var res = runtime.executeLib('package:mangayomi/main.dart', 'main',
|
||||
[$MSource.wrap(source.toMSource())]);
|
||||
try {
|
||||
manga =
|
||||
await (res as MProvider).search(query, page, FilterList(filterList));
|
||||
} catch (e) {
|
||||
throw Exception(e);
|
||||
if (source.sourceCodeLanguage == SourceCodeLanguage.dart) {
|
||||
final bytecode =
|
||||
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
|
||||
final runtime = runtimeEval(bytecode);
|
||||
var res = runtime.executeLib('package:mangayomi/main.dart', 'main',
|
||||
[$MSource.wrap(source.toMSource())]);
|
||||
try {
|
||||
manga =
|
||||
await (res as MProvider).search(query, page, FilterList(filterList));
|
||||
} catch (e) {
|
||||
throw Exception(e);
|
||||
}
|
||||
} else {
|
||||
manga = await JsExtensionService(source)
|
||||
.search(query, page, jsonEncode(filterValuesListToJson(filterList)));
|
||||
}
|
||||
return manga;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ part of 'search.dart';
|
|||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$searchHash() => r'685e379023d83ede702d76696d64fccb803e5549';
|
||||
String _$searchHash() => r'aa2fdda26ef0178495a18e0dec5a4bd7f9792fc7';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
|
|
|||
|
|
@ -1,10 +1,13 @@
|
|||
import 'package:mangayomi/eval/bridge/m_source.dart';
|
||||
import 'package:mangayomi/eval/model/filter.dart';
|
||||
import 'package:mangayomi/eval/model/m_pages.dart';
|
||||
import 'package:mangayomi/eval/compiler/compiler.dart';
|
||||
import 'package:mangayomi/eval/model/m_provider.dart';
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:mangayomi/eval/dart/bridge/m_source.dart';
|
||||
import 'package:mangayomi/eval/javascript/service.dart';
|
||||
import 'package:mangayomi/eval/dart/model/filter.dart';
|
||||
import 'package:mangayomi/eval/dart/model/m_pages.dart';
|
||||
import 'package:mangayomi/eval/dart/compiler/compiler.dart';
|
||||
import 'package:mangayomi/eval/dart/model/m_provider.dart';
|
||||
import 'package:mangayomi/models/source.dart';
|
||||
import 'package:mangayomi/eval/runtime/runtime.dart';
|
||||
import 'package:mangayomi/eval/dart/runtime/runtime.dart';
|
||||
import 'package:mangayomi/sources/source_test.dart';
|
||||
|
||||
Future<MPages?> search(
|
||||
|
|
@ -13,16 +16,21 @@ Future<MPages?> search(
|
|||
required int page,
|
||||
required List<dynamic> filterList}) async {
|
||||
MPages? manga;
|
||||
final bytecode =
|
||||
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
|
||||
final runtime = runtimeEval(bytecode);
|
||||
var res = runtime.executeLib('package:mangayomi/main.dart', 'main',
|
||||
[$MSource.wrap(source.toMSource())]);
|
||||
try {
|
||||
manga =
|
||||
await (res as MProvider).search(query, page, FilterList(filterList));
|
||||
} catch (e) {
|
||||
throw Exception(e);
|
||||
if (source.sourceCodeLanguage == SourceCodeLanguage.dart) {
|
||||
final bytecode =
|
||||
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
|
||||
final runtime = runtimeEval(bytecode);
|
||||
var res = runtime.executeLib('package:mangayomi/main.dart', 'main',
|
||||
[$MSource.wrap(source.toMSource())]);
|
||||
try {
|
||||
manga =
|
||||
await (res as MProvider).search(query, page, FilterList(filterList));
|
||||
} catch (e) {
|
||||
throw Exception(e);
|
||||
}
|
||||
} else {
|
||||
manga = await JsExtensionService(source)
|
||||
.search(query, page, jsonEncode(filterValuesListToJson(filterList)));
|
||||
}
|
||||
return manga;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import 'package:mangayomi/eval/bridge/m_source.dart';
|
||||
import 'package:mangayomi/eval/compiler/compiler.dart';
|
||||
import 'package:mangayomi/eval/model/m_provider.dart';
|
||||
import 'package:mangayomi/eval/dart/bridge/m_source.dart';
|
||||
import 'package:mangayomi/eval/dart/compiler/compiler.dart';
|
||||
import 'package:mangayomi/eval/dart/model/m_provider.dart';
|
||||
import 'package:mangayomi/models/source.dart';
|
||||
import 'package:mangayomi/eval/runtime/runtime.dart';
|
||||
import 'package:mangayomi/eval/dart/runtime/runtime.dart';
|
||||
import 'package:mangayomi/sources/source_test.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
part 'supports_latest.g.dart';
|
||||
|
|
@ -10,19 +10,21 @@ part 'supports_latest.g.dart';
|
|||
@riverpod
|
||||
bool supportsLatest(SupportsLatestRef ref, {required Source source}) {
|
||||
bool? supportsLatest;
|
||||
if (source.sourceCodeLanguage == SourceCodeLanguage.dart) {
|
||||
try {
|
||||
final bytecode =
|
||||
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
|
||||
|
||||
try {
|
||||
final bytecode =
|
||||
compilerEval(useTestSourceCode ? testSourceCode : source.sourceCode!);
|
||||
final runtime = runtimeEval(bytecode);
|
||||
|
||||
final runtime = runtimeEval(bytecode);
|
||||
|
||||
var res = runtime.executeLib('package:mangayomi/main.dart', 'main',
|
||||
[$MSource.wrap(source.toMSource())]);
|
||||
supportsLatest = (res as MProvider).supportsLatest;
|
||||
} catch (e) {
|
||||
var res = runtime.executeLib('package:mangayomi/main.dart', 'main',
|
||||
[$MSource.wrap(source.toMSource())]);
|
||||
supportsLatest = (res as MProvider).supportsLatest;
|
||||
} catch (e) {
|
||||
supportsLatest = true;
|
||||
}
|
||||
} else {
|
||||
supportsLatest = true;
|
||||
}
|
||||
|
||||
return supportsLatest;
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue