fix & reformat
This commit is contained in:
parent
0c84faa5f8
commit
a41ccaff22
228 changed files with 8642 additions and 3604 deletions
|
|
@ -9,13 +9,15 @@ import 'package:mangayomi/eval/model/element.dart';
|
||||||
class $MDocument implements MDocument, $Instance {
|
class $MDocument implements MDocument, $Instance {
|
||||||
$MDocument.wrap(this.$value) : _superclass = $Object($value);
|
$MDocument.wrap(this.$value) : _superclass = $Object($value);
|
||||||
|
|
||||||
static const $type = BridgeTypeRef(BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'MDocument'));
|
static const $type = BridgeTypeRef(
|
||||||
|
BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'MDocument'));
|
||||||
|
|
||||||
static const $declaration = BridgeClassDef(BridgeClassType($type),
|
static const $declaration = BridgeClassDef(BridgeClassType($type),
|
||||||
constructors: {
|
constructors: {
|
||||||
'': BridgeConstructorDef(
|
'': BridgeConstructorDef(
|
||||||
BridgeFunctionDef(returns: BridgeTypeAnnotation($type), params: [
|
BridgeFunctionDef(returns: BridgeTypeAnnotation($type), params: [
|
||||||
BridgeParameter('document', BridgeTypeAnnotation($Element.$type, nullable: true), false),
|
BridgeParameter('document',
|
||||||
|
BridgeTypeAnnotation($Element.$type, nullable: true), false),
|
||||||
]),
|
]),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
|
@ -36,60 +38,118 @@ class $MDocument implements MDocument, $Instance {
|
||||||
returns: BridgeTypeAnnotation($MElement.$type, nullable: true),
|
returns: BridgeTypeAnnotation($MElement.$type, nullable: true),
|
||||||
)),
|
)),
|
||||||
'outerHtml': BridgeMethodDef(BridgeFunctionDef(
|
'outerHtml': BridgeMethodDef(BridgeFunctionDef(
|
||||||
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string), nullable: true),
|
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string),
|
||||||
|
nullable: true),
|
||||||
)),
|
)),
|
||||||
'text': BridgeMethodDef(BridgeFunctionDef(
|
'text': BridgeMethodDef(BridgeFunctionDef(
|
||||||
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string), nullable: true),
|
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string),
|
||||||
|
nullable: true),
|
||||||
)),
|
)),
|
||||||
'children': BridgeMethodDef(BridgeFunctionDef(
|
'children': BridgeMethodDef(BridgeFunctionDef(
|
||||||
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.list, [$MElement.$type]), nullable: true),
|
returns: BridgeTypeAnnotation(
|
||||||
|
BridgeTypeRef(CoreTypes.list, [$MElement.$type]),
|
||||||
|
nullable: true),
|
||||||
)),
|
)),
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
'select': BridgeMethodDef(
|
'select': BridgeMethodDef(
|
||||||
BridgeFunctionDef(
|
BridgeFunctionDef(
|
||||||
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.list, [$MElement.$type]), nullable: true),
|
returns: BridgeTypeAnnotation(
|
||||||
params: [BridgeParameter('selector', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false)]),
|
BridgeTypeRef(CoreTypes.list, [$MElement.$type]),
|
||||||
|
nullable: true),
|
||||||
|
params: [
|
||||||
|
BridgeParameter(
|
||||||
|
'selector',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)),
|
||||||
|
false)
|
||||||
|
]),
|
||||||
),
|
),
|
||||||
'selectFirst': BridgeMethodDef(
|
'selectFirst': BridgeMethodDef(
|
||||||
BridgeFunctionDef(
|
BridgeFunctionDef(
|
||||||
returns: BridgeTypeAnnotation($MElement.$type, nullable: true),
|
returns: BridgeTypeAnnotation($MElement.$type, nullable: true),
|
||||||
params: [BridgeParameter('selector', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false)]),
|
params: [
|
||||||
|
BridgeParameter(
|
||||||
|
'selector',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)),
|
||||||
|
false)
|
||||||
|
]),
|
||||||
),
|
),
|
||||||
'getElementsByClassName': BridgeMethodDef(
|
'getElementsByClassName': BridgeMethodDef(
|
||||||
BridgeFunctionDef(
|
BridgeFunctionDef(
|
||||||
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.list, [$type]), nullable: true),
|
returns: BridgeTypeAnnotation(
|
||||||
params: [BridgeParameter('classNames', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false)]),
|
BridgeTypeRef(CoreTypes.list, [$type]),
|
||||||
|
nullable: true),
|
||||||
|
params: [
|
||||||
|
BridgeParameter(
|
||||||
|
'classNames',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)),
|
||||||
|
false)
|
||||||
|
]),
|
||||||
),
|
),
|
||||||
'getElementsByTagName': BridgeMethodDef(
|
'getElementsByTagName': BridgeMethodDef(
|
||||||
BridgeFunctionDef(
|
BridgeFunctionDef(
|
||||||
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.list, [$type]), nullable: true),
|
returns: BridgeTypeAnnotation(
|
||||||
params: [BridgeParameter('localNames', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false)]),
|
BridgeTypeRef(CoreTypes.list, [$type]),
|
||||||
|
nullable: true),
|
||||||
|
params: [
|
||||||
|
BridgeParameter(
|
||||||
|
'localNames',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)),
|
||||||
|
false)
|
||||||
|
]),
|
||||||
),
|
),
|
||||||
'getElementById': BridgeMethodDef(
|
'getElementById': BridgeMethodDef(
|
||||||
BridgeFunctionDef(
|
BridgeFunctionDef(
|
||||||
returns: BridgeTypeAnnotation($MElement.$type, nullable: true),
|
returns: BridgeTypeAnnotation($MElement.$type, nullable: true),
|
||||||
params: [BridgeParameter('id', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false)]),
|
params: [
|
||||||
|
BridgeParameter(
|
||||||
|
'id',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)),
|
||||||
|
false)
|
||||||
|
]),
|
||||||
),
|
),
|
||||||
'xpath': BridgeMethodDef(
|
'xpath': BridgeMethodDef(
|
||||||
BridgeFunctionDef(
|
BridgeFunctionDef(
|
||||||
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.list, [BridgeTypeRef(CoreTypes.string)])),
|
returns: BridgeTypeAnnotation(BridgeTypeRef(
|
||||||
params: [BridgeParameter('xpath', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false)]),
|
CoreTypes.list, [BridgeTypeRef(CoreTypes.string)])),
|
||||||
|
params: [
|
||||||
|
BridgeParameter(
|
||||||
|
'xpath',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)),
|
||||||
|
false)
|
||||||
|
]),
|
||||||
),
|
),
|
||||||
'xpathFirst': BridgeMethodDef(
|
'xpathFirst': BridgeMethodDef(
|
||||||
BridgeFunctionDef(
|
BridgeFunctionDef(
|
||||||
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string), nullable: true),
|
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string),
|
||||||
params: [BridgeParameter('xpath', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false)]),
|
nullable: true),
|
||||||
|
params: [
|
||||||
|
BridgeParameter(
|
||||||
|
'xpath',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)),
|
||||||
|
false)
|
||||||
|
]),
|
||||||
),
|
),
|
||||||
'attr': BridgeMethodDef(
|
'attr': BridgeMethodDef(
|
||||||
BridgeFunctionDef(returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), params: [
|
BridgeFunctionDef(
|
||||||
BridgeParameter('attr', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string), nullable: true), false)
|
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)),
|
||||||
]),
|
params: [
|
||||||
|
BridgeParameter(
|
||||||
|
'attr',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string),
|
||||||
|
nullable: true),
|
||||||
|
false)
|
||||||
|
]),
|
||||||
),
|
),
|
||||||
'hasAttr': BridgeMethodDef(
|
'hasAttr': BridgeMethodDef(
|
||||||
BridgeFunctionDef(
|
BridgeFunctionDef(
|
||||||
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.bool)),
|
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.bool)),
|
||||||
params: [BridgeParameter('attr', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false)]),
|
params: [
|
||||||
|
BridgeParameter(
|
||||||
|
'attr',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)),
|
||||||
|
false)
|
||||||
|
]),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
wrap: true);
|
wrap: true);
|
||||||
|
|
@ -125,7 +185,9 @@ class $MDocument implements MDocument, $Instance {
|
||||||
return res == null ? const $null() : $String(res);
|
return res == null ? const $null() : $String(res);
|
||||||
case 'children':
|
case 'children':
|
||||||
final res = $value.children;
|
final res = $value.children;
|
||||||
return res == null ? const $null() : $List.wrap(res.map((e) => $MElement.wrap(e)).toList());
|
return res == null
|
||||||
|
? const $null()
|
||||||
|
: $List.wrap(res.map((e) => $MElement.wrap(e)).toList());
|
||||||
case 'select':
|
case 'select':
|
||||||
return __select;
|
return __select;
|
||||||
case 'selectFirst':
|
case 'selectFirst':
|
||||||
|
|
@ -156,59 +218,79 @@ class $MDocument implements MDocument, $Instance {
|
||||||
void $setProperty(Runtime runtime, String identifier, $Value value) {}
|
void $setProperty(Runtime runtime, String identifier, $Value value) {}
|
||||||
|
|
||||||
static const $Function __select = $Function(_select);
|
static const $Function __select = $Function(_select);
|
||||||
static $Value? _select(final Runtime runtime, final $Value? target, final List<$Value?> args) {
|
static $Value? _select(
|
||||||
|
final Runtime runtime, final $Value? target, final List<$Value?> args) {
|
||||||
final res = (target!.$value as MDocument).select(args[0]?.$value);
|
final res = (target!.$value as MDocument).select(args[0]?.$value);
|
||||||
return res == null ? const $null() : $List.wrap(res.map((e) => $MElement.wrap(e)).toList());
|
return res == null
|
||||||
|
? const $null()
|
||||||
|
: $List.wrap(res.map((e) => $MElement.wrap(e)).toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
static const $Function __selectFirst = $Function(_selectFirst);
|
static const $Function __selectFirst = $Function(_selectFirst);
|
||||||
static $Value? _selectFirst(final Runtime runtime, final $Value? target, final List<$Value?> args) {
|
static $Value? _selectFirst(
|
||||||
|
final Runtime runtime, final $Value? target, final List<$Value?> args) {
|
||||||
final res = (target!.$value as MDocument).selectFirst(args[0]?.$value);
|
final res = (target!.$value as MDocument).selectFirst(args[0]?.$value);
|
||||||
return res == null ? const $null() : $MElement.wrap(res);
|
return res == null ? const $null() : $MElement.wrap(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
static $Value? $new(final Runtime runtime, final $Value? target, final List<$Value?> args) {
|
static $Value? $new(
|
||||||
|
final Runtime runtime, final $Value? target, final List<$Value?> args) {
|
||||||
return $MDocument.wrap(MDocument(args[0]?.$value));
|
return $MDocument.wrap(MDocument(args[0]?.$value));
|
||||||
}
|
}
|
||||||
|
|
||||||
static const $Function __getElementsByClassName = $Function(_getElementsByClassName);
|
static const $Function __getElementsByClassName =
|
||||||
static $Value? _getElementsByClassName(final Runtime runtime, final $Value? target, final List<$Value?> args) {
|
$Function(_getElementsByClassName);
|
||||||
final res = (target!.$value as MDocument).getElementsByClassName(args[0]?.$value);
|
static $Value? _getElementsByClassName(
|
||||||
return res == null ? const $null() : $List.wrap(res.map((e) => $MElement.wrap(e)).toList());
|
final Runtime runtime, final $Value? target, final List<$Value?> args) {
|
||||||
|
final res =
|
||||||
|
(target!.$value as MDocument).getElementsByClassName(args[0]?.$value);
|
||||||
|
return res == null
|
||||||
|
? const $null()
|
||||||
|
: $List.wrap(res.map((e) => $MElement.wrap(e)).toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
static const $Function __getElementsByTagName = $Function(_getElementsByTagName);
|
static const $Function __getElementsByTagName =
|
||||||
static $Value? _getElementsByTagName(final Runtime runtime, final $Value? target, final List<$Value?> args) {
|
$Function(_getElementsByTagName);
|
||||||
final res = (target!.$value as MDocument).getElementsByTagName(args[0]?.$value);
|
static $Value? _getElementsByTagName(
|
||||||
return res == null ? const $null() : $List.wrap(res.map((e) => $MElement.wrap(e)).toList());
|
final Runtime runtime, final $Value? target, final List<$Value?> args) {
|
||||||
|
final res =
|
||||||
|
(target!.$value as MDocument).getElementsByTagName(args[0]?.$value);
|
||||||
|
return res == null
|
||||||
|
? const $null()
|
||||||
|
: $List.wrap(res.map((e) => $MElement.wrap(e)).toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
static const $Function __getElementById = $Function(_getElementById);
|
static const $Function __getElementById = $Function(_getElementById);
|
||||||
static $Value? _getElementById(final Runtime runtime, final $Value? target, final List<$Value?> args) {
|
static $Value? _getElementById(
|
||||||
|
final Runtime runtime, final $Value? target, final List<$Value?> args) {
|
||||||
final res = (target!.$value as MDocument).getElementById(args[0]?.$value);
|
final res = (target!.$value as MDocument).getElementById(args[0]?.$value);
|
||||||
return res == null ? const $null() : $MElement.wrap(res);
|
return res == null ? const $null() : $MElement.wrap(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const $Function __xpath = $Function(_xpath);
|
static const $Function __xpath = $Function(_xpath);
|
||||||
static $Value? _xpath(final Runtime runtime, final $Value? target, final List<$Value?> args) {
|
static $Value? _xpath(
|
||||||
|
final Runtime runtime, final $Value? target, final List<$Value?> args) {
|
||||||
final res = (target!.$value as MDocument).xpath(args[0]?.$value);
|
final res = (target!.$value as MDocument).xpath(args[0]?.$value);
|
||||||
return $List.wrap(res.map((e) => $String(e)).toList());
|
return $List.wrap(res.map((e) => $String(e)).toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
static const $Function __xpathFirst = $Function(_xpathFirst);
|
static const $Function __xpathFirst = $Function(_xpathFirst);
|
||||||
static $Value? _xpathFirst(final Runtime runtime, final $Value? target, final List<$Value?> args) {
|
static $Value? _xpathFirst(
|
||||||
|
final Runtime runtime, final $Value? target, final List<$Value?> args) {
|
||||||
final res = (target!.$value as MDocument).xpathFirst(args[0]?.$value);
|
final res = (target!.$value as MDocument).xpathFirst(args[0]?.$value);
|
||||||
return res == null ? const $null() : $String(res);
|
return res == null ? const $null() : $String(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const $Function __attr = $Function(_attr);
|
static const $Function __attr = $Function(_attr);
|
||||||
static $Value? _attr(final Runtime runtime, final $Value? target, final List<$Value?> args) {
|
static $Value? _attr(
|
||||||
|
final Runtime runtime, final $Value? target, final List<$Value?> args) {
|
||||||
final res = (target!.$value as MDocument).attr(args[0]?.$value ?? "");
|
final res = (target!.$value as MDocument).attr(args[0]?.$value ?? "");
|
||||||
return res == null ? const $null() : $String(res);
|
return res == null ? const $null() : $String(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const $Function __hasAttr = $Function(_hasAttr);
|
static const $Function __hasAttr = $Function(_hasAttr);
|
||||||
static $Value? _hasAttr(final Runtime runtime, final $Value? target, final List<$Value?> args) {
|
static $Value? _hasAttr(
|
||||||
|
final Runtime runtime, final $Value? target, final List<$Value?> args) {
|
||||||
final res = (target!.$value as MDocument).attr(args[0]?.$value ?? "");
|
final res = (target!.$value as MDocument).attr(args[0]?.$value ?? "");
|
||||||
return res == null ? const $null() : $String(res);
|
return res == null ? const $null() : $String(res);
|
||||||
}
|
}
|
||||||
|
|
@ -226,10 +308,12 @@ class $MDocument implements MDocument, $Instance {
|
||||||
String? xpathFirst(String xpath) => $value.xpathFirst(xpath);
|
String? xpathFirst(String xpath) => $value.xpathFirst(xpath);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<MElement>? getElementsByClassName(String classNames) => $value.getElementsByClassName(classNames);
|
List<MElement>? getElementsByClassName(String classNames) =>
|
||||||
|
$value.getElementsByClassName(classNames);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<MElement>? getElementsByTagName(String localNames) => $value.getElementsByTagName(localNames);
|
List<MElement>? getElementsByTagName(String localNames) =>
|
||||||
|
$value.getElementsByTagName(localNames);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String? attr(String attr) => $value.attr(attr);
|
String? attr(String attr) => $value.attr(attr);
|
||||||
|
|
@ -265,11 +349,15 @@ class $MDocument implements MDocument, $Instance {
|
||||||
class $Document implements $Instance {
|
class $Document implements $Instance {
|
||||||
$Document.wrap(this.$value) : _superclass = $Object($value);
|
$Document.wrap(this.$value) : _superclass = $Object($value);
|
||||||
|
|
||||||
static const $type = BridgeTypeRef(BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'Document'));
|
static const $type = BridgeTypeRef(
|
||||||
|
BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'Document'));
|
||||||
|
|
||||||
static const $declaration = BridgeClassDef(
|
static const $declaration = BridgeClassDef(
|
||||||
BridgeClassType($type),
|
BridgeClassType($type),
|
||||||
constructors: {'': BridgeConstructorDef(BridgeFunctionDef(returns: BridgeTypeAnnotation($type, nullable: true)))},
|
constructors: {
|
||||||
|
'': BridgeConstructorDef(BridgeFunctionDef(
|
||||||
|
returns: BridgeTypeAnnotation($type, nullable: true)))
|
||||||
|
},
|
||||||
wrap: true,
|
wrap: true,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,13 +5,15 @@ import 'package:mangayomi/eval/model/element.dart';
|
||||||
|
|
||||||
class $MElement implements MElement, $Instance {
|
class $MElement implements MElement, $Instance {
|
||||||
$MElement.wrap(this.$value) : _superclass = $Object($value);
|
$MElement.wrap(this.$value) : _superclass = $Object($value);
|
||||||
static const $type = BridgeTypeRef(BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'MElement'));
|
static const $type = BridgeTypeRef(
|
||||||
|
BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'MElement'));
|
||||||
|
|
||||||
static const $declaration = BridgeClassDef(BridgeClassType($type),
|
static const $declaration = BridgeClassDef(BridgeClassType($type),
|
||||||
constructors: {
|
constructors: {
|
||||||
'': BridgeConstructorDef(
|
'': BridgeConstructorDef(
|
||||||
BridgeFunctionDef(returns: BridgeTypeAnnotation($type), params: [
|
BridgeFunctionDef(returns: BridgeTypeAnnotation($type), params: [
|
||||||
BridgeParameter('element', BridgeTypeAnnotation($Element.$type, nullable: true), false),
|
BridgeParameter('element',
|
||||||
|
BridgeTypeAnnotation($Element.$type, nullable: true), false),
|
||||||
]),
|
]),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
|
@ -20,37 +22,48 @@ class $MElement implements MElement, $Instance {
|
||||||
},
|
},
|
||||||
getters: {
|
getters: {
|
||||||
'outerHtml': BridgeMethodDef(BridgeFunctionDef(
|
'outerHtml': BridgeMethodDef(BridgeFunctionDef(
|
||||||
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string), nullable: true),
|
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string),
|
||||||
|
nullable: true),
|
||||||
)),
|
)),
|
||||||
'innerHtml': BridgeMethodDef(BridgeFunctionDef(
|
'innerHtml': BridgeMethodDef(BridgeFunctionDef(
|
||||||
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string), nullable: true),
|
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string),
|
||||||
|
nullable: true),
|
||||||
)),
|
)),
|
||||||
'text': BridgeMethodDef(BridgeFunctionDef(
|
'text': BridgeMethodDef(BridgeFunctionDef(
|
||||||
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string), nullable: true),
|
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string),
|
||||||
|
nullable: true),
|
||||||
)),
|
)),
|
||||||
'className': BridgeMethodDef(BridgeFunctionDef(
|
'className': BridgeMethodDef(BridgeFunctionDef(
|
||||||
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string), nullable: true),
|
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string),
|
||||||
|
nullable: true),
|
||||||
)),
|
)),
|
||||||
'localName': BridgeMethodDef(BridgeFunctionDef(
|
'localName': BridgeMethodDef(BridgeFunctionDef(
|
||||||
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string), nullable: true),
|
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string),
|
||||||
|
nullable: true),
|
||||||
)),
|
)),
|
||||||
'namespaceUri': BridgeMethodDef(BridgeFunctionDef(
|
'namespaceUri': BridgeMethodDef(BridgeFunctionDef(
|
||||||
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string), nullable: true),
|
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string),
|
||||||
|
nullable: true),
|
||||||
)),
|
)),
|
||||||
'getSrc': BridgeMethodDef(BridgeFunctionDef(
|
'getSrc': BridgeMethodDef(BridgeFunctionDef(
|
||||||
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string), nullable: true),
|
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string),
|
||||||
|
nullable: true),
|
||||||
)),
|
)),
|
||||||
'getImg': BridgeMethodDef(BridgeFunctionDef(
|
'getImg': BridgeMethodDef(BridgeFunctionDef(
|
||||||
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string), nullable: true),
|
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string),
|
||||||
|
nullable: true),
|
||||||
)),
|
)),
|
||||||
'getHref': BridgeMethodDef(BridgeFunctionDef(
|
'getHref': BridgeMethodDef(BridgeFunctionDef(
|
||||||
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string), nullable: true),
|
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string),
|
||||||
|
nullable: true),
|
||||||
)),
|
)),
|
||||||
'getDataSrc': BridgeMethodDef(BridgeFunctionDef(
|
'getDataSrc': BridgeMethodDef(BridgeFunctionDef(
|
||||||
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string), nullable: true),
|
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string),
|
||||||
|
nullable: true),
|
||||||
)),
|
)),
|
||||||
'children': BridgeMethodDef(BridgeFunctionDef(
|
'children': BridgeMethodDef(BridgeFunctionDef(
|
||||||
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.list, [$type]), nullable: true),
|
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.list, [$type]),
|
||||||
|
nullable: true),
|
||||||
)),
|
)),
|
||||||
'parent': BridgeMethodDef(BridgeFunctionDef(
|
'parent': BridgeMethodDef(BridgeFunctionDef(
|
||||||
returns: BridgeTypeAnnotation($type, nullable: true),
|
returns: BridgeTypeAnnotation($type, nullable: true),
|
||||||
|
|
@ -64,48 +77,100 @@ class $MElement implements MElement, $Instance {
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
'attr': BridgeMethodDef(
|
'attr': BridgeMethodDef(
|
||||||
BridgeFunctionDef(returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), params: [
|
BridgeFunctionDef(
|
||||||
BridgeParameter('attr', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string), nullable: true), false)
|
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)),
|
||||||
]),
|
params: [
|
||||||
|
BridgeParameter(
|
||||||
|
'attr',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string),
|
||||||
|
nullable: true),
|
||||||
|
false)
|
||||||
|
]),
|
||||||
),
|
),
|
||||||
'text': BridgeMethodDef(
|
'text': BridgeMethodDef(
|
||||||
BridgeFunctionDef(returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string), nullable: true)),
|
BridgeFunctionDef(
|
||||||
|
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string),
|
||||||
|
nullable: true)),
|
||||||
),
|
),
|
||||||
'select': BridgeMethodDef(
|
'select': BridgeMethodDef(
|
||||||
BridgeFunctionDef(
|
BridgeFunctionDef(
|
||||||
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.list, [$type]), nullable: true),
|
returns: BridgeTypeAnnotation(
|
||||||
params: [BridgeParameter('selector', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false)]),
|
BridgeTypeRef(CoreTypes.list, [$type]),
|
||||||
|
nullable: true),
|
||||||
|
params: [
|
||||||
|
BridgeParameter(
|
||||||
|
'selector',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)),
|
||||||
|
false)
|
||||||
|
]),
|
||||||
),
|
),
|
||||||
'selectFirst': BridgeMethodDef(
|
'selectFirst': BridgeMethodDef(
|
||||||
BridgeFunctionDef(
|
BridgeFunctionDef(
|
||||||
returns: BridgeTypeAnnotation($type, nullable: true),
|
returns: BridgeTypeAnnotation($type, nullable: true),
|
||||||
params: [BridgeParameter('selector', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false)]),
|
params: [
|
||||||
|
BridgeParameter(
|
||||||
|
'selector',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)),
|
||||||
|
false)
|
||||||
|
]),
|
||||||
),
|
),
|
||||||
'getElementsByClassName': BridgeMethodDef(
|
'getElementsByClassName': BridgeMethodDef(
|
||||||
BridgeFunctionDef(
|
BridgeFunctionDef(
|
||||||
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.list, [$type]), nullable: true),
|
returns: BridgeTypeAnnotation(
|
||||||
params: [BridgeParameter('classNames', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false)]),
|
BridgeTypeRef(CoreTypes.list, [$type]),
|
||||||
|
nullable: true),
|
||||||
|
params: [
|
||||||
|
BridgeParameter(
|
||||||
|
'classNames',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)),
|
||||||
|
false)
|
||||||
|
]),
|
||||||
),
|
),
|
||||||
'getElementsByTagName': BridgeMethodDef(
|
'getElementsByTagName': BridgeMethodDef(
|
||||||
BridgeFunctionDef(
|
BridgeFunctionDef(
|
||||||
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.list, [$type]), nullable: true),
|
returns: BridgeTypeAnnotation(
|
||||||
params: [BridgeParameter('localNames', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false)]),
|
BridgeTypeRef(CoreTypes.list, [$type]),
|
||||||
|
nullable: true),
|
||||||
|
params: [
|
||||||
|
BridgeParameter(
|
||||||
|
'localNames',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)),
|
||||||
|
false)
|
||||||
|
]),
|
||||||
),
|
),
|
||||||
'xpath': BridgeMethodDef(
|
'xpath': BridgeMethodDef(
|
||||||
BridgeFunctionDef(
|
BridgeFunctionDef(
|
||||||
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.list, [BridgeTypeRef(CoreTypes.string)]),
|
returns: BridgeTypeAnnotation(
|
||||||
|
BridgeTypeRef(
|
||||||
|
CoreTypes.list, [BridgeTypeRef(CoreTypes.string)]),
|
||||||
nullable: true),
|
nullable: true),
|
||||||
params: [BridgeParameter('xpath', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false)]),
|
params: [
|
||||||
|
BridgeParameter(
|
||||||
|
'xpath',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)),
|
||||||
|
false)
|
||||||
|
]),
|
||||||
),
|
),
|
||||||
'xpathFirst': BridgeMethodDef(
|
'xpathFirst': BridgeMethodDef(
|
||||||
BridgeFunctionDef(
|
BridgeFunctionDef(
|
||||||
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string), nullable: true),
|
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string),
|
||||||
params: [BridgeParameter('xpath', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false)]),
|
nullable: true),
|
||||||
|
params: [
|
||||||
|
BridgeParameter(
|
||||||
|
'xpath',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)),
|
||||||
|
false)
|
||||||
|
]),
|
||||||
),
|
),
|
||||||
'hasAttr': BridgeMethodDef(
|
'hasAttr': BridgeMethodDef(
|
||||||
BridgeFunctionDef(
|
BridgeFunctionDef(
|
||||||
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.bool)),
|
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.bool)),
|
||||||
params: [BridgeParameter('attr', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false)]),
|
params: [
|
||||||
|
BridgeParameter(
|
||||||
|
'attr',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)),
|
||||||
|
false)
|
||||||
|
]),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
wrap: true);
|
wrap: true);
|
||||||
|
|
@ -129,28 +194,44 @@ class $MElement implements MElement, $Instance {
|
||||||
return res == null ? const $null() : $String(res);
|
return res == null ? const $null() : $String(res);
|
||||||
case 'text':
|
case 'text':
|
||||||
final res = $value.text;
|
final res = $value.text;
|
||||||
return res == null ? const $null() : $String(res.trim().trimLeft().trimRight());
|
return res == null
|
||||||
|
? const $null()
|
||||||
|
: $String(res.trim().trimLeft().trimRight());
|
||||||
case 'className':
|
case 'className':
|
||||||
final res = $value.className;
|
final res = $value.className;
|
||||||
return res == null ? const $null() : $String(res.trim().trimLeft().trimRight());
|
return res == null
|
||||||
|
? const $null()
|
||||||
|
: $String(res.trim().trimLeft().trimRight());
|
||||||
case 'localName':
|
case 'localName':
|
||||||
final res = $value.localName;
|
final res = $value.localName;
|
||||||
return res == null ? const $null() : $String(res.trim().trimLeft().trimRight());
|
return res == null
|
||||||
|
? const $null()
|
||||||
|
: $String(res.trim().trimLeft().trimRight());
|
||||||
case 'namespaceUri':
|
case 'namespaceUri':
|
||||||
final res = $value.namespaceUri;
|
final res = $value.namespaceUri;
|
||||||
return res == null ? const $null() : $String(res.trim().trimLeft().trimRight());
|
return res == null
|
||||||
|
? const $null()
|
||||||
|
: $String(res.trim().trimLeft().trimRight());
|
||||||
case 'getSrc':
|
case 'getSrc':
|
||||||
final res = $value.getSrc;
|
final res = $value.getSrc;
|
||||||
return res == null ? const $null() : $String(res.trim().trimLeft().trimRight());
|
return res == null
|
||||||
|
? const $null()
|
||||||
|
: $String(res.trim().trimLeft().trimRight());
|
||||||
case 'getImg':
|
case 'getImg':
|
||||||
final res = $value.getImg;
|
final res = $value.getImg;
|
||||||
return res == null ? const $null() : $String(res.trim().trimLeft().trimRight());
|
return res == null
|
||||||
|
? const $null()
|
||||||
|
: $String(res.trim().trimLeft().trimRight());
|
||||||
case 'getHref':
|
case 'getHref':
|
||||||
final res = $value.getHref;
|
final res = $value.getHref;
|
||||||
return res == null ? const $null() : $String(res.trim().trimLeft().trimRight());
|
return res == null
|
||||||
|
? const $null()
|
||||||
|
: $String(res.trim().trimLeft().trimRight());
|
||||||
case 'getDataSrc':
|
case 'getDataSrc':
|
||||||
final res = $value.getDataSrc;
|
final res = $value.getDataSrc;
|
||||||
return res == null ? const $null() : $String(res.trim().trimLeft().trimRight());
|
return res == null
|
||||||
|
? const $null()
|
||||||
|
: $String(res.trim().trimLeft().trimRight());
|
||||||
case 'parent':
|
case 'parent':
|
||||||
final res = $value.parent;
|
final res = $value.parent;
|
||||||
return res == null ? const $null() : $MElement.wrap(res);
|
return res == null ? const $null() : $MElement.wrap(res);
|
||||||
|
|
@ -187,62 +268,83 @@ class $MElement implements MElement, $Instance {
|
||||||
@override
|
@override
|
||||||
void $setProperty(Runtime runtime, String identifier, $Value value) {}
|
void $setProperty(Runtime runtime, String identifier, $Value value) {}
|
||||||
|
|
||||||
static $Value? $new(final Runtime runtime, final $Value? target, final List<$Value?> args) {
|
static $Value? $new(
|
||||||
|
final Runtime runtime, final $Value? target, final List<$Value?> args) {
|
||||||
return $MElement.wrap(MElement(args[0]?.$value));
|
return $MElement.wrap(MElement(args[0]?.$value));
|
||||||
}
|
}
|
||||||
|
|
||||||
static const $Function __attr = $Function(_attr);
|
static const $Function __attr = $Function(_attr);
|
||||||
|
|
||||||
static $Value? _attr(final Runtime runtime, final $Value? target, final List<$Value?> args) {
|
static $Value? _attr(
|
||||||
|
final Runtime runtime, final $Value? target, final List<$Value?> args) {
|
||||||
final res = (target!.$value as MElement).attr(args[0]?.$value ?? "");
|
final res = (target!.$value as MElement).attr(args[0]?.$value ?? "");
|
||||||
return res == null ? const $null() : $String(res);
|
return res == null ? const $null() : $String(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const $Function __select = $Function(_select);
|
static const $Function __select = $Function(_select);
|
||||||
|
|
||||||
static $Value? _select(final Runtime runtime, final $Value? target, final List<$Value?> args) {
|
static $Value? _select(
|
||||||
|
final Runtime runtime, final $Value? target, final List<$Value?> args) {
|
||||||
final res = (target!.$value as MElement).select(args[0]?.$value);
|
final res = (target!.$value as MElement).select(args[0]?.$value);
|
||||||
return res == null ? const $null() : $List.wrap(res.map((e) => $MElement.wrap(e)).toList());
|
return res == null
|
||||||
|
? const $null()
|
||||||
|
: $List.wrap(res.map((e) => $MElement.wrap(e)).toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
static const $Function __selectFirst = $Function(_selectFirst);
|
static const $Function __selectFirst = $Function(_selectFirst);
|
||||||
|
|
||||||
static $Value? _selectFirst(final Runtime runtime, final $Value? target, final List<$Value?> args) {
|
static $Value? _selectFirst(
|
||||||
|
final Runtime runtime, final $Value? target, final List<$Value?> args) {
|
||||||
final res = (target!.$value as MElement).selectFirst(args[0]?.$value);
|
final res = (target!.$value as MElement).selectFirst(args[0]?.$value);
|
||||||
return res == null ? const $null() : $MElement.wrap(res);
|
return res == null ? const $null() : $MElement.wrap(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const $Function __getElementsByClassName = $Function(_getElementsByClassName);
|
static const $Function __getElementsByClassName =
|
||||||
|
$Function(_getElementsByClassName);
|
||||||
|
|
||||||
static $Value? _getElementsByClassName(final Runtime runtime, final $Value? target, final List<$Value?> args) {
|
static $Value? _getElementsByClassName(
|
||||||
final res = (target!.$value as MElement).getElementsByClassName(args[0]?.$value);
|
final Runtime runtime, final $Value? target, final List<$Value?> args) {
|
||||||
return res == null ? const $null() : $List.wrap(res.map((e) => $MElement.wrap(e)).toList());
|
final res =
|
||||||
|
(target!.$value as MElement).getElementsByClassName(args[0]?.$value);
|
||||||
|
return res == null
|
||||||
|
? const $null()
|
||||||
|
: $List.wrap(res.map((e) => $MElement.wrap(e)).toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
static const $Function __getElementsByTagName = $Function(_getElementsByTagName);
|
static const $Function __getElementsByTagName =
|
||||||
|
$Function(_getElementsByTagName);
|
||||||
|
|
||||||
static $Value? _getElementsByTagName(final Runtime runtime, final $Value? target, final List<$Value?> args) {
|
static $Value? _getElementsByTagName(
|
||||||
final res = (target!.$value as MElement).getElementsByTagName(args[0]?.$value);
|
final Runtime runtime, final $Value? target, final List<$Value?> args) {
|
||||||
return res == null ? const $null() : $List.wrap(res.map((e) => $MElement.wrap(e)).toList());
|
final res =
|
||||||
|
(target!.$value as MElement).getElementsByTagName(args[0]?.$value);
|
||||||
|
return res == null
|
||||||
|
? const $null()
|
||||||
|
: $List.wrap(res.map((e) => $MElement.wrap(e)).toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
static const $Function __xpath = $Function(_xpath);
|
static const $Function __xpath = $Function(_xpath);
|
||||||
|
|
||||||
static $Value? _xpath(final Runtime runtime, final $Value? target, final List<$Value?> args) {
|
static $Value? _xpath(
|
||||||
|
final Runtime runtime, final $Value? target, final List<$Value?> args) {
|
||||||
final res = (target!.$value as MElement).xpath(args[0]?.$value);
|
final res = (target!.$value as MElement).xpath(args[0]?.$value);
|
||||||
return res == null ? const $null() : $List.wrap(res.map((e) => $String(e)).toList());
|
return res == null
|
||||||
|
? const $null()
|
||||||
|
: $List.wrap(res.map((e) => $String(e)).toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
static const $Function __xpathFirst = $Function(_xpathFirst);
|
static const $Function __xpathFirst = $Function(_xpathFirst);
|
||||||
|
|
||||||
static $Value? _xpathFirst(final Runtime runtime, final $Value? target, final List<$Value?> args) {
|
static $Value? _xpathFirst(
|
||||||
|
final Runtime runtime, final $Value? target, final List<$Value?> args) {
|
||||||
final res = (target!.$value as MElement).xpathFirst(args[0]?.$value);
|
final res = (target!.$value as MElement).xpathFirst(args[0]?.$value);
|
||||||
return res == null ? const $null() : $String(res);
|
return res == null ? const $null() : $String(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const $Function __hasAttr = $Function(_hasAttr);
|
static const $Function __hasAttr = $Function(_hasAttr);
|
||||||
|
|
||||||
static $Value? _hasAttr(final Runtime runtime, final $Value? target, final List<$Value?> args) {
|
static $Value? _hasAttr(
|
||||||
|
final Runtime runtime, final $Value? target, final List<$Value?> args) {
|
||||||
final res = (target!.$value as MElement).attr(args[0]?.$value ?? "");
|
final res = (target!.$value as MElement).attr(args[0]?.$value ?? "");
|
||||||
return res == null ? const $null() : $String(res);
|
return res == null ? const $null() : $String(res);
|
||||||
}
|
}
|
||||||
|
|
@ -266,10 +368,12 @@ class $MElement implements MElement, $Instance {
|
||||||
List<MElement>? get children => $value.children;
|
List<MElement>? get children => $value.children;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<MElement>? getElementsByClassName(String classNames) => $value.getElementsByClassName(classNames);
|
List<MElement>? getElementsByClassName(String classNames) =>
|
||||||
|
$value.getElementsByClassName(classNames);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<MElement>? getElementsByTagName(String localNames) => $value.getElementsByTagName(localNames);
|
List<MElement>? getElementsByTagName(String localNames) =>
|
||||||
|
$value.getElementsByTagName(localNames);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool hasAttr(String attr) => $value.hasAttr(attr);
|
bool hasAttr(String attr) => $value.hasAttr(attr);
|
||||||
|
|
@ -317,11 +421,15 @@ class $MElement implements MElement, $Instance {
|
||||||
class $Element implements $Instance {
|
class $Element implements $Instance {
|
||||||
$Element.wrap(this.$value) : _superclass = $Object($value);
|
$Element.wrap(this.$value) : _superclass = $Object($value);
|
||||||
|
|
||||||
static const $type = BridgeTypeRef(BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'Element'));
|
static const $type = BridgeTypeRef(
|
||||||
|
BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'Element'));
|
||||||
|
|
||||||
static const $declaration = BridgeClassDef(
|
static const $declaration = BridgeClassDef(
|
||||||
BridgeClassType($type),
|
BridgeClassType($type),
|
||||||
constructors: {'': BridgeConstructorDef(BridgeFunctionDef(returns: BridgeTypeAnnotation($type, nullable: true)))},
|
constructors: {
|
||||||
|
'': BridgeConstructorDef(BridgeFunctionDef(
|
||||||
|
returns: BridgeTypeAnnotation($type, nullable: true)))
|
||||||
|
},
|
||||||
wrap: true,
|
wrap: true,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,18 +5,24 @@ import 'package:mangayomi/eval/model/filter.dart';
|
||||||
class $FilterList implements FilterList, $Instance {
|
class $FilterList implements FilterList, $Instance {
|
||||||
$FilterList.wrap(this.$value) : _superclass = $Object($value);
|
$FilterList.wrap(this.$value) : _superclass = $Object($value);
|
||||||
|
|
||||||
static const $type = BridgeTypeRef(BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'FilterList'));
|
static const $type = BridgeTypeRef(
|
||||||
|
BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'FilterList'));
|
||||||
|
|
||||||
static const $declaration = BridgeClassDef(BridgeClassType($type),
|
static const $declaration = BridgeClassDef(BridgeClassType($type),
|
||||||
constructors: {
|
constructors: {
|
||||||
'': BridgeConstructorDef(BridgeFunctionDef(returns: BridgeTypeAnnotation($type), params: [
|
'': BridgeConstructorDef(
|
||||||
BridgeParameter('filters',
|
BridgeFunctionDef(returns: BridgeTypeAnnotation($type), params: [
|
||||||
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.list, [BridgeTypeRef(CoreTypes.dynamic)])), false),
|
BridgeParameter(
|
||||||
|
'filters',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(
|
||||||
|
CoreTypes.list, [BridgeTypeRef(CoreTypes.dynamic)])),
|
||||||
|
false),
|
||||||
]))
|
]))
|
||||||
},
|
},
|
||||||
fields: {
|
fields: {
|
||||||
'filters': BridgeFieldDef(
|
'filters': BridgeFieldDef(
|
||||||
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.list, [BridgeTypeRef(CoreTypes.dynamic)])),
|
BridgeTypeAnnotation(BridgeTypeRef(
|
||||||
|
CoreTypes.list, [BridgeTypeRef(CoreTypes.dynamic)])),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
wrap: true);
|
wrap: true);
|
||||||
|
|
@ -51,7 +57,9 @@ class $FilterList implements FilterList, $Instance {
|
||||||
void $setProperty(Runtime runtime, String identifier, $Value value) {
|
void $setProperty(Runtime runtime, String identifier, $Value value) {
|
||||||
switch (identifier) {
|
switch (identifier) {
|
||||||
case 'filters':
|
case 'filters':
|
||||||
$value.filters = (value.$reified as List).map((e) => e is $Value ? e.$reified : e).toList();
|
$value.filters = (value.$reified as List)
|
||||||
|
.map((e) => e is $Value ? e.$reified : e)
|
||||||
|
.toList();
|
||||||
default:
|
default:
|
||||||
_superclass.$setProperty(runtime, identifier, value);
|
_superclass.$setProperty(runtime, identifier, value);
|
||||||
}
|
}
|
||||||
|
|
@ -72,26 +80,37 @@ class $FilterList implements FilterList, $Instance {
|
||||||
class $SelectFilter implements SelectFilter, $Instance {
|
class $SelectFilter implements SelectFilter, $Instance {
|
||||||
$SelectFilter.wrap(this.$value) : _superclass = $Object($value);
|
$SelectFilter.wrap(this.$value) : _superclass = $Object($value);
|
||||||
|
|
||||||
static const $type = BridgeTypeRef(BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'SelectFilter'));
|
static const $type = BridgeTypeRef(
|
||||||
|
BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'SelectFilter'));
|
||||||
|
|
||||||
static const $declaration = BridgeClassDef(BridgeClassType($type),
|
static const $declaration = BridgeClassDef(BridgeClassType($type),
|
||||||
constructors: {
|
constructors: {
|
||||||
'': BridgeConstructorDef(BridgeFunctionDef(returns: BridgeTypeAnnotation($type), params: [
|
'': BridgeConstructorDef(
|
||||||
BridgeParameter('type', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
BridgeFunctionDef(returns: BridgeTypeAnnotation($type), params: [
|
||||||
BridgeParameter('name', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
BridgeParameter('type',
|
||||||
BridgeParameter('state', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.int)), false),
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
||||||
|
BridgeParameter('name',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
||||||
|
BridgeParameter('state',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.int)), false),
|
||||||
BridgeParameter(
|
BridgeParameter(
|
||||||
'values', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.list, [BridgeTypeRef(CoreTypes.dynamic)])), false),
|
'values',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(
|
||||||
|
CoreTypes.list, [BridgeTypeRef(CoreTypes.dynamic)])),
|
||||||
|
false),
|
||||||
]))
|
]))
|
||||||
},
|
},
|
||||||
fields: {
|
fields: {
|
||||||
'type': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
'type': BridgeFieldDef(
|
||||||
'name': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
||||||
|
'name': BridgeFieldDef(
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
||||||
'state': BridgeFieldDef(BridgeTypeAnnotation(
|
'state': BridgeFieldDef(BridgeTypeAnnotation(
|
||||||
BridgeTypeRef(CoreTypes.int),
|
BridgeTypeRef(CoreTypes.int),
|
||||||
)),
|
)),
|
||||||
'values': BridgeFieldDef(
|
'values': BridgeFieldDef(
|
||||||
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.list, [BridgeTypeRef(CoreTypes.dynamic)])),
|
BridgeTypeAnnotation(BridgeTypeRef(
|
||||||
|
CoreTypes.list, [BridgeTypeRef(CoreTypes.dynamic)])),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
wrap: true);
|
wrap: true);
|
||||||
|
|
@ -109,7 +128,8 @@ class $SelectFilter implements SelectFilter, $Instance {
|
||||||
map = value.map((key, value) => MapEntry(key.toString(), value));
|
map = value.map((key, value) => MapEntry(key.toString(), value));
|
||||||
if (map['type'] == 'SelectOption') {
|
if (map['type'] == 'SelectOption') {
|
||||||
final filter = map['filter'] as Map;
|
final filter = map['filter'] as Map;
|
||||||
return SelectFilterOption.fromJson(filter.map((key, value) => MapEntry(key.toString(), value)));
|
return SelectFilterOption.fromJson(filter
|
||||||
|
.map((key, value) => MapEntry(key.toString(), value)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
|
|
@ -202,23 +222,30 @@ class $SelectFilter implements SelectFilter, $Instance {
|
||||||
class $SelectFilterOption implements SelectFilterOption, $Instance {
|
class $SelectFilterOption implements SelectFilterOption, $Instance {
|
||||||
$SelectFilterOption.wrap(this.$value) : _superclass = $Object($value);
|
$SelectFilterOption.wrap(this.$value) : _superclass = $Object($value);
|
||||||
|
|
||||||
static const $type = BridgeTypeRef(BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'SelectFilterOption'));
|
static const $type = BridgeTypeRef(BridgeTypeSpec(
|
||||||
|
'package:mangayomi/bridge_lib.dart', 'SelectFilterOption'));
|
||||||
|
|
||||||
static const $declaration = BridgeClassDef(BridgeClassType($type),
|
static const $declaration = BridgeClassDef(BridgeClassType($type),
|
||||||
constructors: {
|
constructors: {
|
||||||
'': BridgeConstructorDef(BridgeFunctionDef(returns: BridgeTypeAnnotation($type), params: [
|
'': BridgeConstructorDef(
|
||||||
BridgeParameter('name', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
BridgeFunctionDef(returns: BridgeTypeAnnotation($type), params: [
|
||||||
BridgeParameter('value', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
BridgeParameter('name',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
||||||
|
BridgeParameter('value',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
||||||
]))
|
]))
|
||||||
},
|
},
|
||||||
fields: {
|
fields: {
|
||||||
'name': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
'name': BridgeFieldDef(
|
||||||
'value': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
||||||
|
'value': BridgeFieldDef(
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
||||||
},
|
},
|
||||||
wrap: true);
|
wrap: true);
|
||||||
|
|
||||||
static $Value? $new(Runtime runtime, $Value? target, List<$Value?> args) {
|
static $Value? $new(Runtime runtime, $Value? target, List<$Value?> args) {
|
||||||
return $SelectFilterOption.wrap(SelectFilterOption(args[0]!.$value, args[1]!.$value, null));
|
return $SelectFilterOption
|
||||||
|
.wrap(SelectFilterOption(args[0]!.$value, args[1]!.$value, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
@ -285,21 +312,26 @@ class $SelectFilterOption implements SelectFilterOption, $Instance {
|
||||||
class $SeparatorFilter implements SeparatorFilter, $Instance {
|
class $SeparatorFilter implements SeparatorFilter, $Instance {
|
||||||
$SeparatorFilter.wrap(this.$value) : _superclass = $Object($value);
|
$SeparatorFilter.wrap(this.$value) : _superclass = $Object($value);
|
||||||
|
|
||||||
static const $type = BridgeTypeRef(BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'SeparatorFilter'));
|
static const $type = BridgeTypeRef(
|
||||||
|
BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'SeparatorFilter'));
|
||||||
|
|
||||||
static const $declaration = BridgeClassDef(BridgeClassType($type),
|
static const $declaration = BridgeClassDef(BridgeClassType($type),
|
||||||
constructors: {
|
constructors: {
|
||||||
'': BridgeConstructorDef(BridgeFunctionDef(returns: BridgeTypeAnnotation($type), params: [
|
'': BridgeConstructorDef(
|
||||||
BridgeParameter('type', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), true),
|
BridgeFunctionDef(returns: BridgeTypeAnnotation($type), params: [
|
||||||
|
BridgeParameter('type',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), true),
|
||||||
]))
|
]))
|
||||||
},
|
},
|
||||||
fields: {
|
fields: {
|
||||||
'type': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
'type': BridgeFieldDef(
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
||||||
},
|
},
|
||||||
wrap: true);
|
wrap: true);
|
||||||
|
|
||||||
static $Value? $new(Runtime runtime, $Value? target, List<$Value?> args) {
|
static $Value? $new(Runtime runtime, $Value? target, List<$Value?> args) {
|
||||||
return $SeparatorFilter.wrap(SeparatorFilter(null, type: args[0]?.$value ?? ''));
|
return $SeparatorFilter
|
||||||
|
.wrap(SeparatorFilter(null, type: args[0]?.$value ?? ''));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
@ -355,23 +387,30 @@ class $SeparatorFilter implements SeparatorFilter, $Instance {
|
||||||
class $HeaderFilter implements HeaderFilter, $Instance {
|
class $HeaderFilter implements HeaderFilter, $Instance {
|
||||||
$HeaderFilter.wrap(this.$value) : _superclass = $Object($value);
|
$HeaderFilter.wrap(this.$value) : _superclass = $Object($value);
|
||||||
|
|
||||||
static const $type = BridgeTypeRef(BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'HeaderFilter'));
|
static const $type = BridgeTypeRef(
|
||||||
|
BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'HeaderFilter'));
|
||||||
|
|
||||||
static const $declaration = BridgeClassDef(BridgeClassType($type),
|
static const $declaration = BridgeClassDef(BridgeClassType($type),
|
||||||
constructors: {
|
constructors: {
|
||||||
'': BridgeConstructorDef(BridgeFunctionDef(returns: BridgeTypeAnnotation($type), params: [
|
'': BridgeConstructorDef(
|
||||||
BridgeParameter('name', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
BridgeFunctionDef(returns: BridgeTypeAnnotation($type), params: [
|
||||||
BridgeParameter('type', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), true),
|
BridgeParameter('name',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
||||||
|
BridgeParameter('type',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), true),
|
||||||
]))
|
]))
|
||||||
},
|
},
|
||||||
fields: {
|
fields: {
|
||||||
'name': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
'name': BridgeFieldDef(
|
||||||
'type': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
||||||
|
'type': BridgeFieldDef(
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
||||||
},
|
},
|
||||||
wrap: true);
|
wrap: true);
|
||||||
|
|
||||||
static $Value? $new(Runtime runtime, $Value? target, List<$Value?> args) {
|
static $Value? $new(Runtime runtime, $Value? target, List<$Value?> args) {
|
||||||
return $HeaderFilter.wrap(HeaderFilter(args[0]!.$value, null, type: args[1]?.$value ?? ''));
|
return $HeaderFilter
|
||||||
|
.wrap(HeaderFilter(args[0]!.$value, null, type: args[1]?.$value ?? ''));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
@ -438,18 +477,24 @@ class $HeaderFilter implements HeaderFilter, $Instance {
|
||||||
class $TextFilter implements TextFilter, $Instance {
|
class $TextFilter implements TextFilter, $Instance {
|
||||||
$TextFilter.wrap(this.$value) : _superclass = $Object($value);
|
$TextFilter.wrap(this.$value) : _superclass = $Object($value);
|
||||||
|
|
||||||
static const $type = BridgeTypeRef(BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'TextFilter'));
|
static const $type = BridgeTypeRef(
|
||||||
|
BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'TextFilter'));
|
||||||
|
|
||||||
static const $declaration = BridgeClassDef(BridgeClassType($type),
|
static const $declaration = BridgeClassDef(BridgeClassType($type),
|
||||||
constructors: {
|
constructors: {
|
||||||
'': BridgeConstructorDef(BridgeFunctionDef(returns: BridgeTypeAnnotation($type), params: [
|
'': BridgeConstructorDef(
|
||||||
BridgeParameter('type', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
BridgeFunctionDef(returns: BridgeTypeAnnotation($type), params: [
|
||||||
BridgeParameter('name', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
BridgeParameter('type',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
||||||
|
BridgeParameter('name',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
||||||
]))
|
]))
|
||||||
},
|
},
|
||||||
fields: {
|
fields: {
|
||||||
'type': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
'type': BridgeFieldDef(
|
||||||
'name': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
||||||
|
'name': BridgeFieldDef(
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
||||||
},
|
},
|
||||||
wrap: true);
|
wrap: true);
|
||||||
|
|
||||||
|
|
@ -530,24 +575,35 @@ class $TextFilter implements TextFilter, $Instance {
|
||||||
class $SortFilter implements SortFilter, $Instance {
|
class $SortFilter implements SortFilter, $Instance {
|
||||||
$SortFilter.wrap(this.$value) : _superclass = $Object($value);
|
$SortFilter.wrap(this.$value) : _superclass = $Object($value);
|
||||||
|
|
||||||
static const $type = BridgeTypeRef(BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'SortFilter'));
|
static const $type = BridgeTypeRef(
|
||||||
|
BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'SortFilter'));
|
||||||
|
|
||||||
static const $declaration = BridgeClassDef(BridgeClassType($type),
|
static const $declaration = BridgeClassDef(BridgeClassType($type),
|
||||||
constructors: {
|
constructors: {
|
||||||
'': BridgeConstructorDef(BridgeFunctionDef(returns: BridgeTypeAnnotation($type), params: [
|
'': BridgeConstructorDef(
|
||||||
BridgeParameter('type', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
BridgeFunctionDef(returns: BridgeTypeAnnotation($type), params: [
|
||||||
BridgeParameter('name', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
BridgeParameter('type',
|
||||||
BridgeParameter('state', BridgeTypeAnnotation($SortState.$type), false),
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
||||||
|
BridgeParameter('name',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
||||||
BridgeParameter(
|
BridgeParameter(
|
||||||
'values', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.list, [BridgeTypeRef(CoreTypes.dynamic)])), false),
|
'state', BridgeTypeAnnotation($SortState.$type), false),
|
||||||
|
BridgeParameter(
|
||||||
|
'values',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(
|
||||||
|
CoreTypes.list, [BridgeTypeRef(CoreTypes.dynamic)])),
|
||||||
|
false),
|
||||||
]))
|
]))
|
||||||
},
|
},
|
||||||
fields: {
|
fields: {
|
||||||
'type': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
'type': BridgeFieldDef(
|
||||||
'name': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
||||||
|
'name': BridgeFieldDef(
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
||||||
'state': BridgeFieldDef(BridgeTypeAnnotation($SortState.$type)),
|
'state': BridgeFieldDef(BridgeTypeAnnotation($SortState.$type)),
|
||||||
'values': BridgeFieldDef(
|
'values': BridgeFieldDef(
|
||||||
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.list, [BridgeTypeRef(CoreTypes.dynamic)])),
|
BridgeTypeAnnotation(BridgeTypeRef(
|
||||||
|
CoreTypes.list, [BridgeTypeRef(CoreTypes.dynamic)])),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
wrap: true);
|
wrap: true);
|
||||||
|
|
@ -557,7 +613,10 @@ class $SortFilter implements SortFilter, $Instance {
|
||||||
args[0]!.$value,
|
args[0]!.$value,
|
||||||
args[1]!.$value,
|
args[1]!.$value,
|
||||||
args[2]!.$value,
|
args[2]!.$value,
|
||||||
(args[3]!.$value as List).map((e) => SelectFilterOption(e.$reified.name, e.$reified.value, null)).toList(),
|
(args[3]!.$value as List)
|
||||||
|
.map((e) =>
|
||||||
|
SelectFilterOption(e.$reified.name, e.$reified.value, null))
|
||||||
|
.toList(),
|
||||||
null));
|
null));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -644,13 +703,17 @@ class $SortFilter implements SortFilter, $Instance {
|
||||||
class $SortState implements SortState, $Instance {
|
class $SortState implements SortState, $Instance {
|
||||||
$SortState.wrap(this.$value) : _superclass = $Object($value);
|
$SortState.wrap(this.$value) : _superclass = $Object($value);
|
||||||
|
|
||||||
static const $type = BridgeTypeRef(BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'SortState'));
|
static const $type = BridgeTypeRef(
|
||||||
|
BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'SortState'));
|
||||||
|
|
||||||
static const $declaration = BridgeClassDef(BridgeClassType($type),
|
static const $declaration = BridgeClassDef(BridgeClassType($type),
|
||||||
constructors: {
|
constructors: {
|
||||||
'': BridgeConstructorDef(BridgeFunctionDef(returns: BridgeTypeAnnotation($type), params: [
|
'': BridgeConstructorDef(
|
||||||
BridgeParameter('index', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.int)), false),
|
BridgeFunctionDef(returns: BridgeTypeAnnotation($type), params: [
|
||||||
BridgeParameter('ascending', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.bool)), false),
|
BridgeParameter('index',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.int)), false),
|
||||||
|
BridgeParameter('ascending',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.bool)), false),
|
||||||
]))
|
]))
|
||||||
},
|
},
|
||||||
fields: {
|
fields: {
|
||||||
|
|
@ -731,22 +794,31 @@ class $SortState implements SortState, $Instance {
|
||||||
class $TriStateFilter implements TriStateFilter, $Instance {
|
class $TriStateFilter implements TriStateFilter, $Instance {
|
||||||
$TriStateFilter.wrap(this.$value) : _superclass = $Object($value);
|
$TriStateFilter.wrap(this.$value) : _superclass = $Object($value);
|
||||||
|
|
||||||
static const $type = BridgeTypeRef(BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'TriStateFilter'));
|
static const $type = BridgeTypeRef(
|
||||||
|
BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'TriStateFilter'));
|
||||||
|
|
||||||
static const $declaration = BridgeClassDef(BridgeClassType($type),
|
static const $declaration = BridgeClassDef(BridgeClassType($type),
|
||||||
constructors: {
|
constructors: {
|
||||||
'': BridgeConstructorDef(BridgeFunctionDef(returns: BridgeTypeAnnotation($type), params: [
|
'': BridgeConstructorDef(
|
||||||
BridgeParameter('name', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
BridgeFunctionDef(returns: BridgeTypeAnnotation($type), params: [
|
||||||
BridgeParameter('value', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
BridgeParameter('name',
|
||||||
BridgeParameter('type', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), true),
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
||||||
|
BridgeParameter('value',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
||||||
|
BridgeParameter('type',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), true),
|
||||||
], namedParams: [
|
], namedParams: [
|
||||||
BridgeParameter('state', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.int)), true)
|
BridgeParameter(
|
||||||
|
'state', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.int)), true)
|
||||||
]))
|
]))
|
||||||
},
|
},
|
||||||
fields: {
|
fields: {
|
||||||
'name': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
'name': BridgeFieldDef(
|
||||||
'value': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
||||||
'type': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
'value': BridgeFieldDef(
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
||||||
|
'type': BridgeFieldDef(
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
||||||
'state': BridgeFieldDef(BridgeTypeAnnotation(
|
'state': BridgeFieldDef(BridgeTypeAnnotation(
|
||||||
BridgeTypeRef(CoreTypes.int),
|
BridgeTypeRef(CoreTypes.int),
|
||||||
)),
|
)),
|
||||||
|
|
@ -754,8 +826,9 @@ class $TriStateFilter implements TriStateFilter, $Instance {
|
||||||
wrap: true);
|
wrap: true);
|
||||||
|
|
||||||
static $Value? $new(Runtime runtime, $Value? target, List<$Value?> args) {
|
static $Value? $new(Runtime runtime, $Value? target, List<$Value?> args) {
|
||||||
return $TriStateFilter.wrap(
|
return $TriStateFilter.wrap(TriStateFilter(
|
||||||
TriStateFilter(args[2]?.$value ?? '', args[0]!.$value, args[1]!.$value, null, state: args[3]?.$value ?? 0));
|
args[2]?.$value ?? '', args[0]!.$value, args[1]!.$value, null,
|
||||||
|
state: args[3]?.$value ?? 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
@ -842,22 +915,32 @@ class $TriStateFilter implements TriStateFilter, $Instance {
|
||||||
class $GroupFilter implements GroupFilter, $Instance {
|
class $GroupFilter implements GroupFilter, $Instance {
|
||||||
$GroupFilter.wrap(this.$value) : _superclass = $Object($value);
|
$GroupFilter.wrap(this.$value) : _superclass = $Object($value);
|
||||||
|
|
||||||
static const $type = BridgeTypeRef(BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'GroupFilter'));
|
static const $type = BridgeTypeRef(
|
||||||
|
BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'GroupFilter'));
|
||||||
|
|
||||||
static const $declaration = BridgeClassDef(BridgeClassType($type),
|
static const $declaration = BridgeClassDef(BridgeClassType($type),
|
||||||
constructors: {
|
constructors: {
|
||||||
'': BridgeConstructorDef(BridgeFunctionDef(returns: BridgeTypeAnnotation($type), params: [
|
'': BridgeConstructorDef(
|
||||||
BridgeParameter('type', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
BridgeFunctionDef(returns: BridgeTypeAnnotation($type), params: [
|
||||||
BridgeParameter('name', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
BridgeParameter('type',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
||||||
|
BridgeParameter('name',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
||||||
BridgeParameter(
|
BridgeParameter(
|
||||||
'state', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.list, [BridgeTypeRef(CoreTypes.dynamic)])), false),
|
'state',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(
|
||||||
|
CoreTypes.list, [BridgeTypeRef(CoreTypes.dynamic)])),
|
||||||
|
false),
|
||||||
]))
|
]))
|
||||||
},
|
},
|
||||||
fields: {
|
fields: {
|
||||||
'type': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
'type': BridgeFieldDef(
|
||||||
'name': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
||||||
|
'name': BridgeFieldDef(
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
||||||
'state': BridgeFieldDef(
|
'state': BridgeFieldDef(
|
||||||
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.list, [BridgeTypeRef(CoreTypes.dynamic)])),
|
BridgeTypeAnnotation(BridgeTypeRef(
|
||||||
|
CoreTypes.list, [BridgeTypeRef(CoreTypes.dynamic)])),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
wrap: true);
|
wrap: true);
|
||||||
|
|
@ -874,10 +957,12 @@ class $GroupFilter implements GroupFilter, $Instance {
|
||||||
map = value.map((key, value) => MapEntry(key.toString(), value));
|
map = value.map((key, value) => MapEntry(key.toString(), value));
|
||||||
if (map['type'] == 'TriState') {
|
if (map['type'] == 'TriState') {
|
||||||
final filter = map['filter'] as Map;
|
final filter = map['filter'] as Map;
|
||||||
return TriStateFilter.fromJson(filter.map((key, value) => MapEntry(key.toString(), value)));
|
return TriStateFilter.fromJson(filter
|
||||||
|
.map((key, value) => MapEntry(key.toString(), value)));
|
||||||
} else if (map['type'] == 'CheckBox') {
|
} else if (map['type'] == 'CheckBox') {
|
||||||
final filter = map['filter'] as Map;
|
final filter = map['filter'] as Map;
|
||||||
return CheckBoxFilter.fromJson(filter.map((key, value) => MapEntry(key.toString(), value)));
|
return CheckBoxFilter.fromJson(filter
|
||||||
|
.map((key, value) => MapEntry(key.toString(), value)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
|
|
@ -961,22 +1046,31 @@ class $GroupFilter implements GroupFilter, $Instance {
|
||||||
class $CheckBoxFilter implements CheckBoxFilter, $Instance {
|
class $CheckBoxFilter implements CheckBoxFilter, $Instance {
|
||||||
$CheckBoxFilter.wrap(this.$value) : _superclass = $Object($value);
|
$CheckBoxFilter.wrap(this.$value) : _superclass = $Object($value);
|
||||||
|
|
||||||
static const $type = BridgeTypeRef(BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'CheckBoxFilter'));
|
static const $type = BridgeTypeRef(
|
||||||
|
BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'CheckBoxFilter'));
|
||||||
|
|
||||||
static const $declaration = BridgeClassDef(BridgeClassType($type),
|
static const $declaration = BridgeClassDef(BridgeClassType($type),
|
||||||
constructors: {
|
constructors: {
|
||||||
'': BridgeConstructorDef(BridgeFunctionDef(returns: BridgeTypeAnnotation($type), params: [
|
'': BridgeConstructorDef(
|
||||||
BridgeParameter('name', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
BridgeFunctionDef(returns: BridgeTypeAnnotation($type), params: [
|
||||||
BridgeParameter('value', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
BridgeParameter('name',
|
||||||
BridgeParameter('type', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), true),
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
||||||
|
BridgeParameter('value',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
||||||
|
BridgeParameter('type',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), true),
|
||||||
], namedParams: [
|
], namedParams: [
|
||||||
BridgeParameter('state', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.bool)), true),
|
BridgeParameter('state',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.bool)), true),
|
||||||
]))
|
]))
|
||||||
},
|
},
|
||||||
fields: {
|
fields: {
|
||||||
'name': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
'name': BridgeFieldDef(
|
||||||
'value': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
||||||
'type': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
'value': BridgeFieldDef(
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
||||||
|
'type': BridgeFieldDef(
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
||||||
'state': BridgeFieldDef(BridgeTypeAnnotation(
|
'state': BridgeFieldDef(BridgeTypeAnnotation(
|
||||||
BridgeTypeRef(CoreTypes.bool),
|
BridgeTypeRef(CoreTypes.bool),
|
||||||
)),
|
)),
|
||||||
|
|
@ -984,8 +1078,9 @@ class $CheckBoxFilter implements CheckBoxFilter, $Instance {
|
||||||
wrap: true);
|
wrap: true);
|
||||||
|
|
||||||
static $Value? $new(Runtime runtime, $Value? target, List<$Value?> args) {
|
static $Value? $new(Runtime runtime, $Value? target, List<$Value?> args) {
|
||||||
return $CheckBoxFilter.wrap(
|
return $CheckBoxFilter.wrap(CheckBoxFilter(
|
||||||
CheckBoxFilter(args[2]?.$value ?? '', args[0]!.$value, args[1]!.$value, null, state: args[3]?.$value ?? false));
|
args[2]?.$value ?? '', args[0]!.$value, args[1]!.$value, null,
|
||||||
|
state: args[3]?.$value ?? false));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
|
||||||
|
|
@ -17,104 +17,165 @@ class $Client implements $Instance {
|
||||||
late final $Instance _superclass = $Object($value);
|
late final $Instance _superclass = $Object($value);
|
||||||
|
|
||||||
/// Compile-time bridged type reference for [$InterceptedClient]
|
/// Compile-time bridged type reference for [$InterceptedClient]
|
||||||
static const $type = BridgeTypeRef(BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'Client'));
|
static const $type = BridgeTypeRef(
|
||||||
|
BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'Client'));
|
||||||
|
|
||||||
/// Compile-time bridged class declaration for [$InterceptedClient]
|
/// Compile-time bridged class declaration for [$InterceptedClient]
|
||||||
static const $declaration = BridgeClassDef(BridgeClassType($type),
|
static const $declaration = BridgeClassDef(BridgeClassType($type),
|
||||||
constructors: {
|
constructors: {
|
||||||
'': BridgeConstructorDef(BridgeFunctionDef(returns: BridgeTypeAnnotation($type), params: [
|
'': BridgeConstructorDef(
|
||||||
|
BridgeFunctionDef(returns: BridgeTypeAnnotation($type), params: [
|
||||||
BridgeParameter('source', BridgeTypeAnnotation($MSource.$type), true),
|
BridgeParameter('source', BridgeTypeAnnotation($MSource.$type), true),
|
||||||
BridgeParameter('reqcopyWith', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), true),
|
BridgeParameter('reqcopyWith',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), true),
|
||||||
], namedParams: []))
|
], namedParams: []))
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
'get': BridgeMethodDef(BridgeFunctionDef(
|
'get': BridgeMethodDef(BridgeFunctionDef(
|
||||||
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.future, [$Response.$type])),
|
returns: BridgeTypeAnnotation(
|
||||||
|
BridgeTypeRef(CoreTypes.future, [$Response.$type])),
|
||||||
params: [
|
params: [
|
||||||
BridgeParameter('url', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.uri)), false),
|
BridgeParameter('url',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.uri)), false),
|
||||||
],
|
],
|
||||||
namedParams: [
|
namedParams: [
|
||||||
BridgeParameter(
|
BridgeParameter(
|
||||||
'headers',
|
'headers',
|
||||||
BridgeTypeAnnotation(
|
BridgeTypeAnnotation(
|
||||||
BridgeTypeRef(CoreTypes.map, [BridgeTypeRef(CoreTypes.string), BridgeTypeRef(CoreTypes.string)]),
|
BridgeTypeRef(CoreTypes.map, [
|
||||||
|
BridgeTypeRef(CoreTypes.string),
|
||||||
|
BridgeTypeRef(CoreTypes.string)
|
||||||
|
]),
|
||||||
nullable: true),
|
nullable: true),
|
||||||
true),
|
true),
|
||||||
])),
|
])),
|
||||||
'post': BridgeMethodDef(BridgeFunctionDef(
|
'post': BridgeMethodDef(BridgeFunctionDef(
|
||||||
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.future, [$Response.$type])),
|
returns: BridgeTypeAnnotation(
|
||||||
|
BridgeTypeRef(CoreTypes.future, [$Response.$type])),
|
||||||
params: [
|
params: [
|
||||||
BridgeParameter('url', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.uri)), false),
|
BridgeParameter('url',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.uri)), false),
|
||||||
],
|
],
|
||||||
namedParams: [
|
namedParams: [
|
||||||
BridgeParameter(
|
BridgeParameter(
|
||||||
'headers',
|
'headers',
|
||||||
BridgeTypeAnnotation(
|
BridgeTypeAnnotation(
|
||||||
BridgeTypeRef(CoreTypes.map, [BridgeTypeRef(CoreTypes.string), BridgeTypeRef(CoreTypes.string)]),
|
BridgeTypeRef(CoreTypes.map, [
|
||||||
|
BridgeTypeRef(CoreTypes.string),
|
||||||
|
BridgeTypeRef(CoreTypes.string)
|
||||||
|
]),
|
||||||
nullable: true),
|
nullable: true),
|
||||||
true),
|
true),
|
||||||
BridgeParameter('body', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.object), nullable: true), true),
|
|
||||||
BridgeParameter(
|
BridgeParameter(
|
||||||
'encoding', BridgeTypeAnnotation(BridgeTypeRef(ConvertTypes.encoding), nullable: true), true),
|
'body',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.object),
|
||||||
|
nullable: true),
|
||||||
|
true),
|
||||||
|
BridgeParameter(
|
||||||
|
'encoding',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(ConvertTypes.encoding),
|
||||||
|
nullable: true),
|
||||||
|
true),
|
||||||
])),
|
])),
|
||||||
'put': BridgeMethodDef(BridgeFunctionDef(
|
'put': BridgeMethodDef(BridgeFunctionDef(
|
||||||
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.future, [$Response.$type])),
|
returns: BridgeTypeAnnotation(
|
||||||
|
BridgeTypeRef(CoreTypes.future, [$Response.$type])),
|
||||||
params: [
|
params: [
|
||||||
BridgeParameter('url', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.uri)), false),
|
BridgeParameter('url',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.uri)), false),
|
||||||
],
|
],
|
||||||
namedParams: [
|
namedParams: [
|
||||||
BridgeParameter(
|
BridgeParameter(
|
||||||
'headers',
|
'headers',
|
||||||
BridgeTypeAnnotation(
|
BridgeTypeAnnotation(
|
||||||
BridgeTypeRef(CoreTypes.map, [BridgeTypeRef(CoreTypes.string), BridgeTypeRef(CoreTypes.string)]),
|
BridgeTypeRef(CoreTypes.map, [
|
||||||
|
BridgeTypeRef(CoreTypes.string),
|
||||||
|
BridgeTypeRef(CoreTypes.string)
|
||||||
|
]),
|
||||||
nullable: true),
|
nullable: true),
|
||||||
true),
|
true),
|
||||||
BridgeParameter('body', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.object), nullable: true), true),
|
|
||||||
BridgeParameter(
|
BridgeParameter(
|
||||||
'encoding', BridgeTypeAnnotation(BridgeTypeRef(ConvertTypes.encoding), nullable: true), true),
|
'body',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.object),
|
||||||
|
nullable: true),
|
||||||
|
true),
|
||||||
|
BridgeParameter(
|
||||||
|
'encoding',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(ConvertTypes.encoding),
|
||||||
|
nullable: true),
|
||||||
|
true),
|
||||||
])),
|
])),
|
||||||
'delete': BridgeMethodDef(BridgeFunctionDef(
|
'delete': BridgeMethodDef(BridgeFunctionDef(
|
||||||
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.future, [$Response.$type])),
|
returns: BridgeTypeAnnotation(
|
||||||
|
BridgeTypeRef(CoreTypes.future, [$Response.$type])),
|
||||||
params: [
|
params: [
|
||||||
BridgeParameter('url', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.uri)), false),
|
BridgeParameter('url',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.uri)), false),
|
||||||
],
|
],
|
||||||
namedParams: [
|
namedParams: [
|
||||||
BridgeParameter(
|
BridgeParameter(
|
||||||
'headers',
|
'headers',
|
||||||
BridgeTypeAnnotation(
|
BridgeTypeAnnotation(
|
||||||
BridgeTypeRef(CoreTypes.map, [BridgeTypeRef(CoreTypes.string), BridgeTypeRef(CoreTypes.string)]),
|
BridgeTypeRef(CoreTypes.map, [
|
||||||
|
BridgeTypeRef(CoreTypes.string),
|
||||||
|
BridgeTypeRef(CoreTypes.string)
|
||||||
|
]),
|
||||||
nullable: true),
|
nullable: true),
|
||||||
true),
|
true),
|
||||||
BridgeParameter('body', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.object), nullable: true), true),
|
|
||||||
BridgeParameter(
|
BridgeParameter(
|
||||||
'encoding', BridgeTypeAnnotation(BridgeTypeRef(ConvertTypes.encoding), nullable: true), true),
|
'body',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.object),
|
||||||
|
nullable: true),
|
||||||
|
true),
|
||||||
|
BridgeParameter(
|
||||||
|
'encoding',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(ConvertTypes.encoding),
|
||||||
|
nullable: true),
|
||||||
|
true),
|
||||||
])),
|
])),
|
||||||
'patch': BridgeMethodDef(BridgeFunctionDef(
|
'patch': BridgeMethodDef(BridgeFunctionDef(
|
||||||
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.future, [$Response.$type])),
|
returns: BridgeTypeAnnotation(
|
||||||
|
BridgeTypeRef(CoreTypes.future, [$Response.$type])),
|
||||||
params: [
|
params: [
|
||||||
BridgeParameter('url', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.uri)), false),
|
BridgeParameter('url',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.uri)), false),
|
||||||
],
|
],
|
||||||
namedParams: [
|
namedParams: [
|
||||||
BridgeParameter(
|
BridgeParameter(
|
||||||
'headers',
|
'headers',
|
||||||
BridgeTypeAnnotation(
|
BridgeTypeAnnotation(
|
||||||
BridgeTypeRef(CoreTypes.map, [BridgeTypeRef(CoreTypes.string), BridgeTypeRef(CoreTypes.string)]),
|
BridgeTypeRef(CoreTypes.map, [
|
||||||
|
BridgeTypeRef(CoreTypes.string),
|
||||||
|
BridgeTypeRef(CoreTypes.string)
|
||||||
|
]),
|
||||||
nullable: true),
|
nullable: true),
|
||||||
true),
|
true),
|
||||||
BridgeParameter('body', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.object), nullable: true), true),
|
|
||||||
BridgeParameter(
|
BridgeParameter(
|
||||||
'encoding', BridgeTypeAnnotation(BridgeTypeRef(ConvertTypes.encoding), nullable: true), true),
|
'body',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.object),
|
||||||
|
nullable: true),
|
||||||
|
true),
|
||||||
|
BridgeParameter(
|
||||||
|
'encoding',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(ConvertTypes.encoding),
|
||||||
|
nullable: true),
|
||||||
|
true),
|
||||||
])),
|
])),
|
||||||
'read': BridgeMethodDef(BridgeFunctionDef(
|
'read': BridgeMethodDef(BridgeFunctionDef(
|
||||||
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.future, [BridgeTypeRef(CoreTypes.string)])),
|
returns: BridgeTypeAnnotation(BridgeTypeRef(
|
||||||
|
CoreTypes.future, [BridgeTypeRef(CoreTypes.string)])),
|
||||||
params: [
|
params: [
|
||||||
BridgeParameter('url', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.uri)), false),
|
BridgeParameter('url',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.uri)), false),
|
||||||
],
|
],
|
||||||
namedParams: [
|
namedParams: [
|
||||||
BridgeParameter(
|
BridgeParameter(
|
||||||
'headers',
|
'headers',
|
||||||
BridgeTypeAnnotation(
|
BridgeTypeAnnotation(
|
||||||
BridgeTypeRef(CoreTypes.map, [BridgeTypeRef(CoreTypes.string), BridgeTypeRef(CoreTypes.string)]),
|
BridgeTypeRef(CoreTypes.map, [
|
||||||
|
BridgeTypeRef(CoreTypes.string),
|
||||||
|
BridgeTypeRef(CoreTypes.string)
|
||||||
|
]),
|
||||||
nullable: true),
|
nullable: true),
|
||||||
true),
|
true),
|
||||||
])),
|
])),
|
||||||
|
|
@ -123,20 +184,26 @@ class $Client implements $Instance {
|
||||||
BridgeTypeRef(CoreTypes.list, [BridgeTypeRef(CoreTypes.int)])
|
BridgeTypeRef(CoreTypes.list, [BridgeTypeRef(CoreTypes.int)])
|
||||||
])),
|
])),
|
||||||
params: [
|
params: [
|
||||||
BridgeParameter('url', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.uri)), false),
|
BridgeParameter('url',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.uri)), false),
|
||||||
],
|
],
|
||||||
namedParams: [
|
namedParams: [
|
||||||
BridgeParameter(
|
BridgeParameter(
|
||||||
'headers',
|
'headers',
|
||||||
BridgeTypeAnnotation(
|
BridgeTypeAnnotation(
|
||||||
BridgeTypeRef(CoreTypes.map, [BridgeTypeRef(CoreTypes.string), BridgeTypeRef(CoreTypes.string)]),
|
BridgeTypeRef(CoreTypes.map, [
|
||||||
|
BridgeTypeRef(CoreTypes.string),
|
||||||
|
BridgeTypeRef(CoreTypes.string)
|
||||||
|
]),
|
||||||
nullable: true),
|
nullable: true),
|
||||||
true),
|
true),
|
||||||
])),
|
])),
|
||||||
'send': BridgeMethodDef(BridgeFunctionDef(
|
'send': BridgeMethodDef(BridgeFunctionDef(
|
||||||
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.future, [BridgeTypeRef(CoreTypes.list)])),
|
returns: BridgeTypeAnnotation(BridgeTypeRef(
|
||||||
|
CoreTypes.future, [BridgeTypeRef(CoreTypes.list)])),
|
||||||
params: [
|
params: [
|
||||||
BridgeParameter('request', BridgeTypeAnnotation($BaseRequest.$type), false),
|
BridgeParameter(
|
||||||
|
'request', BridgeTypeAnnotation($BaseRequest.$type), false),
|
||||||
])),
|
])),
|
||||||
'close': BridgeMethodDef(BridgeFunctionDef(
|
'close': BridgeMethodDef(BridgeFunctionDef(
|
||||||
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.voidType)),
|
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.voidType)),
|
||||||
|
|
@ -147,7 +214,8 @@ class $Client implements $Instance {
|
||||||
static $Client $new(Runtime runtime, $Value? target, List<$Value?> args) {
|
static $Client $new(Runtime runtime, $Value? target, List<$Value?> args) {
|
||||||
final reqcopyWith = args[1]?.$value == null
|
final reqcopyWith = args[1]?.$value == null
|
||||||
? null
|
? null
|
||||||
: (jsonDecode(args[1]!.$value) as Map).map((key, value) => MapEntry(key.toString(), value));
|
: (jsonDecode(args[1]!.$value) as Map)
|
||||||
|
.map((key, value) => MapEntry(key.toString(), value));
|
||||||
return $Client.wrap(
|
return $Client.wrap(
|
||||||
MClient.init(source: args[0]?.$value, reqcopyWith: reqcopyWith),
|
MClient.init(source: args[0]?.$value, reqcopyWith: reqcopyWith),
|
||||||
);
|
);
|
||||||
|
|
@ -183,8 +251,10 @@ class $Client implements $Instance {
|
||||||
final url = args[0]!.$value as Uri;
|
final url = args[0]!.$value as Uri;
|
||||||
final headers = _toMapString(args[1]?.$value);
|
final headers = _toMapString(args[1]?.$value);
|
||||||
|
|
||||||
final request = (target!.$value as InterceptedClient).get(url, headers: headers);
|
final request =
|
||||||
return $Future.wrap(request.then((value) => $Response.wrap(value)).onErrorMessage());
|
(target!.$value as InterceptedClient).get(url, headers: headers);
|
||||||
|
return $Future
|
||||||
|
.wrap(request.then((value) => $Response.wrap(value)).onErrorMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
static const $Function __post = $Function(_post);
|
static const $Function __post = $Function(_post);
|
||||||
|
|
@ -195,8 +265,10 @@ class $Client implements $Instance {
|
||||||
final body = _toBodyObject(args[2]?.$value);
|
final body = _toBodyObject(args[2]?.$value);
|
||||||
final encoding = args[3]?.$value as Encoding?;
|
final encoding = args[3]?.$value as Encoding?;
|
||||||
|
|
||||||
final request = (target!.$value as InterceptedClient).post(url, headers: headers, body: body, encoding: encoding);
|
final request = (target!.$value as InterceptedClient)
|
||||||
return $Future.wrap(request.then((value) => $Response.wrap(value)).onErrorMessage());
|
.post(url, headers: headers, body: body, encoding: encoding);
|
||||||
|
return $Future
|
||||||
|
.wrap(request.then((value) => $Response.wrap(value)).onErrorMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
static const $Function __put = $Function(_put);
|
static const $Function __put = $Function(_put);
|
||||||
|
|
@ -207,8 +279,10 @@ class $Client implements $Instance {
|
||||||
final body = _toBodyObject(args[2]?.$value);
|
final body = _toBodyObject(args[2]?.$value);
|
||||||
final encoding = args[3]?.$value as Encoding?;
|
final encoding = args[3]?.$value as Encoding?;
|
||||||
|
|
||||||
final request = (target!.$value as InterceptedClient).put(url, headers: headers, body: body, encoding: encoding);
|
final request = (target!.$value as InterceptedClient)
|
||||||
return $Future.wrap(request.then((value) => $Response.wrap(value)).onErrorMessage());
|
.put(url, headers: headers, body: body, encoding: encoding);
|
||||||
|
return $Future
|
||||||
|
.wrap(request.then((value) => $Response.wrap(value)).onErrorMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
static const $Function __delete = $Function(_delete);
|
static const $Function __delete = $Function(_delete);
|
||||||
|
|
@ -219,8 +293,10 @@ class $Client implements $Instance {
|
||||||
final body = _toBodyObject(args[2]?.$value);
|
final body = _toBodyObject(args[2]?.$value);
|
||||||
final encoding = args[3]?.$value as Encoding?;
|
final encoding = args[3]?.$value as Encoding?;
|
||||||
|
|
||||||
final request = (target!.$value as InterceptedClient).delete(url, headers: headers, body: body, encoding: encoding);
|
final request = (target!.$value as InterceptedClient)
|
||||||
return $Future.wrap(request.then((value) => $Response.wrap(value)).onErrorMessage());
|
.delete(url, headers: headers, body: body, encoding: encoding);
|
||||||
|
return $Future
|
||||||
|
.wrap(request.then((value) => $Response.wrap(value)).onErrorMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
static const $Function __patch = $Function(_patch);
|
static const $Function __patch = $Function(_patch);
|
||||||
|
|
@ -231,8 +307,10 @@ class $Client implements $Instance {
|
||||||
final body = _toBodyObject(args[2]?.$value);
|
final body = _toBodyObject(args[2]?.$value);
|
||||||
final encoding = args[3]?.$value as Encoding?;
|
final encoding = args[3]?.$value as Encoding?;
|
||||||
|
|
||||||
final request = (target!.$value as InterceptedClient).patch(url, headers: headers, body: body, encoding: encoding);
|
final request = (target!.$value as InterceptedClient)
|
||||||
return $Future.wrap(request.then((value) => $Response.wrap(value)).onErrorMessage());
|
.patch(url, headers: headers, body: body, encoding: encoding);
|
||||||
|
return $Future
|
||||||
|
.wrap(request.then((value) => $Response.wrap(value)).onErrorMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
static const $Function __read = $Function(_read);
|
static const $Function __read = $Function(_read);
|
||||||
|
|
@ -241,19 +319,25 @@ class $Client implements $Instance {
|
||||||
final url = args[0]!.$value as Uri;
|
final url = args[0]!.$value as Uri;
|
||||||
final headers = _toMapString(args[1]?.$value);
|
final headers = _toMapString(args[1]?.$value);
|
||||||
|
|
||||||
final request = (target!.$value as InterceptedClient).read(url, headers: headers);
|
final request =
|
||||||
return $Future.wrap(request.then((value) => $String(value)).onErrorMessage());
|
(target!.$value as InterceptedClient).read(url, headers: headers);
|
||||||
|
return $Future
|
||||||
|
.wrap(request.then((value) => $String(value)).onErrorMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
static const $Function __readBytes = $Function(_readBytes);
|
static const $Function __readBytes = $Function(_readBytes);
|
||||||
|
|
||||||
static $Value? _readBytes(Runtime runtime, $Value? target, List<$Value?> args) {
|
static $Value? _readBytes(
|
||||||
|
Runtime runtime, $Value? target, List<$Value?> args) {
|
||||||
final url = args[0]!.$value as Uri;
|
final url = args[0]!.$value as Uri;
|
||||||
final headers = (args[1]?.$value as Map<$Value, $Value>?)
|
final headers = (args[1]?.$value as Map<$Value, $Value>?)?.map(
|
||||||
?.map((key, value) => MapEntry((key.$reified).toString(), (value.$reified).toString()));
|
(key, value) =>
|
||||||
|
MapEntry((key.$reified).toString(), (value.$reified).toString()));
|
||||||
|
|
||||||
final request = (target!.$value as InterceptedClient).readBytes(url, headers: headers);
|
final request =
|
||||||
return $Future.wrap(request.then((value) => $List.wrap(value)).onErrorMessage());
|
(target!.$value as InterceptedClient).readBytes(url, headers: headers);
|
||||||
|
return $Future
|
||||||
|
.wrap(request.then((value) => $List.wrap(value)).onErrorMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
static const $Function __close = $Function(_close);
|
static const $Function __close = $Function(_close);
|
||||||
|
|
@ -281,46 +365,52 @@ class $BaseRequest implements $Instance {
|
||||||
final BaseRequest $value;
|
final BaseRequest $value;
|
||||||
|
|
||||||
/// Compile-time bridged type reference for [$BaseRequest]
|
/// Compile-time bridged type reference for [$BaseRequest]
|
||||||
static const $type = BridgeTypeRef(BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'BaseRequest'));
|
static const $type = BridgeTypeRef(
|
||||||
|
BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'BaseRequest'));
|
||||||
|
|
||||||
/// Compile-time bridged class declaration for [$BaseRequest]
|
/// Compile-time bridged class declaration for [$BaseRequest]
|
||||||
static const $declaration = BridgeClassDef(BridgeClassType($type, isAbstract: true),
|
static const $declaration =
|
||||||
constructors: {},
|
BridgeClassDef(BridgeClassType($type, isAbstract: true),
|
||||||
getters: {
|
constructors: {},
|
||||||
'contentLength': BridgeMethodDef(BridgeFunctionDef(
|
getters: {
|
||||||
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.int), nullable: true),
|
'contentLength': BridgeMethodDef(BridgeFunctionDef(
|
||||||
)),
|
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.int),
|
||||||
'finalized': BridgeMethodDef(BridgeFunctionDef(
|
nullable: true),
|
||||||
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.bool)),
|
)),
|
||||||
)),
|
'finalized': BridgeMethodDef(BridgeFunctionDef(
|
||||||
'followRedirects': BridgeMethodDef(BridgeFunctionDef(
|
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.bool)),
|
||||||
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.bool)),
|
)),
|
||||||
)),
|
'followRedirects': BridgeMethodDef(BridgeFunctionDef(
|
||||||
'headers': BridgeMethodDef(BridgeFunctionDef(
|
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.bool)),
|
||||||
returns: BridgeTypeAnnotation(
|
)),
|
||||||
BridgeTypeRef(CoreTypes.map, [BridgeTypeRef(CoreTypes.string), BridgeTypeRef(CoreTypes.string)]),
|
'headers': BridgeMethodDef(BridgeFunctionDef(
|
||||||
),
|
returns: BridgeTypeAnnotation(
|
||||||
)),
|
BridgeTypeRef(CoreTypes.map, [
|
||||||
'maxRedirects': BridgeMethodDef(BridgeFunctionDef(
|
BridgeTypeRef(CoreTypes.string),
|
||||||
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.int)),
|
BridgeTypeRef(CoreTypes.string)
|
||||||
)),
|
]),
|
||||||
'method': BridgeMethodDef(BridgeFunctionDef(
|
),
|
||||||
returns: BridgeTypeAnnotation(
|
)),
|
||||||
BridgeTypeRef(CoreTypes.string),
|
'maxRedirects': BridgeMethodDef(BridgeFunctionDef(
|
||||||
),
|
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.int)),
|
||||||
)),
|
)),
|
||||||
'persistentConnection': BridgeMethodDef(BridgeFunctionDef(
|
'method': BridgeMethodDef(BridgeFunctionDef(
|
||||||
returns: BridgeTypeAnnotation(
|
returns: BridgeTypeAnnotation(
|
||||||
BridgeTypeRef(CoreTypes.string),
|
BridgeTypeRef(CoreTypes.string),
|
||||||
),
|
),
|
||||||
)),
|
)),
|
||||||
'url': BridgeMethodDef(BridgeFunctionDef(
|
'persistentConnection': BridgeMethodDef(BridgeFunctionDef(
|
||||||
returns: BridgeTypeAnnotation(
|
returns: BridgeTypeAnnotation(
|
||||||
BridgeTypeRef(CoreTypes.uri),
|
BridgeTypeRef(CoreTypes.string),
|
||||||
),
|
),
|
||||||
)),
|
)),
|
||||||
},
|
'url': BridgeMethodDef(BridgeFunctionDef(
|
||||||
wrap: true);
|
returns: BridgeTypeAnnotation(
|
||||||
|
BridgeTypeRef(CoreTypes.uri),
|
||||||
|
),
|
||||||
|
)),
|
||||||
|
},
|
||||||
|
wrap: true);
|
||||||
|
|
||||||
final $Instance _superclass;
|
final $Instance _superclass;
|
||||||
|
|
||||||
|
|
@ -369,25 +459,34 @@ class $Response implements $Instance {
|
||||||
final Response $value;
|
final Response $value;
|
||||||
|
|
||||||
/// Compile-time bridged type reference for [$Response]
|
/// Compile-time bridged type reference for [$Response]
|
||||||
static const $type = BridgeTypeRef(BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'Response'));
|
static const $type = BridgeTypeRef(
|
||||||
|
BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'Response'));
|
||||||
|
|
||||||
/// Compile-time bridged class declaration for [$Response]
|
/// Compile-time bridged class declaration for [$Response]
|
||||||
static const $declaration = BridgeClassDef(
|
static const $declaration = BridgeClassDef(
|
||||||
BridgeClassType($type),
|
BridgeClassType($type),
|
||||||
constructors: {'': BridgeConstructorDef(BridgeFunctionDef(returns: BridgeTypeAnnotation($type)))},
|
constructors: {
|
||||||
|
'': BridgeConstructorDef(
|
||||||
|
BridgeFunctionDef(returns: BridgeTypeAnnotation($type)))
|
||||||
|
},
|
||||||
getters: {
|
getters: {
|
||||||
'body': BridgeMethodDef(BridgeFunctionDef(
|
'body': BridgeMethodDef(BridgeFunctionDef(
|
||||||
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)),
|
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)),
|
||||||
)),
|
)),
|
||||||
'bodyBytes': BridgeMethodDef(BridgeFunctionDef(
|
'bodyBytes': BridgeMethodDef(BridgeFunctionDef(
|
||||||
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.list, [BridgeTypeRef(CoreTypes.int)])),
|
returns: BridgeTypeAnnotation(
|
||||||
|
BridgeTypeRef(CoreTypes.list, [BridgeTypeRef(CoreTypes.int)])),
|
||||||
)),
|
)),
|
||||||
'contentLength': BridgeMethodDef(BridgeFunctionDef(
|
'contentLength': BridgeMethodDef(BridgeFunctionDef(
|
||||||
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.int), nullable: true),
|
returns:
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.int), nullable: true),
|
||||||
)),
|
)),
|
||||||
'headers': BridgeMethodDef(BridgeFunctionDef(
|
'headers': BridgeMethodDef(BridgeFunctionDef(
|
||||||
returns: BridgeTypeAnnotation(
|
returns: BridgeTypeAnnotation(
|
||||||
BridgeTypeRef(CoreTypes.map, [BridgeTypeRef(CoreTypes.string), BridgeTypeRef(CoreTypes.string)]),
|
BridgeTypeRef(CoreTypes.map, [
|
||||||
|
BridgeTypeRef(CoreTypes.string),
|
||||||
|
BridgeTypeRef(CoreTypes.string)
|
||||||
|
]),
|
||||||
),
|
),
|
||||||
)),
|
)),
|
||||||
'isRedirect': BridgeMethodDef(BridgeFunctionDef(
|
'isRedirect': BridgeMethodDef(BridgeFunctionDef(
|
||||||
|
|
@ -397,7 +496,8 @@ class $Response implements $Instance {
|
||||||
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.bool)),
|
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.bool)),
|
||||||
)),
|
)),
|
||||||
'reasonPhrase': BridgeMethodDef(BridgeFunctionDef(
|
'reasonPhrase': BridgeMethodDef(BridgeFunctionDef(
|
||||||
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string), nullable: true),
|
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string),
|
||||||
|
nullable: true),
|
||||||
)),
|
)),
|
||||||
'statusCode': BridgeMethodDef(BridgeFunctionDef(
|
'statusCode': BridgeMethodDef(BridgeFunctionDef(
|
||||||
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.int)),
|
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.int)),
|
||||||
|
|
@ -460,22 +560,30 @@ class $StreamedResponse implements $Instance {
|
||||||
final StreamedResponse $value;
|
final StreamedResponse $value;
|
||||||
|
|
||||||
/// Compile-time bridged type reference for [$StreamedResponse]
|
/// Compile-time bridged type reference for [$StreamedResponse]
|
||||||
static const $type = BridgeTypeRef(BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'StreamedResponse'));
|
static const $type = BridgeTypeRef(
|
||||||
|
BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'StreamedResponse'));
|
||||||
|
|
||||||
/// Compile-time bridged class declaration for [$StreamedResponse]
|
/// Compile-time bridged class declaration for [$StreamedResponse]
|
||||||
static const $declaration = BridgeClassDef(
|
static const $declaration = BridgeClassDef(
|
||||||
BridgeClassType($type),
|
BridgeClassType($type),
|
||||||
constructors: {'': BridgeConstructorDef(BridgeFunctionDef(returns: BridgeTypeAnnotation($type)))},
|
constructors: {
|
||||||
|
'': BridgeConstructorDef(
|
||||||
|
BridgeFunctionDef(returns: BridgeTypeAnnotation($type)))
|
||||||
|
},
|
||||||
getters: {
|
getters: {
|
||||||
'stream': BridgeMethodDef(BridgeFunctionDef(
|
'stream': BridgeMethodDef(BridgeFunctionDef(
|
||||||
returns: BridgeTypeAnnotation($ByteStream.$type),
|
returns: BridgeTypeAnnotation($ByteStream.$type),
|
||||||
)),
|
)),
|
||||||
'contentLength': BridgeMethodDef(BridgeFunctionDef(
|
'contentLength': BridgeMethodDef(BridgeFunctionDef(
|
||||||
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.int), nullable: true),
|
returns:
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.int), nullable: true),
|
||||||
)),
|
)),
|
||||||
'headers': BridgeMethodDef(BridgeFunctionDef(
|
'headers': BridgeMethodDef(BridgeFunctionDef(
|
||||||
returns: BridgeTypeAnnotation(
|
returns: BridgeTypeAnnotation(
|
||||||
BridgeTypeRef(CoreTypes.map, [BridgeTypeRef(CoreTypes.string), BridgeTypeRef(CoreTypes.string)]),
|
BridgeTypeRef(CoreTypes.map, [
|
||||||
|
BridgeTypeRef(CoreTypes.string),
|
||||||
|
BridgeTypeRef(CoreTypes.string)
|
||||||
|
]),
|
||||||
),
|
),
|
||||||
)),
|
)),
|
||||||
'isRedirect': BridgeMethodDef(BridgeFunctionDef(
|
'isRedirect': BridgeMethodDef(BridgeFunctionDef(
|
||||||
|
|
@ -485,7 +593,8 @@ class $StreamedResponse implements $Instance {
|
||||||
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.bool)),
|
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.bool)),
|
||||||
)),
|
)),
|
||||||
'reasonPhrase': BridgeMethodDef(BridgeFunctionDef(
|
'reasonPhrase': BridgeMethodDef(BridgeFunctionDef(
|
||||||
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string), nullable: true),
|
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string),
|
||||||
|
nullable: true),
|
||||||
)),
|
)),
|
||||||
'statusCode': BridgeMethodDef(BridgeFunctionDef(
|
'statusCode': BridgeMethodDef(BridgeFunctionDef(
|
||||||
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.int)),
|
returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.int)),
|
||||||
|
|
@ -546,12 +655,16 @@ class $ByteStream implements $Instance {
|
||||||
final ByteStream $value;
|
final ByteStream $value;
|
||||||
|
|
||||||
/// Compile-time bridged type reference for [$ByteStream]
|
/// Compile-time bridged type reference for [$ByteStream]
|
||||||
static const $type = BridgeTypeRef(BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'ByteStream'));
|
static const $type = BridgeTypeRef(
|
||||||
|
BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'ByteStream'));
|
||||||
|
|
||||||
/// Compile-time bridged class declaration for [$ByteStream]
|
/// Compile-time bridged class declaration for [$ByteStream]
|
||||||
static const $declaration = BridgeClassDef(
|
static const $declaration = BridgeClassDef(
|
||||||
BridgeClassType($type),
|
BridgeClassType($type),
|
||||||
constructors: {'': BridgeConstructorDef(BridgeFunctionDef(returns: BridgeTypeAnnotation($type)))},
|
constructors: {
|
||||||
|
'': BridgeConstructorDef(
|
||||||
|
BridgeFunctionDef(returns: BridgeTypeAnnotation($type)))
|
||||||
|
},
|
||||||
getters: {},
|
getters: {},
|
||||||
wrap: true,
|
wrap: true,
|
||||||
);
|
);
|
||||||
|
|
@ -579,13 +692,15 @@ class $ByteStream implements $Instance {
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, String>? _toMapString(Map<$Value, $Value>? value) {
|
Map<String, String>? _toMapString(Map<$Value, $Value>? value) {
|
||||||
return value?.map((key, value) => MapEntry((key.$reified).toString(), (value.$reified).toString()));
|
return value?.map((key, value) =>
|
||||||
|
MapEntry((key.$reified).toString(), (value.$reified).toString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
Object? _toBodyObject(Object? value) {
|
Object? _toBodyObject(Object? value) {
|
||||||
Object? body;
|
Object? body;
|
||||||
if (value is Map<$Value, $Value>) {
|
if (value is Map<$Value, $Value>) {
|
||||||
body = value.map((key, value) => MapEntry((key.$reified).toString(), (value.$reified).toString()));
|
body = value.map((key, value) =>
|
||||||
|
MapEntry((key.$reified).toString(), (value.$reified).toString()));
|
||||||
} else if (value is List<$Value>) {
|
} else if (value is List<$Value>) {
|
||||||
body = value.map((e) => e.$reified).toList();
|
body = value.map((e) => e.$reified).toList();
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -5,23 +5,35 @@ import 'package:mangayomi/eval/model/m_chapter.dart';
|
||||||
class $MChapter implements MChapter, $Instance {
|
class $MChapter implements MChapter, $Instance {
|
||||||
$MChapter.wrap(this.$value) : _superclass = $Object($value);
|
$MChapter.wrap(this.$value) : _superclass = $Object($value);
|
||||||
|
|
||||||
static const $type = BridgeTypeRef(BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'MChapter'));
|
static const $type = BridgeTypeRef(
|
||||||
|
BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'MChapter'));
|
||||||
|
|
||||||
static const $declaration = BridgeClassDef(BridgeClassType($type),
|
static const $declaration = BridgeClassDef(BridgeClassType($type),
|
||||||
constructors: {
|
constructors: {
|
||||||
'': BridgeConstructorDef(BridgeFunctionDef(returns: BridgeTypeAnnotation($type), params: [], namedParams: [
|
'': BridgeConstructorDef(BridgeFunctionDef(
|
||||||
BridgeParameter('name', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
returns: BridgeTypeAnnotation($type),
|
||||||
BridgeParameter('url', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
params: [],
|
||||||
BridgeParameter('dateUpload', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
namedParams: [
|
||||||
BridgeParameter('scanlator', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), true),
|
BridgeParameter('name',
|
||||||
]))
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
||||||
|
BridgeParameter('url',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
||||||
|
BridgeParameter('dateUpload',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
||||||
|
BridgeParameter('scanlator',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), true),
|
||||||
|
]))
|
||||||
},
|
},
|
||||||
// Specify class fields
|
// Specify class fields
|
||||||
fields: {
|
fields: {
|
||||||
'name': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
'name': BridgeFieldDef(
|
||||||
'url': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
||||||
'dateUpload': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
'url': BridgeFieldDef(
|
||||||
'scanlator': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
||||||
|
'dateUpload': BridgeFieldDef(
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
||||||
|
'scanlator': BridgeFieldDef(
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
||||||
},
|
},
|
||||||
wrap: true);
|
wrap: true);
|
||||||
|
|
||||||
|
|
@ -102,5 +114,10 @@ class $MChapter implements MChapter, $Instance {
|
||||||
set scanlator(String? scanlator) {}
|
set scanlator(String? scanlator) {}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Map<String, dynamic> toJson() => {'name': name, 'url': url, 'dateUpload': dateUpload, 'scanlator': scanlator};
|
Map<String, dynamic> toJson() => {
|
||||||
|
'name': name,
|
||||||
|
'url': url,
|
||||||
|
'dateUpload': dateUpload,
|
||||||
|
'scanlator': scanlator
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,25 +10,36 @@ import 'package:mangayomi/utils/extensions/string_extensions.dart';
|
||||||
class $MManga implements MManga, $Instance {
|
class $MManga implements MManga, $Instance {
|
||||||
$MManga.wrap(this.$value) : _superclass = $Object($value);
|
$MManga.wrap(this.$value) : _superclass = $Object($value);
|
||||||
|
|
||||||
static const $type = BridgeTypeRef(BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'MManga'));
|
static const $type = BridgeTypeRef(
|
||||||
|
BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'MManga'));
|
||||||
|
|
||||||
static const $declaration = BridgeClassDef(BridgeClassType($type),
|
static const $declaration = BridgeClassDef(BridgeClassType($type),
|
||||||
constructors: {'': BridgeConstructorDef(BridgeFunctionDef(returns: BridgeTypeAnnotation($type), params: []))},
|
constructors: {
|
||||||
|
'': BridgeConstructorDef(
|
||||||
|
BridgeFunctionDef(returns: BridgeTypeAnnotation($type), params: []))
|
||||||
|
},
|
||||||
// Specify class fields
|
// Specify class fields
|
||||||
fields: {
|
fields: {
|
||||||
'author': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
'author': BridgeFieldDef(
|
||||||
'artist': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
||||||
|
'artist': BridgeFieldDef(
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
||||||
'status': BridgeFieldDef(BridgeTypeAnnotation($MStatus.$type)),
|
'status': BridgeFieldDef(BridgeTypeAnnotation($MStatus.$type)),
|
||||||
'genre': BridgeFieldDef(
|
'genre': BridgeFieldDef(
|
||||||
BridgeTypeAnnotation(
|
BridgeTypeAnnotation(
|
||||||
BridgeTypeRef(CoreTypes.list, [BridgeTypeRef(CoreTypes.string)]),
|
BridgeTypeRef(CoreTypes.list, [BridgeTypeRef(CoreTypes.string)]),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
'imageUrl': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
'imageUrl': BridgeFieldDef(
|
||||||
'name': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
||||||
'link': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
'name': BridgeFieldDef(
|
||||||
'description': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
||||||
'chapters': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.list, [$MChapter.$type]))),
|
'link': BridgeFieldDef(
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
||||||
|
'description': BridgeFieldDef(
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
||||||
|
'chapters': BridgeFieldDef(BridgeTypeAnnotation(
|
||||||
|
BridgeTypeRef(CoreTypes.list, [$MChapter.$type]))),
|
||||||
},
|
},
|
||||||
wrap: true);
|
wrap: true);
|
||||||
|
|
||||||
|
|
@ -65,7 +76,8 @@ class $MManga implements MManga, $Instance {
|
||||||
case 'description':
|
case 'description':
|
||||||
return $String($value.description!);
|
return $String($value.description!);
|
||||||
case 'chapters':
|
case 'chapters':
|
||||||
return $List.wrap($value.chapters!.map((e) => $MChapter.wrap(e)).toList());
|
return $List
|
||||||
|
.wrap($value.chapters!.map((e) => $MChapter.wrap(e)).toList());
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return _superclass.$getProperty(runtime, identifier);
|
return _superclass.$getProperty(runtime, identifier);
|
||||||
|
|
@ -85,7 +97,8 @@ class $MManga implements MManga, $Instance {
|
||||||
case 'status':
|
case 'status':
|
||||||
$value.status = value.$reified;
|
$value.status = value.$reified;
|
||||||
case 'genre':
|
case 'genre':
|
||||||
$value.genre = (value.$reified as List).map((e) => e.toString()).toList();
|
$value.genre =
|
||||||
|
(value.$reified as List).map((e) => e.toString()).toList();
|
||||||
case 'imageUrl':
|
case 'imageUrl':
|
||||||
$value.imageUrl = value.$reified;
|
$value.imageUrl = value.$reified;
|
||||||
case 'name':
|
case 'name':
|
||||||
|
|
@ -96,7 +109,11 @@ class $MManga implements MManga, $Instance {
|
||||||
$value.description = value.$reified;
|
$value.description = value.$reified;
|
||||||
case 'chapters':
|
case 'chapters':
|
||||||
$value.chapters = (value.$reified as List)
|
$value.chapters = (value.$reified as List)
|
||||||
.map((e) => MChapter(dateUpload: e.dateUpload, url: e.url, name: e.name, scanlator: e.scanlator))
|
.map((e) => MChapter(
|
||||||
|
dateUpload: e.dateUpload,
|
||||||
|
url: e.url,
|
||||||
|
name: e.name,
|
||||||
|
scanlator: e.scanlator))
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
||||||
|
|
@ -7,26 +7,40 @@ import 'package:mangayomi/eval/model/m_pages.dart';
|
||||||
class $MPages implements MPages, $Instance {
|
class $MPages implements MPages, $Instance {
|
||||||
$MPages.wrap(this.$value) : _superclass = $Object($value);
|
$MPages.wrap(this.$value) : _superclass = $Object($value);
|
||||||
|
|
||||||
static const $type = BridgeTypeRef(BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'MPages'));
|
static const $type = BridgeTypeRef(
|
||||||
|
BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'MPages'));
|
||||||
|
|
||||||
static const $declaration = BridgeClassDef(BridgeClassType($type),
|
static const $declaration = BridgeClassDef(BridgeClassType($type),
|
||||||
constructors: {
|
constructors: {
|
||||||
'': BridgeConstructorDef(BridgeFunctionDef(returns: BridgeTypeAnnotation($type), params: [
|
'': BridgeConstructorDef(
|
||||||
BridgeParameter('list', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.list, [$MManga.$type])), false),
|
BridgeFunctionDef(returns: BridgeTypeAnnotation($type), params: [
|
||||||
BridgeParameter('hasNextPage', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.bool), nullable: true), true),
|
BridgeParameter(
|
||||||
|
'list',
|
||||||
|
BridgeTypeAnnotation(
|
||||||
|
BridgeTypeRef(CoreTypes.list, [$MManga.$type])),
|
||||||
|
false),
|
||||||
|
BridgeParameter(
|
||||||
|
'hasNextPage',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.bool),
|
||||||
|
nullable: true),
|
||||||
|
true),
|
||||||
]))
|
]))
|
||||||
},
|
},
|
||||||
fields: {
|
fields: {
|
||||||
'list': BridgeFieldDef(
|
'list': BridgeFieldDef(
|
||||||
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.list, [$MManga.$type])),
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.list, [$MManga.$type])),
|
||||||
),
|
),
|
||||||
'hasNextPage': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.bool), nullable: true)),
|
'hasNextPage': BridgeFieldDef(BridgeTypeAnnotation(
|
||||||
|
BridgeTypeRef(CoreTypes.bool),
|
||||||
|
nullable: true)),
|
||||||
},
|
},
|
||||||
wrap: true);
|
wrap: true);
|
||||||
|
|
||||||
static $Value? $new(Runtime runtime, $Value? target, List<$Value?> args) {
|
static $Value? $new(Runtime runtime, $Value? target, List<$Value?> args) {
|
||||||
List<$Value> list = args[0]!.$value;
|
List<$Value> list = args[0]!.$value;
|
||||||
return $MPages.wrap(MPages(list: list.map((e) => e as MManga).toList(), hasNextPage: args[1]?.$value ?? false));
|
return $MPages.wrap(MPages(
|
||||||
|
list: list.map((e) => e as MManga).toList(),
|
||||||
|
hasNextPage: args[1]?.$value ?? false));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -5,21 +5,35 @@ import 'package:mangayomi/eval/model/m_source.dart';
|
||||||
class $MSource implements MSource, $Instance {
|
class $MSource implements MSource, $Instance {
|
||||||
$MSource.wrap(this.$value) : _superclass = $Object($value);
|
$MSource.wrap(this.$value) : _superclass = $Object($value);
|
||||||
|
|
||||||
static const $type = BridgeTypeRef(BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'MSource'));
|
static const $type = BridgeTypeRef(
|
||||||
|
BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'MSource'));
|
||||||
|
|
||||||
static const $declaration = BridgeClassDef(BridgeClassType($type),
|
static const $declaration = BridgeClassDef(BridgeClassType($type),
|
||||||
constructors: {'': BridgeConstructorDef(BridgeFunctionDef(returns: BridgeTypeAnnotation($type), params: []))},
|
constructors: {
|
||||||
|
'': BridgeConstructorDef(
|
||||||
|
BridgeFunctionDef(returns: BridgeTypeAnnotation($type), params: []))
|
||||||
|
},
|
||||||
fields: {
|
fields: {
|
||||||
'id': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.int))),
|
'id':
|
||||||
'name': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.int))),
|
||||||
'baseUrl': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
'name': BridgeFieldDef(
|
||||||
'lang': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
||||||
'isFullData': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.bool))),
|
'baseUrl': BridgeFieldDef(
|
||||||
'hasCloudflare': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.bool))),
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
||||||
'dateFormat': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
'lang': BridgeFieldDef(
|
||||||
'dateFormatLocale': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
||||||
'apiUrl': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
'isFullData':
|
||||||
'additionalParams': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.bool))),
|
||||||
|
'hasCloudflare':
|
||||||
|
BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.bool))),
|
||||||
|
'dateFormat': BridgeFieldDef(
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
||||||
|
'dateFormatLocale': BridgeFieldDef(
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
||||||
|
'apiUrl': BridgeFieldDef(
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
||||||
|
'additionalParams': BridgeFieldDef(
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
||||||
},
|
},
|
||||||
wrap: true);
|
wrap: true);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,14 +3,18 @@ import 'package:dart_eval/stdlib/core.dart';
|
||||||
import 'package:mangayomi/models/manga.dart';
|
import 'package:mangayomi/models/manga.dart';
|
||||||
|
|
||||||
class $MStatus implements $Instance {
|
class $MStatus implements $Instance {
|
||||||
static $MStatus $wrap(Runtime runtime, $Value? target, List<$Value?> args) => $MStatus.wrap(args[0]!.$value);
|
static $MStatus $wrap(Runtime runtime, $Value? target, List<$Value?> args) =>
|
||||||
static const $type = BridgeTypeRef(BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'MStatus'));
|
$MStatus.wrap(args[0]!.$value);
|
||||||
static const $declaration = BridgeEnumDef($type,
|
static const $type = BridgeTypeRef(
|
||||||
values: ['ongoing', 'completed', 'canceled', 'unknown', 'onHiatus', 'publishingFinished'],
|
BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'MStatus'));
|
||||||
methods: {},
|
static const $declaration = BridgeEnumDef($type, values: [
|
||||||
getters: {},
|
'ongoing',
|
||||||
setters: {},
|
'completed',
|
||||||
fields: {});
|
'canceled',
|
||||||
|
'unknown',
|
||||||
|
'onHiatus',
|
||||||
|
'publishingFinished'
|
||||||
|
], methods: {}, getters: {}, setters: {}, fields: {});
|
||||||
static final $values = Status.values.asNameMap().map(
|
static final $values = Status.values.asNameMap().map(
|
||||||
(key, value) => MapEntry(key, $MStatus.wrap(value)),
|
(key, value) => MapEntry(key, $MStatus.wrap(value)),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,8 @@ import 'package:mangayomi/models/video.dart';
|
||||||
class $MTrack implements Track, $Instance {
|
class $MTrack implements Track, $Instance {
|
||||||
$MTrack.wrap(this.$value) : _superclass = $Object($value);
|
$MTrack.wrap(this.$value) : _superclass = $Object($value);
|
||||||
|
|
||||||
static const $type = BridgeTypeRef(BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'MTrack'));
|
static const $type = BridgeTypeRef(
|
||||||
|
BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'MTrack'));
|
||||||
|
|
||||||
static const $declaration = BridgeClassDef(BridgeClassType($type),
|
static const $declaration = BridgeClassDef(BridgeClassType($type),
|
||||||
constructors: {
|
constructors: {
|
||||||
|
|
@ -15,8 +16,10 @@ class $MTrack implements Track, $Instance {
|
||||||
},
|
},
|
||||||
// Specify class fields
|
// Specify class fields
|
||||||
fields: {
|
fields: {
|
||||||
'file': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
'file': BridgeFieldDef(
|
||||||
'label': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
||||||
|
'label': BridgeFieldDef(
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
||||||
},
|
},
|
||||||
wrap: true);
|
wrap: true);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,8 @@ import 'package:mangayomi/models/video.dart';
|
||||||
class $MVideo implements Video, $Instance {
|
class $MVideo implements Video, $Instance {
|
||||||
$MVideo.wrap(this.$value) : _superclass = $Object($value);
|
$MVideo.wrap(this.$value) : _superclass = $Object($value);
|
||||||
|
|
||||||
static const $type = BridgeTypeRef(BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'MVideo'));
|
static const $type = BridgeTypeRef(
|
||||||
|
BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'MVideo'));
|
||||||
|
|
||||||
static const $declaration = BridgeClassDef(BridgeClassType($type),
|
static const $declaration = BridgeClassDef(BridgeClassType($type),
|
||||||
constructors: {
|
constructors: {
|
||||||
|
|
@ -16,14 +17,22 @@ class $MVideo implements Video, $Instance {
|
||||||
},
|
},
|
||||||
// Specify class fields
|
// Specify class fields
|
||||||
fields: {
|
fields: {
|
||||||
'url': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
'url': BridgeFieldDef(
|
||||||
'quality': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
||||||
'originalUrl': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
'quality': BridgeFieldDef(
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
||||||
|
'originalUrl': BridgeFieldDef(
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
||||||
'headers': BridgeFieldDef(BridgeTypeAnnotation(
|
'headers': BridgeFieldDef(BridgeTypeAnnotation(
|
||||||
BridgeTypeRef(CoreTypes.map, [BridgeTypeRef(CoreTypes.string), BridgeTypeRef(CoreTypes.string)]),
|
BridgeTypeRef(CoreTypes.map, [
|
||||||
|
BridgeTypeRef(CoreTypes.string),
|
||||||
|
BridgeTypeRef(CoreTypes.string)
|
||||||
|
]),
|
||||||
nullable: true)),
|
nullable: true)),
|
||||||
'subtitles': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.list, [$MTrack.$type]))),
|
'subtitles': BridgeFieldDef(BridgeTypeAnnotation(
|
||||||
'audios': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.list, [$MTrack.$type]))),
|
BridgeTypeRef(CoreTypes.list, [$MTrack.$type]))),
|
||||||
|
'audios': BridgeFieldDef(BridgeTypeAnnotation(
|
||||||
|
BridgeTypeRef(CoreTypes.list, [$MTrack.$type]))),
|
||||||
},
|
},
|
||||||
wrap: true);
|
wrap: true);
|
||||||
|
|
||||||
|
|
@ -51,9 +60,13 @@ class $MVideo implements Video, $Instance {
|
||||||
case 'headers':
|
case 'headers':
|
||||||
return $Map.wrap($value.headers ?? {});
|
return $Map.wrap($value.headers ?? {});
|
||||||
case 'subtitles':
|
case 'subtitles':
|
||||||
return $List.wrap($value.subtitles!.map((e) => $MTrack.wrap(Track(file: e.file, label: e.label))).toList());
|
return $List.wrap($value.subtitles!
|
||||||
|
.map((e) => $MTrack.wrap(Track(file: e.file, label: e.label)))
|
||||||
|
.toList());
|
||||||
case 'audios':
|
case 'audios':
|
||||||
return $List.wrap($value.audios!.map((e) => $MTrack.wrap(Track(file: e.file, label: e.label))).toList());
|
return $List.wrap($value.audios!
|
||||||
|
.map((e) => $MTrack.wrap(Track(file: e.file, label: e.label)))
|
||||||
|
.toList());
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return _superclass.$getProperty(runtime, identifier);
|
return _superclass.$getProperty(runtime, identifier);
|
||||||
|
|
@ -73,12 +86,17 @@ class $MVideo implements Video, $Instance {
|
||||||
case 'originalUrl':
|
case 'originalUrl':
|
||||||
$value.originalUrl = value.$reified;
|
$value.originalUrl = value.$reified;
|
||||||
case 'headers':
|
case 'headers':
|
||||||
$value.headers = (value.$reified as Map).map((key, value) => MapEntry(key.toString(), value.toString()));
|
$value.headers = (value.$reified as Map)
|
||||||
|
.map((key, value) => MapEntry(key.toString(), value.toString()));
|
||||||
case 'subtitles':
|
case 'subtitles':
|
||||||
$value.subtitles = (value.$reified as List).map((e) => Track(file: e.file, label: e.label)).toList();
|
$value.subtitles = (value.$reified as List)
|
||||||
|
.map((e) => Track(file: e.file, label: e.label))
|
||||||
|
.toList();
|
||||||
|
|
||||||
case 'audios':
|
case 'audios':
|
||||||
$value.audios = (value.$reified as List).map((e) => Track(file: e.file, label: e.label)).toList();
|
$value.audios = (value.$reified as List)
|
||||||
|
.map((e) => Track(file: e.file, label: e.label))
|
||||||
|
.toList();
|
||||||
|
|
||||||
default:
|
default:
|
||||||
_superclass.$setProperty(runtime, identifier, value);
|
_superclass.$setProperty(runtime, identifier, value);
|
||||||
|
|
|
||||||
|
|
@ -6,30 +6,44 @@ import 'package:mangayomi/eval/model/source_preference.dart';
|
||||||
class $CheckBoxPreference implements SourcePreference, $Instance {
|
class $CheckBoxPreference implements SourcePreference, $Instance {
|
||||||
$CheckBoxPreference.wrap(this.$value) : _superclass = $Object($value);
|
$CheckBoxPreference.wrap(this.$value) : _superclass = $Object($value);
|
||||||
|
|
||||||
static const $type = BridgeTypeRef(BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'CheckBoxPreference'));
|
static const $type = BridgeTypeRef(BridgeTypeSpec(
|
||||||
|
'package:mangayomi/bridge_lib.dart', 'CheckBoxPreference'));
|
||||||
|
|
||||||
static const $declaration = BridgeClassDef(BridgeClassType($type),
|
static const $declaration = BridgeClassDef(BridgeClassType($type),
|
||||||
constructors: {
|
constructors: {
|
||||||
'': BridgeConstructorDef(BridgeFunctionDef(returns: BridgeTypeAnnotation($type), params: [], namedParams: [
|
'': BridgeConstructorDef(BridgeFunctionDef(
|
||||||
BridgeParameter('key', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
returns: BridgeTypeAnnotation($type),
|
||||||
BridgeParameter('title', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
params: [],
|
||||||
BridgeParameter('summary', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
namedParams: [
|
||||||
BridgeParameter('value', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.bool)), false),
|
BridgeParameter('key',
|
||||||
]))
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
||||||
|
BridgeParameter('title',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
||||||
|
BridgeParameter('summary',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
||||||
|
BridgeParameter('value',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.bool)), false),
|
||||||
|
]))
|
||||||
},
|
},
|
||||||
fields: {
|
fields: {
|
||||||
'key': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
'key': BridgeFieldDef(
|
||||||
'title': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
||||||
'summary': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
'title': BridgeFieldDef(
|
||||||
'value': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.bool))),
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
||||||
|
'summary': BridgeFieldDef(
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
||||||
|
'value':
|
||||||
|
BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.bool))),
|
||||||
},
|
},
|
||||||
wrap: true);
|
wrap: true);
|
||||||
|
|
||||||
static $Value? $new(Runtime runtime, $Value? target, List<$Value?> args) {
|
static $Value? $new(Runtime runtime, $Value? target, List<$Value?> args) {
|
||||||
return $CheckBoxPreference.wrap(SourcePreference(
|
return $CheckBoxPreference.wrap(SourcePreference(
|
||||||
key: args[0]!.$value,
|
key: args[0]!.$value,
|
||||||
checkBoxPreference:
|
checkBoxPreference: CheckBoxPreference(
|
||||||
CheckBoxPreference(title: args[1]!.$value, summary: args[2]!.$value, value: args[3]!.$value)));
|
title: args[1]!.$value,
|
||||||
|
summary: args[2]!.$value,
|
||||||
|
value: args[3]!.$value)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
@ -78,10 +92,12 @@ class $CheckBoxPreference implements SourcePreference, $Instance {
|
||||||
ListPreference? get listPreference => $value.listPreference;
|
ListPreference? get listPreference => $value.listPreference;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
MultiSelectListPreference? get multiSelectListPreference => $value.multiSelectListPreference;
|
MultiSelectListPreference? get multiSelectListPreference =>
|
||||||
|
$value.multiSelectListPreference;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
SwitchPreferenceCompat? get switchPreferenceCompat => $value.switchPreferenceCompat;
|
SwitchPreferenceCompat? get switchPreferenceCompat =>
|
||||||
|
$value.switchPreferenceCompat;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Id? get id => $value.id;
|
Id? get id => $value.id;
|
||||||
|
|
@ -108,7 +124,8 @@ class $CheckBoxPreference implements SourcePreference, $Instance {
|
||||||
set listPreference(ListPreference? listPreference) {}
|
set listPreference(ListPreference? listPreference) {}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
set multiSelectListPreference(MultiSelectListPreference? multiSelectListPreference) {}
|
set multiSelectListPreference(
|
||||||
|
MultiSelectListPreference? multiSelectListPreference) {}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
set sourceId(int? sourceId) {}
|
set sourceId(int? sourceId) {}
|
||||||
|
|
@ -125,30 +142,44 @@ class $CheckBoxPreference implements SourcePreference, $Instance {
|
||||||
class $SwitchPreferenceCompat implements SourcePreference, $Instance {
|
class $SwitchPreferenceCompat implements SourcePreference, $Instance {
|
||||||
$SwitchPreferenceCompat.wrap(this.$value) : _superclass = $Object($value);
|
$SwitchPreferenceCompat.wrap(this.$value) : _superclass = $Object($value);
|
||||||
|
|
||||||
static const $type = BridgeTypeRef(BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'SwitchPreferenceCompat'));
|
static const $type = BridgeTypeRef(BridgeTypeSpec(
|
||||||
|
'package:mangayomi/bridge_lib.dart', 'SwitchPreferenceCompat'));
|
||||||
|
|
||||||
static const $declaration = BridgeClassDef(BridgeClassType($type),
|
static const $declaration = BridgeClassDef(BridgeClassType($type),
|
||||||
constructors: {
|
constructors: {
|
||||||
'': BridgeConstructorDef(BridgeFunctionDef(returns: BridgeTypeAnnotation($type), params: [], namedParams: [
|
'': BridgeConstructorDef(BridgeFunctionDef(
|
||||||
BridgeParameter('key', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
returns: BridgeTypeAnnotation($type),
|
||||||
BridgeParameter('title', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
params: [],
|
||||||
BridgeParameter('summary', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
namedParams: [
|
||||||
BridgeParameter('value', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.bool)), false),
|
BridgeParameter('key',
|
||||||
]))
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
||||||
|
BridgeParameter('title',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
||||||
|
BridgeParameter('summary',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
||||||
|
BridgeParameter('value',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.bool)), false),
|
||||||
|
]))
|
||||||
},
|
},
|
||||||
fields: {
|
fields: {
|
||||||
'key': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
'key': BridgeFieldDef(
|
||||||
'title': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
||||||
'summary': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
'title': BridgeFieldDef(
|
||||||
'value': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.bool))),
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
||||||
|
'summary': BridgeFieldDef(
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
||||||
|
'value':
|
||||||
|
BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.bool))),
|
||||||
},
|
},
|
||||||
wrap: true);
|
wrap: true);
|
||||||
|
|
||||||
static $Value? $new(Runtime runtime, $Value? target, List<$Value?> args) {
|
static $Value? $new(Runtime runtime, $Value? target, List<$Value?> args) {
|
||||||
return $SwitchPreferenceCompat.wrap(SourcePreference(
|
return $SwitchPreferenceCompat.wrap(SourcePreference(
|
||||||
key: args[0]!.$value,
|
key: args[0]!.$value,
|
||||||
switchPreferenceCompat:
|
switchPreferenceCompat: SwitchPreferenceCompat(
|
||||||
SwitchPreferenceCompat(title: args[1]!.$value, summary: args[2]!.$value, value: args[3]!.$value)));
|
title: args[1]!.$value,
|
||||||
|
summary: args[2]!.$value,
|
||||||
|
value: args[3]!.$value)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
@ -197,10 +228,12 @@ class $SwitchPreferenceCompat implements SourcePreference, $Instance {
|
||||||
ListPreference? get listPreference => $value.listPreference;
|
ListPreference? get listPreference => $value.listPreference;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
MultiSelectListPreference? get multiSelectListPreference => $value.multiSelectListPreference;
|
MultiSelectListPreference? get multiSelectListPreference =>
|
||||||
|
$value.multiSelectListPreference;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
SwitchPreferenceCompat? get switchPreferenceCompat => $value.switchPreferenceCompat;
|
SwitchPreferenceCompat? get switchPreferenceCompat =>
|
||||||
|
$value.switchPreferenceCompat;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Id? get id => $value.id;
|
Id? get id => $value.id;
|
||||||
|
|
@ -227,7 +260,8 @@ class $SwitchPreferenceCompat implements SourcePreference, $Instance {
|
||||||
set listPreference(ListPreference? listPreference) {}
|
set listPreference(ListPreference? listPreference) {}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
set multiSelectListPreference(MultiSelectListPreference? multiSelectListPreference) {}
|
set multiSelectListPreference(
|
||||||
|
MultiSelectListPreference? multiSelectListPreference) {}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
set sourceId(int? sourceId) {}
|
set sourceId(int? sourceId) {}
|
||||||
|
|
@ -244,30 +278,48 @@ class $SwitchPreferenceCompat implements SourcePreference, $Instance {
|
||||||
class $ListPreference implements SourcePreference, $Instance {
|
class $ListPreference implements SourcePreference, $Instance {
|
||||||
$ListPreference.wrap(this.$value) : _superclass = $Object($value);
|
$ListPreference.wrap(this.$value) : _superclass = $Object($value);
|
||||||
|
|
||||||
static const $type = BridgeTypeRef(BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'ListPreference'));
|
static const $type = BridgeTypeRef(
|
||||||
|
BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'ListPreference'));
|
||||||
|
|
||||||
static const $declaration = BridgeClassDef(BridgeClassType($type),
|
static const $declaration = BridgeClassDef(BridgeClassType($type),
|
||||||
constructors: {
|
constructors: {
|
||||||
'': BridgeConstructorDef(BridgeFunctionDef(returns: BridgeTypeAnnotation($type), params: [], namedParams: [
|
'': BridgeConstructorDef(BridgeFunctionDef(
|
||||||
BridgeParameter('key', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
returns: BridgeTypeAnnotation($type),
|
||||||
BridgeParameter('title', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
params: [],
|
||||||
BridgeParameter('summary', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
namedParams: [
|
||||||
BridgeParameter('valueIndex', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.int)), false),
|
BridgeParameter('key',
|
||||||
BridgeParameter(
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
||||||
'entries', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.list, [BridgeTypeRef(CoreTypes.string)])), false),
|
BridgeParameter('title',
|
||||||
BridgeParameter('entryValues',
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
||||||
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.list, [BridgeTypeRef(CoreTypes.string)])), false),
|
BridgeParameter('summary',
|
||||||
]))
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
||||||
|
BridgeParameter('valueIndex',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.int)), false),
|
||||||
|
BridgeParameter(
|
||||||
|
'entries',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(
|
||||||
|
CoreTypes.list, [BridgeTypeRef(CoreTypes.string)])),
|
||||||
|
false),
|
||||||
|
BridgeParameter(
|
||||||
|
'entryValues',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(
|
||||||
|
CoreTypes.list, [BridgeTypeRef(CoreTypes.string)])),
|
||||||
|
false),
|
||||||
|
]))
|
||||||
},
|
},
|
||||||
fields: {
|
fields: {
|
||||||
'key': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
'key': BridgeFieldDef(
|
||||||
'title': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
||||||
'summary': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
'title': BridgeFieldDef(
|
||||||
'valueIndex': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.int))),
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
||||||
'entries':
|
'summary': BridgeFieldDef(
|
||||||
BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.list, [BridgeTypeRef(CoreTypes.string)]))),
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
||||||
'entryValues':
|
'valueIndex':
|
||||||
BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.list, [BridgeTypeRef(CoreTypes.string)]))),
|
BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.int))),
|
||||||
|
'entries': BridgeFieldDef(BridgeTypeAnnotation(
|
||||||
|
BridgeTypeRef(CoreTypes.list, [BridgeTypeRef(CoreTypes.string)]))),
|
||||||
|
'entryValues': BridgeFieldDef(BridgeTypeAnnotation(
|
||||||
|
BridgeTypeRef(CoreTypes.list, [BridgeTypeRef(CoreTypes.string)]))),
|
||||||
},
|
},
|
||||||
wrap: true);
|
wrap: true);
|
||||||
|
|
||||||
|
|
@ -278,8 +330,12 @@ class $ListPreference implements SourcePreference, $Instance {
|
||||||
title: args[1]!.$value,
|
title: args[1]!.$value,
|
||||||
summary: args[2]!.$value,
|
summary: args[2]!.$value,
|
||||||
valueIndex: args[3]!.$value,
|
valueIndex: args[3]!.$value,
|
||||||
entries: (args[4]!.$value as List).map((e) => (e is $Value ? e.$reified : e).toString()).toList(),
|
entries: (args[4]!.$value as List)
|
||||||
entryValues: (args[5]!.$value as List).map((e) => (e is $Value ? e.$reified : e).toString()).toList())));
|
.map((e) => (e is $Value ? e.$reified : e).toString())
|
||||||
|
.toList(),
|
||||||
|
entryValues: (args[5]!.$value as List)
|
||||||
|
.map((e) => (e is $Value ? e.$reified : e).toString())
|
||||||
|
.toList())));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
@ -332,10 +388,12 @@ class $ListPreference implements SourcePreference, $Instance {
|
||||||
ListPreference? get listPreference => $value.listPreference;
|
ListPreference? get listPreference => $value.listPreference;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
MultiSelectListPreference? get multiSelectListPreference => $value.multiSelectListPreference;
|
MultiSelectListPreference? get multiSelectListPreference =>
|
||||||
|
$value.multiSelectListPreference;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
SwitchPreferenceCompat? get switchPreferenceCompat => $value.switchPreferenceCompat;
|
SwitchPreferenceCompat? get switchPreferenceCompat =>
|
||||||
|
$value.switchPreferenceCompat;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Id? get id => $value.id;
|
Id? get id => $value.id;
|
||||||
|
|
@ -362,7 +420,8 @@ class $ListPreference implements SourcePreference, $Instance {
|
||||||
set listPreference(ListPreference? listPreference) {}
|
set listPreference(ListPreference? listPreference) {}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
set multiSelectListPreference(MultiSelectListPreference? multiSelectListPreference) {}
|
set multiSelectListPreference(
|
||||||
|
MultiSelectListPreference? multiSelectListPreference) {}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
set sourceId(int? sourceId) {}
|
set sourceId(int? sourceId) {}
|
||||||
|
|
@ -379,32 +438,51 @@ class $ListPreference implements SourcePreference, $Instance {
|
||||||
class $MultiSelectListPreference implements SourcePreference, $Instance {
|
class $MultiSelectListPreference implements SourcePreference, $Instance {
|
||||||
$MultiSelectListPreference.wrap(this.$value) : _superclass = $Object($value);
|
$MultiSelectListPreference.wrap(this.$value) : _superclass = $Object($value);
|
||||||
|
|
||||||
static const $type = BridgeTypeRef(BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'MultiSelectListPreference'));
|
static const $type = BridgeTypeRef(BridgeTypeSpec(
|
||||||
|
'package:mangayomi/bridge_lib.dart', 'MultiSelectListPreference'));
|
||||||
|
|
||||||
static const $declaration = BridgeClassDef(BridgeClassType($type),
|
static const $declaration = BridgeClassDef(BridgeClassType($type),
|
||||||
constructors: {
|
constructors: {
|
||||||
'': BridgeConstructorDef(BridgeFunctionDef(returns: BridgeTypeAnnotation($type), params: [], namedParams: [
|
'': BridgeConstructorDef(BridgeFunctionDef(
|
||||||
BridgeParameter('key', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
returns: BridgeTypeAnnotation($type),
|
||||||
BridgeParameter('title', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
params: [],
|
||||||
BridgeParameter('summary', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
namedParams: [
|
||||||
BridgeParameter(
|
BridgeParameter('key',
|
||||||
'entries', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.list, [BridgeTypeRef(CoreTypes.string)])), false),
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
||||||
BridgeParameter('entryValues',
|
BridgeParameter('title',
|
||||||
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.list, [BridgeTypeRef(CoreTypes.string)])), false),
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
||||||
BridgeParameter(
|
BridgeParameter('summary',
|
||||||
'values', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.list, [BridgeTypeRef(CoreTypes.string)])), false),
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
||||||
]))
|
BridgeParameter(
|
||||||
|
'entries',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(
|
||||||
|
CoreTypes.list, [BridgeTypeRef(CoreTypes.string)])),
|
||||||
|
false),
|
||||||
|
BridgeParameter(
|
||||||
|
'entryValues',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(
|
||||||
|
CoreTypes.list, [BridgeTypeRef(CoreTypes.string)])),
|
||||||
|
false),
|
||||||
|
BridgeParameter(
|
||||||
|
'values',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(
|
||||||
|
CoreTypes.list, [BridgeTypeRef(CoreTypes.string)])),
|
||||||
|
false),
|
||||||
|
]))
|
||||||
},
|
},
|
||||||
fields: {
|
fields: {
|
||||||
'key': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
'key': BridgeFieldDef(
|
||||||
'title': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
||||||
'summary': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
'title': BridgeFieldDef(
|
||||||
'entries':
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
||||||
BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.list, [BridgeTypeRef(CoreTypes.string)]))),
|
'summary': BridgeFieldDef(
|
||||||
'entryValues':
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
||||||
BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.list, [BridgeTypeRef(CoreTypes.string)]))),
|
'entries': BridgeFieldDef(BridgeTypeAnnotation(
|
||||||
'values':
|
BridgeTypeRef(CoreTypes.list, [BridgeTypeRef(CoreTypes.string)]))),
|
||||||
BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.list, [BridgeTypeRef(CoreTypes.string)]))),
|
'entryValues': BridgeFieldDef(BridgeTypeAnnotation(
|
||||||
|
BridgeTypeRef(CoreTypes.list, [BridgeTypeRef(CoreTypes.string)]))),
|
||||||
|
'values': BridgeFieldDef(BridgeTypeAnnotation(
|
||||||
|
BridgeTypeRef(CoreTypes.list, [BridgeTypeRef(CoreTypes.string)]))),
|
||||||
},
|
},
|
||||||
wrap: true);
|
wrap: true);
|
||||||
|
|
||||||
|
|
@ -414,9 +492,15 @@ class $MultiSelectListPreference implements SourcePreference, $Instance {
|
||||||
multiSelectListPreference: MultiSelectListPreference(
|
multiSelectListPreference: MultiSelectListPreference(
|
||||||
title: args[1]!.$value,
|
title: args[1]!.$value,
|
||||||
summary: args[2]!.$value,
|
summary: args[2]!.$value,
|
||||||
entries: (args[3]!.$value as List).map((e) => (e is $Value ? e.$reified : e).toString()).toList(),
|
entries: (args[3]!.$value as List)
|
||||||
entryValues: (args[4]!.$value as List).map((e) => (e is $Value ? e.$reified : e).toString()).toList(),
|
.map((e) => (e is $Value ? e.$reified : e).toString())
|
||||||
values: (args[5]!.$value as List).map((e) => (e is $Value ? e.$reified : e).toString()).toList())));
|
.toList(),
|
||||||
|
entryValues: (args[4]!.$value as List)
|
||||||
|
.map((e) => (e is $Value ? e.$reified : e).toString())
|
||||||
|
.toList(),
|
||||||
|
values: (args[5]!.$value as List)
|
||||||
|
.map((e) => (e is $Value ? e.$reified : e).toString())
|
||||||
|
.toList())));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
@ -469,10 +553,12 @@ class $MultiSelectListPreference implements SourcePreference, $Instance {
|
||||||
ListPreference? get listPreference => $value.listPreference;
|
ListPreference? get listPreference => $value.listPreference;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
MultiSelectListPreference? get multiSelectListPreference => $value.multiSelectListPreference;
|
MultiSelectListPreference? get multiSelectListPreference =>
|
||||||
|
$value.multiSelectListPreference;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
SwitchPreferenceCompat? get switchPreferenceCompat => $value.switchPreferenceCompat;
|
SwitchPreferenceCompat? get switchPreferenceCompat =>
|
||||||
|
$value.switchPreferenceCompat;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Id? get id => $value.id;
|
Id? get id => $value.id;
|
||||||
|
|
@ -499,7 +585,8 @@ class $MultiSelectListPreference implements SourcePreference, $Instance {
|
||||||
set listPreference(ListPreference? listPreference) {}
|
set listPreference(ListPreference? listPreference) {}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
set multiSelectListPreference(MultiSelectListPreference? multiSelectListPreference) {}
|
set multiSelectListPreference(
|
||||||
|
MultiSelectListPreference? multiSelectListPreference) {}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
set sourceId(int? sourceId) {}
|
set sourceId(int? sourceId) {}
|
||||||
|
|
@ -516,28 +603,46 @@ class $MultiSelectListPreference implements SourcePreference, $Instance {
|
||||||
class $EditTextPreference implements SourcePreference, $Instance {
|
class $EditTextPreference implements SourcePreference, $Instance {
|
||||||
$EditTextPreference.wrap(this.$value) : _superclass = $Object($value);
|
$EditTextPreference.wrap(this.$value) : _superclass = $Object($value);
|
||||||
|
|
||||||
static const $type = BridgeTypeRef(BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'EditTextPreference'));
|
static const $type = BridgeTypeRef(BridgeTypeSpec(
|
||||||
|
'package:mangayomi/bridge_lib.dart', 'EditTextPreference'));
|
||||||
|
|
||||||
static const $declaration = BridgeClassDef(BridgeClassType($type),
|
static const $declaration = BridgeClassDef(BridgeClassType($type),
|
||||||
constructors: {
|
constructors: {
|
||||||
'': BridgeConstructorDef(BridgeFunctionDef(returns: BridgeTypeAnnotation($type), params: [], namedParams: [
|
'': BridgeConstructorDef(BridgeFunctionDef(
|
||||||
BridgeParameter('key', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
returns: BridgeTypeAnnotation($type),
|
||||||
BridgeParameter('title', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
params: [],
|
||||||
BridgeParameter('summary', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
namedParams: [
|
||||||
BridgeParameter('value', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
BridgeParameter('key',
|
||||||
BridgeParameter('dialogTitle', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
||||||
BridgeParameter('dialogMessage', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
BridgeParameter('title',
|
||||||
BridgeParameter('text', BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
||||||
]))
|
BridgeParameter('summary',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
||||||
|
BridgeParameter('value',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
||||||
|
BridgeParameter('dialogTitle',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
||||||
|
BridgeParameter('dialogMessage',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
||||||
|
BridgeParameter('text',
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), false),
|
||||||
|
]))
|
||||||
},
|
},
|
||||||
fields: {
|
fields: {
|
||||||
'key': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
'key': BridgeFieldDef(
|
||||||
'title': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
||||||
'summary': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
'title': BridgeFieldDef(
|
||||||
'value': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
||||||
'dialogTitle': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
'summary': BridgeFieldDef(
|
||||||
'dialogMessage': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
||||||
'text': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
'value': BridgeFieldDef(
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
||||||
|
'dialogTitle': BridgeFieldDef(
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
||||||
|
'dialogMessage': BridgeFieldDef(
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
||||||
|
'text': BridgeFieldDef(
|
||||||
|
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string))),
|
||||||
},
|
},
|
||||||
wrap: true);
|
wrap: true);
|
||||||
|
|
||||||
|
|
@ -605,10 +710,12 @@ class $EditTextPreference implements SourcePreference, $Instance {
|
||||||
ListPreference? get listPreference => $value.listPreference;
|
ListPreference? get listPreference => $value.listPreference;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
MultiSelectListPreference? get multiSelectListPreference => $value.multiSelectListPreference;
|
MultiSelectListPreference? get multiSelectListPreference =>
|
||||||
|
$value.multiSelectListPreference;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
SwitchPreferenceCompat? get switchPreferenceCompat => $value.switchPreferenceCompat;
|
SwitchPreferenceCompat? get switchPreferenceCompat =>
|
||||||
|
$value.switchPreferenceCompat;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Id? get id => $value.id;
|
Id? get id => $value.id;
|
||||||
|
|
@ -635,7 +742,8 @@ class $EditTextPreference implements SourcePreference, $Instance {
|
||||||
set listPreference(ListPreference? listPreference) {}
|
set listPreference(ListPreference? listPreference) {}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
set multiSelectListPreference(MultiSelectListPreference? multiSelectListPreference) {}
|
set multiSelectListPreference(
|
||||||
|
MultiSelectListPreference? multiSelectListPreference) {}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
set sourceId(int? sourceId) {}
|
set sourceId(int? sourceId) {}
|
||||||
|
|
|
||||||
|
|
@ -61,39 +61,64 @@ class MEvalPlugin extends EvalPlugin {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void configureForRuntime(Runtime runtime) {
|
void configureForRuntime(Runtime runtime) {
|
||||||
runtime.registerBridgeFunc('package:mangayomi/bridge_lib.dart', 'MProvider.', $MProvider.$construct,
|
runtime.registerBridgeFunc('package:mangayomi/bridge_lib.dart',
|
||||||
|
'MProvider.', $MProvider.$construct,
|
||||||
isBridge: true);
|
isBridge: true);
|
||||||
runtime.registerBridgeFunc('package:mangayomi/bridge_lib.dart', 'MChapter.', $MChapter.$new);
|
runtime.registerBridgeFunc(
|
||||||
runtime.registerBridgeFunc('package:mangayomi/bridge_lib.dart', 'MManga.', $MManga.$new);
|
'package:mangayomi/bridge_lib.dart', 'MChapter.', $MChapter.$new);
|
||||||
runtime.registerBridgeFunc('package:mangayomi/bridge_lib.dart', 'MPages.', $MPages.$new);
|
runtime.registerBridgeFunc(
|
||||||
runtime.registerBridgeFunc('package:mangayomi/bridge_lib.dart', 'MSource.', $MSource.$new);
|
'package:mangayomi/bridge_lib.dart', 'MManga.', $MManga.$new);
|
||||||
runtime.registerBridgeFunc('package:mangayomi/bridge_lib.dart', 'MVideo.', $MVideo.$new);
|
runtime.registerBridgeFunc(
|
||||||
runtime.registerBridgeFunc('package:mangayomi/bridge_lib.dart', 'MTrack.', $MTrack.$new);
|
'package:mangayomi/bridge_lib.dart', 'MPages.', $MPages.$new);
|
||||||
runtime.registerBridgeEnumValues('package:mangayomi/bridge_lib.dart', 'MStatus', $MStatus.$values);
|
runtime.registerBridgeFunc(
|
||||||
|
'package:mangayomi/bridge_lib.dart', 'MSource.', $MSource.$new);
|
||||||
|
runtime.registerBridgeFunc(
|
||||||
|
'package:mangayomi/bridge_lib.dart', 'MVideo.', $MVideo.$new);
|
||||||
|
runtime.registerBridgeFunc(
|
||||||
|
'package:mangayomi/bridge_lib.dart', 'MTrack.', $MTrack.$new);
|
||||||
|
runtime.registerBridgeEnumValues(
|
||||||
|
'package:mangayomi/bridge_lib.dart', 'MStatus', $MStatus.$values);
|
||||||
//Filter
|
//Filter
|
||||||
runtime.registerBridgeFunc('package:mangayomi/bridge_lib.dart', 'FilterList.', $FilterList.$new);
|
runtime.registerBridgeFunc(
|
||||||
runtime.registerBridgeFunc('package:mangayomi/bridge_lib.dart', 'SelectFilter.', $SelectFilter.$new);
|
'package:mangayomi/bridge_lib.dart', 'FilterList.', $FilterList.$new);
|
||||||
runtime.registerBridgeFunc('package:mangayomi/bridge_lib.dart', 'SeparatorFilter.', $SeparatorFilter.$new);
|
runtime.registerBridgeFunc('package:mangayomi/bridge_lib.dart',
|
||||||
runtime.registerBridgeFunc('package:mangayomi/bridge_lib.dart', 'HeaderFilter.', $HeaderFilter.$new);
|
'SelectFilter.', $SelectFilter.$new);
|
||||||
runtime.registerBridgeFunc('package:mangayomi/bridge_lib.dart', 'TextFilter.', $TextFilter.$new);
|
runtime.registerBridgeFunc('package:mangayomi/bridge_lib.dart',
|
||||||
runtime.registerBridgeFunc('package:mangayomi/bridge_lib.dart', 'SortFilter.', $SortFilter.$new);
|
'SeparatorFilter.', $SeparatorFilter.$new);
|
||||||
runtime.registerBridgeFunc('package:mangayomi/bridge_lib.dart', 'TriStateFilter.', $TriStateFilter.$new);
|
runtime.registerBridgeFunc('package:mangayomi/bridge_lib.dart',
|
||||||
runtime.registerBridgeFunc('package:mangayomi/bridge_lib.dart', 'GroupFilter.', $GroupFilter.$new);
|
'HeaderFilter.', $HeaderFilter.$new);
|
||||||
runtime.registerBridgeFunc('package:mangayomi/bridge_lib.dart', 'CheckBoxFilter.', $CheckBoxFilter.$new);
|
runtime.registerBridgeFunc(
|
||||||
runtime.registerBridgeFunc('package:mangayomi/bridge_lib.dart', 'SortState.', $SortState.$new);
|
'package:mangayomi/bridge_lib.dart', 'TextFilter.', $TextFilter.$new);
|
||||||
runtime.registerBridgeFunc('package:mangayomi/bridge_lib.dart', 'SelectFilterOption.', $SelectFilterOption.$new);
|
runtime.registerBridgeFunc(
|
||||||
|
'package:mangayomi/bridge_lib.dart', 'SortFilter.', $SortFilter.$new);
|
||||||
|
runtime.registerBridgeFunc('package:mangayomi/bridge_lib.dart',
|
||||||
|
'TriStateFilter.', $TriStateFilter.$new);
|
||||||
|
runtime.registerBridgeFunc(
|
||||||
|
'package:mangayomi/bridge_lib.dart', 'GroupFilter.', $GroupFilter.$new);
|
||||||
|
runtime.registerBridgeFunc('package:mangayomi/bridge_lib.dart',
|
||||||
|
'CheckBoxFilter.', $CheckBoxFilter.$new);
|
||||||
|
runtime.registerBridgeFunc(
|
||||||
|
'package:mangayomi/bridge_lib.dart', 'SortState.', $SortState.$new);
|
||||||
|
runtime.registerBridgeFunc('package:mangayomi/bridge_lib.dart',
|
||||||
|
'SelectFilterOption.', $SelectFilterOption.$new);
|
||||||
//Sources preferences
|
//Sources preferences
|
||||||
runtime.registerBridgeFunc('package:mangayomi/bridge_lib.dart', 'CheckBoxPreference.', $CheckBoxPreference.$new);
|
runtime.registerBridgeFunc('package:mangayomi/bridge_lib.dart',
|
||||||
runtime.registerBridgeFunc(
|
'CheckBoxPreference.', $CheckBoxPreference.$new);
|
||||||
'package:mangayomi/bridge_lib.dart', 'SwitchPreferenceCompat.', $SwitchPreferenceCompat.$new);
|
runtime.registerBridgeFunc('package:mangayomi/bridge_lib.dart',
|
||||||
runtime.registerBridgeFunc('package:mangayomi/bridge_lib.dart', 'ListPreference.', $ListPreference.$new);
|
'SwitchPreferenceCompat.', $SwitchPreferenceCompat.$new);
|
||||||
runtime.registerBridgeFunc(
|
runtime.registerBridgeFunc('package:mangayomi/bridge_lib.dart',
|
||||||
'package:mangayomi/bridge_lib.dart', 'MultiSelectListPreference.', $MultiSelectListPreference.$new);
|
'ListPreference.', $ListPreference.$new);
|
||||||
runtime.registerBridgeFunc('package:mangayomi/bridge_lib.dart', 'EditTextPreference.', $EditTextPreference.$new);
|
runtime.registerBridgeFunc('package:mangayomi/bridge_lib.dart',
|
||||||
|
'MultiSelectListPreference.', $MultiSelectListPreference.$new);
|
||||||
|
runtime.registerBridgeFunc('package:mangayomi/bridge_lib.dart',
|
||||||
|
'EditTextPreference.', $EditTextPreference.$new);
|
||||||
//DOM HTML
|
//DOM HTML
|
||||||
runtime.registerBridgeFunc('package:mangayomi/bridge_lib.dart', 'MElement.', $MElement.$new);
|
runtime.registerBridgeFunc(
|
||||||
runtime.registerBridgeFunc('package:mangayomi/bridge_lib.dart', 'MDocument.', $MDocument.$new);
|
'package:mangayomi/bridge_lib.dart', 'MElement.', $MElement.$new);
|
||||||
|
runtime.registerBridgeFunc(
|
||||||
|
'package:mangayomi/bridge_lib.dart', 'MDocument.', $MDocument.$new);
|
||||||
//HTTP CLIENT
|
//HTTP CLIENT
|
||||||
runtime.registerBridgeFunc('package:mangayomi/bridge_lib.dart', 'Client.', $Client.$new);
|
runtime.registerBridgeFunc(
|
||||||
|
'package:mangayomi/bridge_lib.dart', 'Client.', $Client.$new);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,8 @@ class DartExtensionService implements ExtensionService {
|
||||||
|
|
||||||
final runtime = runtimeEval(bytecode);
|
final runtime = runtimeEval(bytecode);
|
||||||
|
|
||||||
return runtime.executeLib('package:mangayomi/main.dart', 'main', [$MSource.wrap(source.toMSource())]) as MProvider;
|
return runtime.executeLib('package:mangayomi/main.dart', 'main',
|
||||||
|
[$MSource.wrap(source.toMSource())]) as MProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
@ -103,7 +104,9 @@ class DartExtensionService implements ExtensionService {
|
||||||
@override
|
@override
|
||||||
Future<List<PageUrl>> getPageList(String url) async {
|
Future<List<PageUrl>> getPageList(String url) async {
|
||||||
return (await _executeLib().getPageList(url))
|
return (await _executeLib().getPageList(url))
|
||||||
.map((e) => e is String ? PageUrl(e.toString().trim()) : PageUrl.fromJson((e as Map).toMapStringDynamic!))
|
.map((e) => e is String
|
||||||
|
? PageUrl(e.toString().trim())
|
||||||
|
: PageUrl.fromJson((e as Map).toMapStringDynamic!))
|
||||||
.toList();
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -117,7 +120,10 @@ class DartExtensionService implements ExtensionService {
|
||||||
List<dynamic> list;
|
List<dynamic> list;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
list = _executeLib().getFilterList().map((e) => e is $Value ? e.$reified : e).toList();
|
list = _executeLib()
|
||||||
|
.getFilterList()
|
||||||
|
.map((e) => e is $Value ? e.$reified : e)
|
||||||
|
.toList();
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
list = [];
|
list = [];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -67,8 +67,10 @@ class JsDomSelector {
|
||||||
final type = args[0];
|
final type = args[0];
|
||||||
final key = args[1];
|
final key = args[1];
|
||||||
final ele = _elements[key];
|
final ele = _elements[key];
|
||||||
final element =
|
final element = switch (type) {
|
||||||
switch (type) { 'nextElementSibling' => ele?.nextElementSibling, _ => ele?.previousElementSibling };
|
'nextElementSibling' => ele?.nextElementSibling,
|
||||||
|
_ => ele?.previousElementSibling
|
||||||
|
};
|
||||||
_elementKey++;
|
_elementKey++;
|
||||||
_elements[_elementKey] = element;
|
_elements[_elementKey] = element;
|
||||||
return _elementKey;
|
return _elementKey;
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,8 @@ class JsVideosExtractors {
|
||||||
|
|
||||||
void init() {
|
void init() {
|
||||||
runtime.onMessage('sibnetExtractor', (dynamic args) async {
|
runtime.onMessage('sibnetExtractor', (dynamic args) async {
|
||||||
return (await MBridge.sibnetExtractor(args[0], args[1] ?? "")).encodeToJson();
|
return (await MBridge.sibnetExtractor(args[0], args[1] ?? ""))
|
||||||
|
.encodeToJson();
|
||||||
});
|
});
|
||||||
runtime.onMessage('myTvExtractor', (dynamic args) async {
|
runtime.onMessage('myTvExtractor', (dynamic args) async {
|
||||||
return (await MBridge.myTvExtractor(args[0])).encodeToJson();
|
return (await MBridge.myTvExtractor(args[0])).encodeToJson();
|
||||||
|
|
@ -25,7 +26,8 @@ class JsVideosExtractors {
|
||||||
return (await MBridge.vidBomExtractor(args[0])).encodeToJson();
|
return (await MBridge.vidBomExtractor(args[0])).encodeToJson();
|
||||||
});
|
});
|
||||||
runtime.onMessage('quarkVideosExtractor', (dynamic args) async {
|
runtime.onMessage('quarkVideosExtractor', (dynamic args) async {
|
||||||
return (await MBridge.quarkVideosExtractor(args[0], args[1])).encodeToJson();
|
return (await MBridge.quarkVideosExtractor(args[0], args[1]))
|
||||||
|
.encodeToJson();
|
||||||
});
|
});
|
||||||
runtime.onMessage('ucVideosExtractor', (dynamic args) async {
|
runtime.onMessage('ucVideosExtractor', (dynamic args) async {
|
||||||
return (await MBridge.ucVideosExtractor(args[0], args[1])).encodeToJson();
|
return (await MBridge.ucVideosExtractor(args[0], args[1])).encodeToJson();
|
||||||
|
|
@ -39,16 +41,27 @@ class JsVideosExtractors {
|
||||||
return (await MBridge.ucFilesExtractor(urls, args[1]));
|
return (await MBridge.ucFilesExtractor(urls, args[1]));
|
||||||
});
|
});
|
||||||
runtime.onMessage('streamlareExtractor', (dynamic args) async {
|
runtime.onMessage('streamlareExtractor', (dynamic args) async {
|
||||||
return (await MBridge.streamlareExtractor(args[0], args[1] ?? "", args[2] ?? "")).encodeToJson();
|
return (await MBridge.streamlareExtractor(
|
||||||
|
args[0], args[1] ?? "", args[2] ?? ""))
|
||||||
|
.encodeToJson();
|
||||||
});
|
});
|
||||||
runtime.onMessage('sendVidExtractor', (dynamic args) async {
|
runtime.onMessage('sendVidExtractor', (dynamic args) async {
|
||||||
return (await MBridge.sendVidExtractor(
|
return (await MBridge.sendVidExtractor(
|
||||||
args[0], args[1] != null ? jsonEncode((args[1] as Map?).toMapStringString) : null, args[2] ?? ""))
|
args[0],
|
||||||
|
args[1] != null
|
||||||
|
? jsonEncode((args[1] as Map?).toMapStringString)
|
||||||
|
: null,
|
||||||
|
args[2] ?? ""))
|
||||||
.encodeToJson();
|
.encodeToJson();
|
||||||
});
|
});
|
||||||
runtime.onMessage('yourUploadExtractor', (dynamic args) async {
|
runtime.onMessage('yourUploadExtractor', (dynamic args) async {
|
||||||
return (await MBridge.yourUploadExtractor(args[0],
|
return (await MBridge.yourUploadExtractor(
|
||||||
args[1] != null ? jsonEncode((args[1] as Map?).toMapStringString) : null, args[2], args[3] ?? ""))
|
args[0],
|
||||||
|
args[1] != null
|
||||||
|
? jsonEncode((args[1] as Map?).toMapStringString)
|
||||||
|
: null,
|
||||||
|
args[2],
|
||||||
|
args[3] ?? ""))
|
||||||
.encodeToJson();
|
.encodeToJson();
|
||||||
});
|
});
|
||||||
runtime.onMessage('gogoCdnExtractor', (dynamic args) async {
|
runtime.onMessage('gogoCdnExtractor', (dynamic args) async {
|
||||||
|
|
@ -58,18 +71,27 @@ class JsVideosExtractors {
|
||||||
return (await MBridge.doodExtractor(args[0], args[1])).encodeToJson();
|
return (await MBridge.doodExtractor(args[0], args[1])).encodeToJson();
|
||||||
});
|
});
|
||||||
runtime.onMessage('streamTapeExtractor', (dynamic args) async {
|
runtime.onMessage('streamTapeExtractor', (dynamic args) async {
|
||||||
return (await MBridge.streamTapeExtractor(args[0], args[1])).encodeToJson();
|
return (await MBridge.streamTapeExtractor(args[0], args[1]))
|
||||||
|
.encodeToJson();
|
||||||
});
|
});
|
||||||
runtime.onMessage('mp4UploadExtractor', (dynamic args) async {
|
runtime.onMessage('mp4UploadExtractor', (dynamic args) async {
|
||||||
return (await MBridge.mp4UploadExtractor(args[0],
|
return (await MBridge.mp4UploadExtractor(
|
||||||
args[1] != null ? jsonEncode((args[1] as Map?).toMapStringString) : null, args[2] ?? "", args[3] ?? ""))
|
args[0],
|
||||||
|
args[1] != null
|
||||||
|
? jsonEncode((args[1] as Map?).toMapStringString)
|
||||||
|
: null,
|
||||||
|
args[2] ?? "",
|
||||||
|
args[3] ?? ""))
|
||||||
.encodeToJson();
|
.encodeToJson();
|
||||||
});
|
});
|
||||||
runtime.onMessage('streamWishExtractor', (dynamic args) async {
|
runtime.onMessage('streamWishExtractor', (dynamic args) async {
|
||||||
return (await MBridge.streamWishExtractor(args[0], args[1] ?? "")).encodeToJson();
|
return (await MBridge.streamWishExtractor(args[0], args[1] ?? ""))
|
||||||
|
.encodeToJson();
|
||||||
});
|
});
|
||||||
runtime.onMessage('filemoonExtractor', (dynamic args) async {
|
runtime.onMessage('filemoonExtractor', (dynamic args) async {
|
||||||
return (await MBridge.filemoonExtractor(args[0], args[1] ?? "", args[2] ?? "")).encodeToJson();
|
return (await MBridge.filemoonExtractor(
|
||||||
|
args[0], args[1] ?? "", args[2] ?? ""))
|
||||||
|
.encodeToJson();
|
||||||
});
|
});
|
||||||
|
|
||||||
runtime.evaluate('''
|
runtime.evaluate('''
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,8 @@ class JsHttpClient {
|
||||||
|
|
||||||
void init() {
|
void init() {
|
||||||
InterceptedClient client(dynamic reqcopyWith) {
|
InterceptedClient client(dynamic reqcopyWith) {
|
||||||
return MClient.init(reqcopyWith: (reqcopyWith as Map?)?.toMapStringDynamic);
|
return MClient.init(
|
||||||
|
reqcopyWith: (reqcopyWith as Map?)?.toMapStringDynamic);
|
||||||
}
|
}
|
||||||
|
|
||||||
runtime.onMessage('http_get', (dynamic args) async {
|
runtime.onMessage('http_get', (dynamic args) async {
|
||||||
|
|
@ -85,7 +86,9 @@ Future<String> _toHttpResponse(Client client, String method, List args) async {
|
||||||
final body = args.length >= 5 ? (args[4] as Map?)?.toMapStringDynamic : null;
|
final body = args.length >= 5 ? (args[4] as Map?)?.toMapStringDynamic : null;
|
||||||
var request = http.Request(method, Uri.parse(url));
|
var request = http.Request(method, Uri.parse(url));
|
||||||
request.headers.addAll(headers ?? {});
|
request.headers.addAll(headers ?? {});
|
||||||
if ((request.headers[HttpHeaders.contentTypeHeader]?.contains("application/json")) ?? false) {
|
if ((request.headers[HttpHeaders.contentTypeHeader]
|
||||||
|
?.contains("application/json")) ??
|
||||||
|
false) {
|
||||||
request.body = json.encode(body);
|
request.body = json.encode(body);
|
||||||
request.headers.addAll(headers ?? {});
|
request.headers.addAll(headers ?? {});
|
||||||
http.StreamedResponse response = await client.send(request);
|
http.StreamedResponse response = await client.send(request);
|
||||||
|
|
@ -136,6 +139,7 @@ extension ToMapExtension on Map? {
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, String>? get toMapStringString {
|
Map<String, String>? get toMapStringString {
|
||||||
return this?.map((key, value) => MapEntry(key.toString(), value.toString()));
|
return this
|
||||||
|
?.map((key, value) => MapEntry(key.toString(), value.toString()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,8 @@ var extention = new DefaultExtension();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Map<String, String> getHeaders() {
|
Map<String, String> getHeaders() {
|
||||||
return _extensionCall<Map>('getHeaders(`${source.baseUrl ?? ''}`)', {}).toMapStringString!;
|
return _extensionCall<Map>('getHeaders(`${source.baseUrl ?? ''}`)', {})
|
||||||
|
.toMapStringString!;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
@ -98,13 +99,15 @@ var extention = new DefaultExtension();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<MPages> getLatestUpdates(int page) async {
|
Future<MPages> getLatestUpdates(int page) async {
|
||||||
return MPages.fromJson(await _extensionCallAsync('getLatestUpdates($page)', {}));
|
return MPages.fromJson(
|
||||||
|
await _extensionCallAsync('getLatestUpdates($page)', {}));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<MPages> search(String query, int page, List<dynamic> filters) async {
|
Future<MPages> search(String query, int page, List<dynamic> filters) async {
|
||||||
return MPages.fromJson(
|
return MPages.fromJson(await _extensionCallAsync(
|
||||||
await _extensionCallAsync('search("$query",$page,${jsonEncode(filterValuesListToJson(filters))})', {}));
|
'search("$query",$page,${jsonEncode(filterValuesListToJson(filters))})',
|
||||||
|
{}));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
@ -115,14 +118,17 @@ var extention = new DefaultExtension();
|
||||||
@override
|
@override
|
||||||
Future<List<PageUrl>> getPageList(String url) async {
|
Future<List<PageUrl>> getPageList(String url) async {
|
||||||
return (await _extensionCallAsync<List>('getPageList(`$url`)', []))
|
return (await _extensionCallAsync<List>('getPageList(`$url`)', []))
|
||||||
.map((e) => e is String ? PageUrl(e.trim()) : PageUrl.fromJson((e as Map).toMapStringDynamic!))
|
.map((e) => e is String
|
||||||
|
? PageUrl(e.trim())
|
||||||
|
: PageUrl.fromJson((e as Map).toMapStringDynamic!))
|
||||||
.toList();
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List<Video>> getVideoList(String url) async {
|
Future<List<Video>> getVideoList(String url) async {
|
||||||
return (await _extensionCallAsync<List>('getVideoList(`$url`)', []))
|
return (await _extensionCallAsync<List>('getVideoList(`$url`)', []))
|
||||||
.where((element) => element['url'] != null && element['originalUrl'] != null)
|
.where((element) =>
|
||||||
|
element['url'] != null && element['originalUrl'] != null)
|
||||||
.map((e) => Video.fromJson(e))
|
.map((e) => Video.fromJson(e))
|
||||||
.toList()
|
.toList()
|
||||||
.toSet()
|
.toSet()
|
||||||
|
|
@ -149,12 +155,11 @@ var extention = new DefaultExtension();
|
||||||
.toList();
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
T _extensionCall<T>(String call, T def) {
|
T _extensionCall<T>(String call, T def) {
|
||||||
_init();
|
_init();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final res = runtime.evaluate('JSON.stringify(extention.`$call`)');
|
final res = runtime.evaluate('JSON.stringify(extention.$call)');
|
||||||
|
|
||||||
return jsonDecode(res.stringResult) as T;
|
return jsonDecode(res.stringResult) as T;
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
|
|
@ -170,7 +175,8 @@ var extention = new DefaultExtension();
|
||||||
_init();
|
_init();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final promised = await runtime.handlePromise(await runtime.evaluateAsync('jsonStringify(() => extention.$call)'));
|
final promised = await runtime.handlePromise(
|
||||||
|
await runtime.evaluateAsync('jsonStringify(() => extention.$call)'));
|
||||||
|
|
||||||
return jsonDecode(promised.stringResult) as T;
|
return jsonDecode(promised.stringResult) as T;
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,8 @@ class MDocument {
|
||||||
|
|
||||||
String? get text => _document?.text;
|
String? get text => _document?.text;
|
||||||
|
|
||||||
List<MElement>? get children => _document?.children.map((e) => MElement(e)).toList();
|
List<MElement>? get children =>
|
||||||
|
_document?.children.map((e) => MElement(e)).toList();
|
||||||
|
|
||||||
List<MElement>? select(String selector) {
|
List<MElement>? select(String selector) {
|
||||||
return _document?.select(selector)?.map((e) => MElement(e)).toList();
|
return _document?.select(selector)?.map((e) => MElement(e)).toList();
|
||||||
|
|
@ -34,11 +35,17 @@ class MDocument {
|
||||||
}
|
}
|
||||||
|
|
||||||
List<MElement>? getElementsByClassName(String classNames) {
|
List<MElement>? getElementsByClassName(String classNames) {
|
||||||
return _document?.getElementsByClassName(classNames).map((e) => MElement(e)).toList();
|
return _document
|
||||||
|
?.getElementsByClassName(classNames)
|
||||||
|
.map((e) => MElement(e))
|
||||||
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
List<MElement>? getElementsByTagName(String localNames) {
|
List<MElement>? getElementsByTagName(String localNames) {
|
||||||
return _document?.getElementsByTagName(localNames).map((e) => MElement(e)).toList();
|
return _document
|
||||||
|
?.getElementsByTagName(localNames)
|
||||||
|
.map((e) => MElement(e))
|
||||||
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
MElement? getElementById(String id) {
|
MElement? getElementById(String id) {
|
||||||
|
|
|
||||||
|
|
@ -26,13 +26,15 @@ class MElement {
|
||||||
|
|
||||||
String? get getDataSrc => _element?.getDataSrc;
|
String? get getDataSrc => _element?.getDataSrc;
|
||||||
|
|
||||||
List<MElement>? get children => _element?.children.map((e) => MElement(e)).toList();
|
List<MElement>? get children =>
|
||||||
|
_element?.children.map((e) => MElement(e)).toList();
|
||||||
|
|
||||||
MElement? get parent => MElement(_element?.parent);
|
MElement? get parent => MElement(_element?.parent);
|
||||||
|
|
||||||
MElement? get nextElementSibling => MElement(_element?.nextElementSibling);
|
MElement? get nextElementSibling => MElement(_element?.nextElementSibling);
|
||||||
|
|
||||||
MElement? get previousElementSibling => MElement(_element?.previousElementSibling);
|
MElement? get previousElementSibling =>
|
||||||
|
MElement(_element?.previousElementSibling);
|
||||||
|
|
||||||
String? xpathFirst(String xpath) {
|
String? xpathFirst(String xpath) {
|
||||||
return _element?.outerHtml == null ? null : _element?.xpathFirst(xpath);
|
return _element?.outerHtml == null ? null : _element?.xpathFirst(xpath);
|
||||||
|
|
@ -43,11 +45,17 @@ class MElement {
|
||||||
}
|
}
|
||||||
|
|
||||||
List<MElement>? getElementsByClassName(String classNames) {
|
List<MElement>? getElementsByClassName(String classNames) {
|
||||||
return _element?.getElementsByClassName(classNames).map((e) => MElement(e)).toList();
|
return _element
|
||||||
|
?.getElementsByClassName(classNames)
|
||||||
|
.map((e) => MElement(e))
|
||||||
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
List<MElement>? getElementsByTagName(String localNames) {
|
List<MElement>? getElementsByTagName(String localNames) {
|
||||||
return _element?.getElementsByTagName(localNames).map((e) => MElement(e)).toList();
|
return _element
|
||||||
|
?.getElementsByTagName(localNames)
|
||||||
|
.map((e) => MElement(e))
|
||||||
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
List<MElement>? select(String selector) {
|
List<MElement>? select(String selector) {
|
||||||
|
|
|
||||||
|
|
@ -18,8 +18,8 @@ class SelectFilter {
|
||||||
|
|
||||||
SelectFilter(this.type, this.name, this.state, this.values, this.typeName);
|
SelectFilter(this.type, this.name, this.state, this.values, this.typeName);
|
||||||
factory SelectFilter.fromJson(Map<String, dynamic> json) {
|
factory SelectFilter.fromJson(Map<String, dynamic> json) {
|
||||||
return SelectFilter(
|
return SelectFilter(json['type'], json['name'], json['state'] ?? 0,
|
||||||
json['type'], json['name'], json['state'] ?? 0, fromJsonFilterValuesToList(json['values']), json['type_name']);
|
fromJsonFilterValuesToList(json['values']), json['type_name']);
|
||||||
}
|
}
|
||||||
Map<String, dynamic> toJson() => {
|
Map<String, dynamic> toJson() => {
|
||||||
'type': type,
|
'type': type,
|
||||||
|
|
@ -39,7 +39,8 @@ class SelectFilterOption {
|
||||||
factory SelectFilterOption.fromJson(Map<String, dynamic> json) {
|
factory SelectFilterOption.fromJson(Map<String, dynamic> json) {
|
||||||
return SelectFilterOption(json['name'], json['value'], json['type_name']);
|
return SelectFilterOption(json['name'], json['value'], json['type_name']);
|
||||||
}
|
}
|
||||||
Map<String, dynamic> toJson() => {'value': value, 'name': name, 'type_name': "SelectOption"};
|
Map<String, dynamic> toJson() =>
|
||||||
|
{'value': value, 'name': name, 'type_name': "SelectOption"};
|
||||||
}
|
}
|
||||||
|
|
||||||
class SeparatorFilter {
|
class SeparatorFilter {
|
||||||
|
|
@ -49,7 +50,8 @@ class SeparatorFilter {
|
||||||
factory SeparatorFilter.fromJson(Map<String, dynamic> json) {
|
factory SeparatorFilter.fromJson(Map<String, dynamic> json) {
|
||||||
return SeparatorFilter(type: json['type'], json['type_name']);
|
return SeparatorFilter(type: json['type'], json['type_name']);
|
||||||
}
|
}
|
||||||
Map<String, dynamic> toJson() => {'type': type, 'type_name': "SeparatorFilter"};
|
Map<String, dynamic> toJson() =>
|
||||||
|
{'type': type, 'type_name': "SeparatorFilter"};
|
||||||
}
|
}
|
||||||
|
|
||||||
class HeaderFilter {
|
class HeaderFilter {
|
||||||
|
|
@ -60,7 +62,8 @@ class HeaderFilter {
|
||||||
factory HeaderFilter.fromJson(Map<String, dynamic> json) {
|
factory HeaderFilter.fromJson(Map<String, dynamic> json) {
|
||||||
return HeaderFilter(json['name'], json['type_name'], type: json['value']);
|
return HeaderFilter(json['name'], json['type_name'], type: json['value']);
|
||||||
}
|
}
|
||||||
Map<String, dynamic> toJson() => {'type': type, 'name': name, 'type_name': "HeaderFilter"};
|
Map<String, dynamic> toJson() =>
|
||||||
|
{'type': type, 'name': name, 'type_name': "HeaderFilter"};
|
||||||
}
|
}
|
||||||
|
|
||||||
class TextFilter {
|
class TextFilter {
|
||||||
|
|
@ -71,9 +74,11 @@ class TextFilter {
|
||||||
|
|
||||||
TextFilter(this.type, this.name, this.typeName, {this.state = ""});
|
TextFilter(this.type, this.name, this.typeName, {this.state = ""});
|
||||||
factory TextFilter.fromJson(Map<String, dynamic> json) {
|
factory TextFilter.fromJson(Map<String, dynamic> json) {
|
||||||
return TextFilter(json['type'], json['name'], json['type_name'], state: json['state'] ?? "");
|
return TextFilter(json['type'], json['name'], json['type_name'],
|
||||||
|
state: json['state'] ?? "");
|
||||||
}
|
}
|
||||||
Map<String, dynamic> toJson() => {'type': type, 'name': name, 'state': state, 'type_name': "TextFilter"};
|
Map<String, dynamic> toJson() =>
|
||||||
|
{'type': type, 'name': name, 'state': state, 'type_name': "TextFilter"};
|
||||||
}
|
}
|
||||||
|
|
||||||
class SortFilter {
|
class SortFilter {
|
||||||
|
|
@ -88,7 +93,9 @@ class SortFilter {
|
||||||
return SortFilter(
|
return SortFilter(
|
||||||
json['type'],
|
json['type'],
|
||||||
json['name'],
|
json['name'],
|
||||||
json['state'] == null ? SortState(0, false, "") : SortState.fromJson(json['state']),
|
json['state'] == null
|
||||||
|
? SortState(0, false, "")
|
||||||
|
: SortState.fromJson(json['state']),
|
||||||
fromJsonFilterValuesToList(json['values']),
|
fromJsonFilterValuesToList(json['values']),
|
||||||
json['type_name']);
|
json['type_name']);
|
||||||
}
|
}
|
||||||
|
|
@ -110,7 +117,8 @@ class SortState {
|
||||||
factory SortState.fromJson(Map<String, dynamic> json) {
|
factory SortState.fromJson(Map<String, dynamic> json) {
|
||||||
return SortState(json['index'], json['ascending'], json['type_name']);
|
return SortState(json['index'], json['ascending'], json['type_name']);
|
||||||
}
|
}
|
||||||
Map<String, dynamic> toJson() => {'index': index, 'ascending': ascending, 'type_name': "SortState"};
|
Map<String, dynamic> toJson() =>
|
||||||
|
{'index': index, 'ascending': ascending, 'type_name': "SortState"};
|
||||||
}
|
}
|
||||||
|
|
||||||
class TriStateFilter {
|
class TriStateFilter {
|
||||||
|
|
@ -121,11 +129,19 @@ class TriStateFilter {
|
||||||
String? typeName;
|
String? typeName;
|
||||||
|
|
||||||
factory TriStateFilter.fromJson(Map<String, dynamic> json) {
|
factory TriStateFilter.fromJson(Map<String, dynamic> json) {
|
||||||
return TriStateFilter(json['type'], json['name'], json['value'], json['type_name'], state: json['state'] ?? 0);
|
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});
|
TriStateFilter(this.type, this.name, this.value, this.typeName,
|
||||||
Map<String, dynamic> toJson() =>
|
{this.state = 0});
|
||||||
{'type': type, 'name': name, 'value': value, 'state': state, 'type_name': "TriState"};
|
Map<String, dynamic> toJson() => {
|
||||||
|
'type': type,
|
||||||
|
'name': name,
|
||||||
|
'value': value,
|
||||||
|
'state': state,
|
||||||
|
'type_name': "TriState"
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
class GroupFilter {
|
class GroupFilter {
|
||||||
|
|
@ -136,10 +152,15 @@ class GroupFilter {
|
||||||
|
|
||||||
GroupFilter(this.type, this.name, this.state, this.typeName);
|
GroupFilter(this.type, this.name, this.state, this.typeName);
|
||||||
factory GroupFilter.fromJson(Map<String, dynamic> json) {
|
factory GroupFilter.fromJson(Map<String, dynamic> json) {
|
||||||
return GroupFilter(json['type'], json['name'], fromJsonFilterValuesToList(json['state']), json['type_name']);
|
return GroupFilter(json['type'], json['name'],
|
||||||
|
fromJsonFilterValuesToList(json['state']), json['type_name']);
|
||||||
}
|
}
|
||||||
Map<String, dynamic> toJson() =>
|
Map<String, dynamic> toJson() => {
|
||||||
{'type': type, 'name': name, 'state': filterValuesListToJson(state), 'type_name': "GroupFilter"};
|
'type': type,
|
||||||
|
'name': name,
|
||||||
|
'state': filterValuesListToJson(state),
|
||||||
|
'type_name': "GroupFilter"
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
class CheckBoxFilter {
|
class CheckBoxFilter {
|
||||||
|
|
@ -149,12 +170,20 @@ class CheckBoxFilter {
|
||||||
bool state;
|
bool state;
|
||||||
String? typeName;
|
String? typeName;
|
||||||
|
|
||||||
CheckBoxFilter(this.type, this.name, this.value, this.typeName, {this.state = false});
|
CheckBoxFilter(this.type, this.name, this.value, this.typeName,
|
||||||
|
{this.state = false});
|
||||||
factory CheckBoxFilter.fromJson(Map<String, dynamic> json) {
|
factory CheckBoxFilter.fromJson(Map<String, dynamic> json) {
|
||||||
return CheckBoxFilter(json['type'], json['name'], json['value'], json['type_name'], state: json['state'] ?? false);
|
return CheckBoxFilter(
|
||||||
|
json['type'], json['name'], json['value'], json['type_name'],
|
||||||
|
state: json['state'] ?? false);
|
||||||
}
|
}
|
||||||
Map<String, dynamic> toJson() =>
|
Map<String, dynamic> toJson() => {
|
||||||
{'type': type, 'name': name, 'value': value, 'state': state, 'type_name': "CheckBox"};
|
'type': type,
|
||||||
|
'name': name,
|
||||||
|
'value': value,
|
||||||
|
'state': state,
|
||||||
|
'type_name': "CheckBox"
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
List<dynamic> fromJsonFilterValuesToList(List list) {
|
List<dynamic> fromJsonFilterValuesToList(List list) {
|
||||||
|
|
@ -165,9 +194,11 @@ List<dynamic> fromJsonFilterValuesToList(List list) {
|
||||||
return switch (map['type_name']) {
|
return switch (map['type_name']) {
|
||||||
'TriState' => TriStateFilter.fromJson(map.toMapStringDynamic!),
|
'TriState' => TriStateFilter.fromJson(map.toMapStringDynamic!),
|
||||||
'CheckBox' => CheckBoxFilter.fromJson(map.toMapStringDynamic!),
|
'CheckBox' => CheckBoxFilter.fromJson(map.toMapStringDynamic!),
|
||||||
'SelectOption' => SelectFilterOption.fromJson(map.toMapStringDynamic!),
|
'SelectOption' =>
|
||||||
|
SelectFilterOption.fromJson(map.toMapStringDynamic!),
|
||||||
'SelectFilter' => SelectFilter.fromJson(map.toMapStringDynamic!),
|
'SelectFilter' => SelectFilter.fromJson(map.toMapStringDynamic!),
|
||||||
'SeparatorFilter' => SeparatorFilter.fromJson(map.toMapStringDynamic!),
|
'SeparatorFilter' =>
|
||||||
|
SeparatorFilter.fromJson(map.toMapStringDynamic!),
|
||||||
'HeaderFilter' => HeaderFilter.fromJson(map.toMapStringDynamic!),
|
'HeaderFilter' => HeaderFilter.fromJson(map.toMapStringDynamic!),
|
||||||
'TextFilter' => TextFilter.fromJson(map.toMapStringDynamic!),
|
'TextFilter' => TextFilter.fromJson(map.toMapStringDynamic!),
|
||||||
'SortFilter' => SortFilter.fromJson(map.toMapStringDynamic!),
|
'SortFilter' => SortFilter.fromJson(map.toMapStringDynamic!),
|
||||||
|
|
|
||||||
|
|
@ -44,15 +44,18 @@ class WordSet {
|
||||||
WordSet(this.words);
|
WordSet(this.words);
|
||||||
|
|
||||||
bool anyWordIn(String dateString) {
|
bool anyWordIn(String dateString) {
|
||||||
return words.any((word) => dateString.toLowerCase().contains(word.toLowerCase()));
|
return words
|
||||||
|
.any((word) => dateString.toLowerCase().contains(word.toLowerCase()));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool startsWith(String dateString) {
|
bool startsWith(String dateString) {
|
||||||
return words.any((word) => dateString.toLowerCase().startsWith(word.toLowerCase()));
|
return words
|
||||||
|
.any((word) => dateString.toLowerCase().startsWith(word.toLowerCase()));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool endsWith(String dateString) {
|
bool endsWith(String dateString) {
|
||||||
return words.any((word) => dateString.toLowerCase().endsWith(word.toLowerCase()));
|
return words
|
||||||
|
.any((word) => dateString.toLowerCase().endsWith(word.toLowerCase()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -79,7 +82,8 @@ class MBridge {
|
||||||
|
|
||||||
//Return one attr
|
//Return one attr
|
||||||
else if (query.nodes.length == 1) {
|
else if (query.nodes.length == 1) {
|
||||||
String attr = query.attr != null ? query.attr!.trim().trimLeft().trimRight() : "";
|
String attr =
|
||||||
|
query.attr != null ? query.attr!.trim().trimLeft().trimRight() : "";
|
||||||
if (attr.isNotEmpty) {
|
if (attr.isNotEmpty) {
|
||||||
attrs = [attr];
|
attrs = [attr];
|
||||||
}
|
}
|
||||||
|
|
@ -102,7 +106,10 @@ class MBridge {
|
||||||
statusMap = element;
|
statusMap = element;
|
||||||
}
|
}
|
||||||
for (var element in statusMap.entries) {
|
for (var element in statusMap.entries) {
|
||||||
if (element.key.toString().toLowerCase().contains(status.toLowerCase().trim().trimLeft().trimRight())) {
|
if (element.key
|
||||||
|
.toString()
|
||||||
|
.toLowerCase()
|
||||||
|
.contains(status.toLowerCase().trim().trimLeft().trimRight())) {
|
||||||
return switch (element.value as int) {
|
return switch (element.value as int) {
|
||||||
0 => Status.ongoing,
|
0 => Status.ongoing,
|
||||||
1 => Status.completed,
|
1 => Status.completed,
|
||||||
|
|
@ -259,7 +266,8 @@ class MBridge {
|
||||||
}
|
}
|
||||||
|
|
||||||
//Parse a list of dates to millisecondsSinceEpoch
|
//Parse a list of dates to millisecondsSinceEpoch
|
||||||
static List parseDates(List value, String dateFormat, String dateFormatLocale) {
|
static List parseDates(
|
||||||
|
List value, String dateFormat, String dateFormatLocale) {
|
||||||
List<dynamic> val = [];
|
List<dynamic> val = [];
|
||||||
for (var element in value) {
|
for (var element in value) {
|
||||||
if (element is $Value) {
|
if (element is $Value) {
|
||||||
|
|
@ -304,7 +312,8 @@ class MBridge {
|
||||||
}
|
}
|
||||||
|
|
||||||
//Utility to use RegExp
|
//Utility to use RegExp
|
||||||
static String regExp(String expression, String source, String replace, int type, int group) {
|
static String regExp(
|
||||||
|
String expression, String source, String replace, int type, int group) {
|
||||||
if (type == 0) {
|
if (type == 0) {
|
||||||
return expression.replaceAll(RegExp(source), replace);
|
return expression.replaceAll(RegExp(source), replace);
|
||||||
}
|
}
|
||||||
|
|
@ -319,48 +328,58 @@ class MBridge {
|
||||||
return await DoodExtractor().videosFromUrl(url, quality: quality);
|
return await DoodExtractor().videosFromUrl(url, quality: quality);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<List<Video>> streamWishExtractor(String url, String prefix) async {
|
static Future<List<Video>> streamWishExtractor(
|
||||||
|
String url, String prefix) async {
|
||||||
return await StreamWishExtractor().videosFromUrl(url, prefix);
|
return await StreamWishExtractor().videosFromUrl(url, prefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<List<Video>> filemoonExtractor(String url, String prefix, String suffix) async {
|
static Future<List<Video>> filemoonExtractor(
|
||||||
|
String url, String prefix, String suffix) async {
|
||||||
return await FilemoonExtractor().videosFromUrl(url, prefix, suffix);
|
return await FilemoonExtractor().videosFromUrl(url, prefix, suffix);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<List<Video>> mp4UploadExtractor(String url, String? headers, String prefix, String suffix) async {
|
static Future<List<Video>> mp4UploadExtractor(
|
||||||
|
String url, String? headers, String prefix, String suffix) async {
|
||||||
Map<String, String> newHeaders = {};
|
Map<String, String> newHeaders = {};
|
||||||
if (headers != null) {
|
if (headers != null) {
|
||||||
newHeaders = (jsonDecode(headers) as Map).toMapStringString!;
|
newHeaders = (jsonDecode(headers) as Map).toMapStringString!;
|
||||||
}
|
}
|
||||||
return await Mp4uploadExtractor().videosFromUrl(url, newHeaders, prefix: prefix, suffix: suffix);
|
return await Mp4uploadExtractor()
|
||||||
|
.videosFromUrl(url, newHeaders, prefix: prefix, suffix: suffix);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<List<Map<String, String>>> quarkFilesExtractor(List<String> url, String cookie) async {
|
static Future<List<Map<String, String>>> quarkFilesExtractor(
|
||||||
|
List<String> url, String cookie) async {
|
||||||
QuarkUcExtractor quark = QuarkUcExtractor();
|
QuarkUcExtractor quark = QuarkUcExtractor();
|
||||||
await quark.initCloudDrive(cookie, CloudDriveType.quark);
|
await quark.initCloudDrive(cookie, CloudDriveType.quark);
|
||||||
return await quark.videoFilesFromUrl(url);
|
return await quark.videoFilesFromUrl(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<List<Map<String, String>>> ucFilesExtractor(List<String> url, String cookie) async {
|
static Future<List<Map<String, String>>> ucFilesExtractor(
|
||||||
|
List<String> url, String cookie) async {
|
||||||
QuarkUcExtractor uc = QuarkUcExtractor();
|
QuarkUcExtractor uc = QuarkUcExtractor();
|
||||||
await uc.initCloudDrive(cookie, CloudDriveType.uc);
|
await uc.initCloudDrive(cookie, CloudDriveType.uc);
|
||||||
return await uc.videoFilesFromUrl(url);
|
return await uc.videoFilesFromUrl(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<List<Video>> quarkVideosExtractor(String url, String cookie) async {
|
static Future<List<Video>> quarkVideosExtractor(
|
||||||
|
String url, String cookie) async {
|
||||||
QuarkUcExtractor quark = QuarkUcExtractor();
|
QuarkUcExtractor quark = QuarkUcExtractor();
|
||||||
await quark.initCloudDrive(cookie, CloudDriveType.quark);
|
await quark.initCloudDrive(cookie, CloudDriveType.quark);
|
||||||
return await quark.videosFromUrl(url);
|
return await quark.videosFromUrl(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<List<Video>> ucVideosExtractor(String url, String cookie) async {
|
static Future<List<Video>> ucVideosExtractor(
|
||||||
|
String url, String cookie) async {
|
||||||
QuarkUcExtractor uc = QuarkUcExtractor();
|
QuarkUcExtractor uc = QuarkUcExtractor();
|
||||||
await uc.initCloudDrive(cookie, CloudDriveType.uc);
|
await uc.initCloudDrive(cookie, CloudDriveType.uc);
|
||||||
return await uc.videosFromUrl(url);
|
return await uc.videosFromUrl(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<List<Video>> streamTapeExtractor(String url, String? quality) async {
|
static Future<List<Video>> streamTapeExtractor(
|
||||||
return await StreamTapeExtractor().videosFromUrl(url, quality: quality ?? "StreamTape");
|
String url, String? quality) async {
|
||||||
|
return await StreamTapeExtractor()
|
||||||
|
.videosFromUrl(url, quality: quality ?? "StreamTape");
|
||||||
}
|
}
|
||||||
|
|
||||||
//Utility to use substring
|
//Utility to use substring
|
||||||
|
|
@ -383,28 +402,55 @@ class MBridge {
|
||||||
}
|
}
|
||||||
|
|
||||||
//Parse a chapter date to millisecondsSinceEpoch
|
//Parse a chapter date to millisecondsSinceEpoch
|
||||||
static String parseChapterDate(
|
static String parseChapterDate(String date, String dateFormat,
|
||||||
String date, String dateFormat, String dateFormatLocale, Function((String, String, bool)) newLocale) {
|
String dateFormatLocale, Function((String, String, bool)) newLocale) {
|
||||||
int parseRelativeDate(String date) {
|
int parseRelativeDate(String date) {
|
||||||
final number = int.tryParse(RegExp(r"(\d+)").firstMatch(date)!.group(0)!);
|
final number = int.tryParse(RegExp(r"(\d+)").firstMatch(date)!.group(0)!);
|
||||||
if (number == null) return 0;
|
if (number == null) return 0;
|
||||||
final cal = DateTime.now();
|
final cal = DateTime.now();
|
||||||
|
|
||||||
if (WordSet(["hari", "gün", "jour", "día", "dia", "day", "วัน", "ngày", "giorni", "أيام", "天"]).anyWordIn(date)) {
|
if (WordSet([
|
||||||
|
"hari",
|
||||||
|
"gün",
|
||||||
|
"jour",
|
||||||
|
"día",
|
||||||
|
"dia",
|
||||||
|
"day",
|
||||||
|
"วัน",
|
||||||
|
"ngày",
|
||||||
|
"giorni",
|
||||||
|
"أيام",
|
||||||
|
"天"
|
||||||
|
]).anyWordIn(date)) {
|
||||||
return cal.subtract(Duration(days: number)).millisecondsSinceEpoch;
|
return cal.subtract(Duration(days: number)).millisecondsSinceEpoch;
|
||||||
} else if (WordSet(["jam", "saat", "heure", "hora", "hour", "ชั่วโมง", "giờ", "ore", "ساعة", "小时"])
|
} else if (WordSet([
|
||||||
.anyWordIn(date)) {
|
"jam",
|
||||||
|
"saat",
|
||||||
|
"heure",
|
||||||
|
"hora",
|
||||||
|
"hour",
|
||||||
|
"ชั่วโมง",
|
||||||
|
"giờ",
|
||||||
|
"ore",
|
||||||
|
"ساعة",
|
||||||
|
"小时"
|
||||||
|
]).anyWordIn(date)) {
|
||||||
return cal.subtract(Duration(hours: number)).millisecondsSinceEpoch;
|
return cal.subtract(Duration(hours: number)).millisecondsSinceEpoch;
|
||||||
} else if (WordSet(["menit", "dakika", "min", "minute", "minuto", "นาที", "دقائق"]).anyWordIn(date)) {
|
} else if (WordSet(
|
||||||
|
["menit", "dakika", "min", "minute", "minuto", "นาที", "دقائق"])
|
||||||
|
.anyWordIn(date)) {
|
||||||
return cal.subtract(Duration(minutes: number)).millisecondsSinceEpoch;
|
return cal.subtract(Duration(minutes: number)).millisecondsSinceEpoch;
|
||||||
} else if (WordSet(["detik", "segundo", "second", "วินาที", "sec"]).anyWordIn(date)) {
|
} else if (WordSet(["detik", "segundo", "second", "วินาที", "sec"])
|
||||||
|
.anyWordIn(date)) {
|
||||||
return cal.subtract(Duration(seconds: number)).millisecondsSinceEpoch;
|
return cal.subtract(Duration(seconds: number)).millisecondsSinceEpoch;
|
||||||
} else if (WordSet(["week", "semana"]).anyWordIn(date)) {
|
} else if (WordSet(["week", "semana"]).anyWordIn(date)) {
|
||||||
return cal.subtract(Duration(days: number * 7)).millisecondsSinceEpoch;
|
return cal.subtract(Duration(days: number * 7)).millisecondsSinceEpoch;
|
||||||
} else if (WordSet(["month", "mes"]).anyWordIn(date)) {
|
} else if (WordSet(["month", "mes"]).anyWordIn(date)) {
|
||||||
return cal.subtract(Duration(days: number * 30)).millisecondsSinceEpoch;
|
return cal.subtract(Duration(days: number * 30)).millisecondsSinceEpoch;
|
||||||
} else if (WordSet(["year", "año"]).anyWordIn(date)) {
|
} else if (WordSet(["year", "año"]).anyWordIn(date)) {
|
||||||
return cal.subtract(Duration(days: number * 365)).millisecondsSinceEpoch;
|
return cal
|
||||||
|
.subtract(Duration(days: number * 365))
|
||||||
|
.millisecondsSinceEpoch;
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -430,11 +476,19 @@ class MBridge {
|
||||||
} else if (date.contains(RegExp(r"\d(st|nd|rd|th)"))) {
|
} else if (date.contains(RegExp(r"\d(st|nd|rd|th)"))) {
|
||||||
final cleanedDate = date
|
final cleanedDate = date
|
||||||
.split(" ")
|
.split(" ")
|
||||||
.map((it) => it.contains(RegExp(r"\d\D\D")) ? it.replaceAll(RegExp(r"\D"), "") : it)
|
.map((it) => it.contains(RegExp(r"\d\D\D"))
|
||||||
|
? it.replaceAll(RegExp(r"\D"), "")
|
||||||
|
: it)
|
||||||
.join(" ");
|
.join(" ");
|
||||||
return DateFormat(dateFormat, dateFormatLocale).parse(cleanedDate).millisecondsSinceEpoch.toString();
|
return DateFormat(dateFormat, dateFormatLocale)
|
||||||
|
.parse(cleanedDate)
|
||||||
|
.millisecondsSinceEpoch
|
||||||
|
.toString();
|
||||||
} else {
|
} else {
|
||||||
return DateFormat(dateFormat, dateFormatLocale).parse(date).millisecondsSinceEpoch.toString();
|
return DateFormat(dateFormat, dateFormatLocale)
|
||||||
|
.parse(date)
|
||||||
|
.millisecondsSinceEpoch
|
||||||
|
.toString();
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
final supportedLocales = DateFormat.allLocalesWithSymbols();
|
final supportedLocales = DateFormat.allLocalesWithSymbols();
|
||||||
|
|
@ -456,18 +510,27 @@ class MBridge {
|
||||||
DateTime cal = DateTime.now().subtract(const Duration(days: 2));
|
DateTime cal = DateTime.now().subtract(const Duration(days: 2));
|
||||||
cal = DateTime(cal.year, cal.month, cal.day);
|
cal = DateTime(cal.year, cal.month, cal.day);
|
||||||
return cal.millisecondsSinceEpoch.toString();
|
return cal.millisecondsSinceEpoch.toString();
|
||||||
} else if (WordSet(["ago", "atrás", "önce", "قبل"]).endsWith(date)) {
|
} else if (WordSet(["ago", "atrás", "önce", "قبل"])
|
||||||
|
.endsWith(date)) {
|
||||||
return parseRelativeDate(date).toString();
|
return parseRelativeDate(date).toString();
|
||||||
} else if (WordSet(["hace"]).startsWith(date)) {
|
} else if (WordSet(["hace"]).startsWith(date)) {
|
||||||
return parseRelativeDate(date).toString();
|
return parseRelativeDate(date).toString();
|
||||||
} else if (date.contains(RegExp(r"\d(st|nd|rd|th)"))) {
|
} else if (date.contains(RegExp(r"\d(st|nd|rd|th)"))) {
|
||||||
final cleanedDate = date
|
final cleanedDate = date
|
||||||
.split(" ")
|
.split(" ")
|
||||||
.map((it) => it.contains(RegExp(r"\d\D\D")) ? it.replaceAll(RegExp(r"\D"), "") : it)
|
.map((it) => it.contains(RegExp(r"\d\D\D"))
|
||||||
|
? it.replaceAll(RegExp(r"\D"), "")
|
||||||
|
: it)
|
||||||
.join(" ");
|
.join(" ");
|
||||||
return DateFormat(dateFormat, locale).parse(cleanedDate).millisecondsSinceEpoch.toString();
|
return DateFormat(dateFormat, locale)
|
||||||
|
.parse(cleanedDate)
|
||||||
|
.millisecondsSinceEpoch
|
||||||
|
.toString();
|
||||||
} else {
|
} else {
|
||||||
return DateFormat(dateFormat, locale).parse(date).millisecondsSinceEpoch.toString();
|
return DateFormat(dateFormat, locale)
|
||||||
|
.parse(date)
|
||||||
|
.millisecondsSinceEpoch
|
||||||
|
.toString();
|
||||||
}
|
}
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
}
|
}
|
||||||
|
|
@ -485,13 +548,15 @@ class MBridge {
|
||||||
return await SibnetExtractor().videosFromUrl(url, prefix: prefix);
|
return await SibnetExtractor().videosFromUrl(url, prefix: prefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<List<Video>> sendVidExtractor(String url, String? headers, String prefix) async {
|
static Future<List<Video>> sendVidExtractor(
|
||||||
|
String url, String? headers, String prefix) async {
|
||||||
Map<String, String> newHeaders = {};
|
Map<String, String> newHeaders = {};
|
||||||
if (headers != null) {
|
if (headers != null) {
|
||||||
newHeaders = (jsonDecode(headers) as Map).toMapStringString!;
|
newHeaders = (jsonDecode(headers) as Map).toMapStringString!;
|
||||||
}
|
}
|
||||||
|
|
||||||
return await SendvidExtractor(newHeaders).videosFromUrl(url, prefix: prefix);
|
return await SendvidExtractor(newHeaders)
|
||||||
|
.videosFromUrl(url, prefix: prefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<List<Video>> myTvExtractor(String url) async {
|
static Future<List<Video>> myTvExtractor(String url) async {
|
||||||
|
|
@ -502,12 +567,14 @@ class MBridge {
|
||||||
return await OkruExtractor().videosFromUrl(url);
|
return await OkruExtractor().videosFromUrl(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<List<Video>> yourUploadExtractor(String url, String? headers, String? name, String prefix) async {
|
static Future<List<Video>> yourUploadExtractor(
|
||||||
|
String url, String? headers, String? name, String prefix) async {
|
||||||
Map<String, String> newHeaders = {};
|
Map<String, String> newHeaders = {};
|
||||||
if (headers != null) {
|
if (headers != null) {
|
||||||
newHeaders = (jsonDecode(headers) as Map).toMapStringString!;
|
newHeaders = (jsonDecode(headers) as Map).toMapStringString!;
|
||||||
}
|
}
|
||||||
return await YourUploadExtractor().videosFromUrl(url, newHeaders, prefix: prefix, name: name ?? "YourUpload");
|
return await YourUploadExtractor().videosFromUrl(url, newHeaders,
|
||||||
|
prefix: prefix, name: name ?? "YourUpload");
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<List<Video>> voeExtractor(String url, String? quality) async {
|
static Future<List<Video>> voeExtractor(String url, String? quality) async {
|
||||||
|
|
@ -518,8 +585,10 @@ class MBridge {
|
||||||
return await VidBomExtractor().videosFromUrl(url);
|
return await VidBomExtractor().videosFromUrl(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<List<Video>> streamlareExtractor(String url, String prefix, String suffix) async {
|
static Future<List<Video>> streamlareExtractor(
|
||||||
return await StreamlareExtractor().videosFromUrl(url, prefix: prefix, suffix: suffix);
|
String url, String prefix, String suffix) async {
|
||||||
|
return await StreamlareExtractor()
|
||||||
|
.videosFromUrl(url, prefix: prefix, suffix: suffix);
|
||||||
}
|
}
|
||||||
|
|
||||||
static String encryptAESCryptoJS(String plainText, String passphrase) {
|
static String encryptAESCryptoJS(String plainText, String passphrase) {
|
||||||
|
|
@ -530,16 +599,18 @@ class MBridge {
|
||||||
return CryptoAES.decryptAESCryptoJS(encrypted, passphrase);
|
return CryptoAES.decryptAESCryptoJS(encrypted, passphrase);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Video toVideo(
|
static Video toVideo(String url, String quality, String originalUrl,
|
||||||
String url, String quality, String originalUrl, String? headers, List<Track>? subtitles, List<Track>? audios) {
|
String? headers, List<Track>? subtitles, List<Track>? audios) {
|
||||||
Map<String, String> newHeaders = {};
|
Map<String, String> newHeaders = {};
|
||||||
if (headers != null) {
|
if (headers != null) {
|
||||||
newHeaders = (jsonDecode(headers) as Map).toMapStringString!;
|
newHeaders = (jsonDecode(headers) as Map).toMapStringString!;
|
||||||
}
|
}
|
||||||
return Video(url, quality, originalUrl, headers: newHeaders, subtitles: subtitles ?? [], audios: audios ?? []);
|
return Video(url, quality, originalUrl,
|
||||||
|
headers: newHeaders, subtitles: subtitles ?? [], audios: audios ?? []);
|
||||||
}
|
}
|
||||||
|
|
||||||
static String cryptoHandler(String text, String iv, String secretKeyString, bool encrypt) {
|
static String cryptoHandler(
|
||||||
|
String text, String iv, String secretKeyString, bool encrypt) {
|
||||||
try {
|
try {
|
||||||
if (encrypt) {
|
if (encrypt) {
|
||||||
final encryptt = _encrypt(secretKeyString, iv);
|
final encryptt = _encrypt(secretKeyString, iv);
|
||||||
|
|
@ -603,7 +674,10 @@ void botToast(String title,
|
||||||
bool hasCloudFlare = false,
|
bool hasCloudFlare = false,
|
||||||
String? url}) {
|
String? url}) {
|
||||||
final context = navigatorKey.currentState?.context;
|
final context = navigatorKey.currentState?.context;
|
||||||
final assets = ['assets/app_icons/icon-black.png', 'assets/app_icons/icon-red.png'];
|
final assets = [
|
||||||
|
'assets/app_icons/icon-black.png',
|
||||||
|
'assets/app_icons/icon-red.png'
|
||||||
|
];
|
||||||
BotToast.showNotification(
|
BotToast.showNotification(
|
||||||
onlyOne: true,
|
onlyOne: true,
|
||||||
dismissDirections: [DismissDirection.horizontal, DismissDirection.down],
|
dismissDirections: [DismissDirection.horizontal, DismissDirection.down],
|
||||||
|
|
@ -617,9 +691,11 @@ void botToast(String title,
|
||||||
? (_) => OutlinedButton.icon(
|
? (_) => OutlinedButton.icon(
|
||||||
style: OutlinedButton.styleFrom(elevation: 10),
|
style: OutlinedButton.styleFrom(elevation: 10),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
context?.push("/mangawebview", extra: {'url': url, 'title': ''});
|
context
|
||||||
|
?.push("/mangawebview", extra: {'url': url, 'title': ''});
|
||||||
},
|
},
|
||||||
label: Text("Resolve Cloudflare challenge", style: TextStyle(color: context?.secondaryColor)),
|
label: Text("Resolve Cloudflare challenge",
|
||||||
|
style: TextStyle(color: context?.secondaryColor)),
|
||||||
icon: const Icon(Icons.public),
|
icon: const Icon(Icons.public),
|
||||||
)
|
)
|
||||||
: null,
|
: null,
|
||||||
|
|
@ -629,6 +705,7 @@ void botToast(String title,
|
||||||
(encrypt.Encrypter, encrypt.IV) _encrypt(String keyy, String ivv) {
|
(encrypt.Encrypter, encrypt.IV) _encrypt(String keyy, String ivv) {
|
||||||
final key = encrypt.Key.fromUtf8(keyy);
|
final key = encrypt.Key.fromUtf8(keyy);
|
||||||
final iv = encrypt.IV.fromUtf8(ivv);
|
final iv = encrypt.IV.fromUtf8(ivv);
|
||||||
final encrypter = encrypt.Encrypter(encrypt.AES(key, mode: encrypt.AESMode.cbc, padding: 'PKCS7'));
|
final encrypter = encrypt.Encrypter(
|
||||||
|
encrypt.AES(key, mode: encrypt.AESMode.cbc, padding: 'PKCS7'));
|
||||||
return (encrypter, iv);
|
return (encrypter, iv);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,16 @@ class MChapter {
|
||||||
String? scanlator;
|
String? scanlator;
|
||||||
MChapter({this.name, this.url, this.dateUpload, this.scanlator});
|
MChapter({this.name, this.url, this.dateUpload, this.scanlator});
|
||||||
factory MChapter.fromJson(Map<String, dynamic> json) {
|
factory MChapter.fromJson(Map<String, dynamic> json) {
|
||||||
return MChapter(name: json['name'], url: json['url'], dateUpload: json['dateUpload'], scanlator: json['scanlator']);
|
return MChapter(
|
||||||
|
name: json['name'],
|
||||||
|
url: json['url'],
|
||||||
|
dateUpload: json['dateUpload'],
|
||||||
|
scanlator: json['scanlator']);
|
||||||
}
|
}
|
||||||
Map<String, dynamic> toJson() => {'name': name, 'url': url, 'dateUpload': dateUpload, 'scanlator': scanlator};
|
Map<String, dynamic> toJson() => {
|
||||||
|
'name': name,
|
||||||
|
'url': url,
|
||||||
|
'dateUpload': dateUpload,
|
||||||
|
'scanlator': scanlator
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -48,11 +48,16 @@ class MManga {
|
||||||
4 => Status.publishingFinished,
|
4 => Status.publishingFinished,
|
||||||
_ => Status.unknown,
|
_ => Status.unknown,
|
||||||
},
|
},
|
||||||
genre: (json['genre'] as List?)?.map((e) => e.toString()).toList() ?? [],
|
genre:
|
||||||
|
(json['genre'] as List?)?.map((e) => e.toString()).toList() ?? [],
|
||||||
chapters: json['chapters'] != null
|
chapters: json['chapters'] != null
|
||||||
? (json['chapters'] as List).map((e) => MChapter.fromJson(e)).toList()
|
? (json['chapters'] as List)
|
||||||
|
.map((e) => MChapter.fromJson(e))
|
||||||
|
.toList()
|
||||||
: json['episodes'] != null
|
: json['episodes'] != null
|
||||||
? (json['episodes'] as List).map((e) => MChapter.fromJson(e)).toList()
|
? (json['episodes'] as List)
|
||||||
|
.map((e) => MChapter.fromJson(e))
|
||||||
|
.toList()
|
||||||
: []);
|
: []);
|
||||||
}
|
}
|
||||||
Map<String, dynamic> toJson() => {
|
Map<String, dynamic> toJson() => {
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,9 @@ class MPages {
|
||||||
|
|
||||||
factory MPages.fromJson(Map<String, dynamic> json) {
|
factory MPages.fromJson(Map<String, dynamic> json) {
|
||||||
return MPages(
|
return MPages(
|
||||||
list: json['list'] != null ? (json['list'] as List).map((e) => MManga.fromJson(e)).toList() : [],
|
list: json['list'] != null
|
||||||
|
? (json['list'] as List).map((e) => MManga.fromJson(e)).toList()
|
||||||
|
: [],
|
||||||
hasNextPage: json['hasNextPage']);
|
hasNextPage: json['hasNextPage']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,8 @@ class MVideo {
|
||||||
List<MTrack>? subtitles;
|
List<MTrack>? subtitles;
|
||||||
List<MTrack>? audios;
|
List<MTrack>? audios;
|
||||||
|
|
||||||
MVideo(this.url, this.quality, this.originalUrl, {this.headers, this.subtitles, this.audios});
|
MVideo(this.url, this.quality, this.originalUrl,
|
||||||
|
{this.headers, this.subtitles, this.audios});
|
||||||
}
|
}
|
||||||
|
|
||||||
class MTrack {
|
class MTrack {
|
||||||
|
|
|
||||||
|
|
@ -27,11 +27,15 @@ class SourcePreference {
|
||||||
'id': id,
|
'id': id,
|
||||||
'sourceId': sourceId,
|
'sourceId': sourceId,
|
||||||
'key': key,
|
'key': key,
|
||||||
if (checkBoxPreference != null) 'checkBoxPreference': checkBoxPreference!.toJson(),
|
if (checkBoxPreference != null)
|
||||||
if (switchPreferenceCompat != null) 'switchPreferenceCompat': switchPreferenceCompat!.toJson(),
|
'checkBoxPreference': checkBoxPreference!.toJson(),
|
||||||
|
if (switchPreferenceCompat != null)
|
||||||
|
'switchPreferenceCompat': switchPreferenceCompat!.toJson(),
|
||||||
if (listPreference != null) 'listPreference': listPreference!.toJson(),
|
if (listPreference != null) 'listPreference': listPreference!.toJson(),
|
||||||
if (multiSelectListPreference != null) 'multiSelectListPreference': multiSelectListPreference!.toJson(),
|
if (multiSelectListPreference != null)
|
||||||
if (editTextPreference != null) 'editTextPreference': editTextPreference!.toJson()
|
'multiSelectListPreference': multiSelectListPreference!.toJson(),
|
||||||
|
if (editTextPreference != null)
|
||||||
|
'editTextPreference': editTextPreference!.toJson()
|
||||||
};
|
};
|
||||||
|
|
||||||
factory SourcePreference.fromJson(Map<String, dynamic> json) {
|
factory SourcePreference.fromJson(Map<String, dynamic> json) {
|
||||||
|
|
@ -39,17 +43,22 @@ class SourcePreference {
|
||||||
id: json['id'] ?? Isar.autoIncrement,
|
id: json['id'] ?? Isar.autoIncrement,
|
||||||
sourceId: json['sourceId'],
|
sourceId: json['sourceId'],
|
||||||
key: json['key'],
|
key: json['key'],
|
||||||
checkBoxPreference:
|
checkBoxPreference: json['checkBoxPreference'] != null
|
||||||
json['checkBoxPreference'] != null ? CheckBoxPreference.fromJson(json['checkBoxPreference']) : null,
|
? CheckBoxPreference.fromJson(json['checkBoxPreference'])
|
||||||
|
: null,
|
||||||
switchPreferenceCompat: json['switchPreferenceCompat'] != null
|
switchPreferenceCompat: json['switchPreferenceCompat'] != null
|
||||||
? SwitchPreferenceCompat.fromJson(json['switchPreferenceCompat'])
|
? SwitchPreferenceCompat.fromJson(json['switchPreferenceCompat'])
|
||||||
: null,
|
: null,
|
||||||
listPreference: json['listPreference'] != null ? ListPreference.fromJson(json['listPreference']) : null,
|
listPreference: json['listPreference'] != null
|
||||||
multiSelectListPreference: json['multiSelectListPreference'] != null
|
? ListPreference.fromJson(json['listPreference'])
|
||||||
? MultiSelectListPreference.fromJson(json['multiSelectListPreference'])
|
|
||||||
: null,
|
: null,
|
||||||
editTextPreference:
|
multiSelectListPreference: json['multiSelectListPreference'] != null
|
||||||
json['editTextPreference'] != null ? EditTextPreference.fromJson(json['editTextPreference']) : null);
|
? MultiSelectListPreference.fromJson(
|
||||||
|
json['multiSelectListPreference'])
|
||||||
|
: null,
|
||||||
|
editTextPreference: json['editTextPreference'] != null
|
||||||
|
? EditTextPreference.fromJson(json['editTextPreference'])
|
||||||
|
: null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -61,10 +70,12 @@ class CheckBoxPreference {
|
||||||
|
|
||||||
CheckBoxPreference({this.title, this.summary, this.value});
|
CheckBoxPreference({this.title, this.summary, this.value});
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {'title': title, 'summary': summary, 'value': value};
|
Map<String, dynamic> toJson() =>
|
||||||
|
{'title': title, 'summary': summary, 'value': value};
|
||||||
|
|
||||||
factory CheckBoxPreference.fromJson(Map<String, dynamic> json) {
|
factory CheckBoxPreference.fromJson(Map<String, dynamic> json) {
|
||||||
return CheckBoxPreference(title: json['title'], summary: json['summary'], value: json['value']);
|
return CheckBoxPreference(
|
||||||
|
title: json['title'], summary: json['summary'], value: json['value']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -76,10 +87,12 @@ class SwitchPreferenceCompat {
|
||||||
|
|
||||||
SwitchPreferenceCompat({this.title, this.summary, this.value});
|
SwitchPreferenceCompat({this.title, this.summary, this.value});
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {'title': title, 'summary': summary, 'value': value};
|
Map<String, dynamic> toJson() =>
|
||||||
|
{'title': title, 'summary': summary, 'value': value};
|
||||||
|
|
||||||
factory SwitchPreferenceCompat.fromJson(Map<String, dynamic> json) {
|
factory SwitchPreferenceCompat.fromJson(Map<String, dynamic> json) {
|
||||||
return SwitchPreferenceCompat(title: json['title'], summary: json['summary'], value: json['value']);
|
return SwitchPreferenceCompat(
|
||||||
|
title: json['title'], summary: json['summary'], value: json['value']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -91,10 +104,20 @@ class ListPreference {
|
||||||
List<String>? entries;
|
List<String>? entries;
|
||||||
List<String>? entryValues;
|
List<String>? entryValues;
|
||||||
|
|
||||||
ListPreference({this.title, this.summary, this.valueIndex, this.entries, this.entryValues});
|
ListPreference(
|
||||||
|
{this.title,
|
||||||
|
this.summary,
|
||||||
|
this.valueIndex,
|
||||||
|
this.entries,
|
||||||
|
this.entryValues});
|
||||||
|
|
||||||
Map<String, dynamic> toJson() =>
|
Map<String, dynamic> toJson() => {
|
||||||
{'title': title, 'summary': summary, 'valueIndex': valueIndex, 'entries': entries, 'entryValues': entryValues};
|
'title': title,
|
||||||
|
'summary': summary,
|
||||||
|
'valueIndex': valueIndex,
|
||||||
|
'entries': entries,
|
||||||
|
'entryValues': entryValues
|
||||||
|
};
|
||||||
|
|
||||||
factory ListPreference.fromJson(Map<String, dynamic> json) {
|
factory ListPreference.fromJson(Map<String, dynamic> json) {
|
||||||
return ListPreference(
|
return ListPreference(
|
||||||
|
|
@ -114,7 +137,8 @@ class MultiSelectListPreference {
|
||||||
List<String>? entryValues;
|
List<String>? entryValues;
|
||||||
List<String>? values;
|
List<String>? values;
|
||||||
|
|
||||||
MultiSelectListPreference({this.title, this.summary, this.entries, this.entryValues, this.values});
|
MultiSelectListPreference(
|
||||||
|
{this.title, this.summary, this.entries, this.entryValues, this.values});
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
Map<String, dynamic> toJson() => {
|
||||||
'title': title,
|
'title': title,
|
||||||
|
|
@ -143,7 +167,13 @@ class EditTextPreference {
|
||||||
String? dialogMessage;
|
String? dialogMessage;
|
||||||
String? text;
|
String? text;
|
||||||
|
|
||||||
EditTextPreference({this.title, this.summary, this.value, this.dialogTitle, this.dialogMessage, this.text});
|
EditTextPreference(
|
||||||
|
{this.title,
|
||||||
|
this.summary,
|
||||||
|
this.value,
|
||||||
|
this.dialogTitle,
|
||||||
|
this.dialogMessage,
|
||||||
|
this.text});
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
Map<String, dynamic> toJson() => {
|
||||||
'title': title,
|
'title': title,
|
||||||
|
|
@ -173,5 +203,6 @@ class SourcePreferenceStringValue {
|
||||||
String? key;
|
String? key;
|
||||||
String? value;
|
String? value;
|
||||||
|
|
||||||
SourcePreferenceStringValue({this.id = Isar.autoIncrement, this.sourceId, this.key, this.value});
|
SourcePreferenceStringValue(
|
||||||
|
{this.id = Isar.autoIncrement, this.sourceId, this.key, this.value});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,13 +13,17 @@ import 'dart:ffi' as ffi;
|
||||||
/// Bindings to `lib/ffi/libmtorrentserver.h`.
|
/// Bindings to `lib/ffi/libmtorrentserver.h`.
|
||||||
class TorrentLibrary {
|
class TorrentLibrary {
|
||||||
/// Holds the symbol lookup function.
|
/// Holds the symbol lookup function.
|
||||||
final ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName) _lookup;
|
final ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
|
||||||
|
_lookup;
|
||||||
|
|
||||||
/// The symbols are looked up in [dynamicLibrary].
|
/// The symbols are looked up in [dynamicLibrary].
|
||||||
TorrentLibrary(ffi.DynamicLibrary dynamicLibrary) : _lookup = dynamicLibrary.lookup;
|
TorrentLibrary(ffi.DynamicLibrary dynamicLibrary)
|
||||||
|
: _lookup = dynamicLibrary.lookup;
|
||||||
|
|
||||||
/// The symbols are looked up with [lookup].
|
/// The symbols are looked up with [lookup].
|
||||||
TorrentLibrary.fromLookup(ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName) lookup)
|
TorrentLibrary.fromLookup(
|
||||||
|
ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
|
||||||
|
lookup)
|
||||||
: _lookup = lookup;
|
: _lookup = lookup;
|
||||||
|
|
||||||
void __va_start(
|
void __va_start(
|
||||||
|
|
@ -30,15 +34,21 @@ class TorrentLibrary {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
late final ___va_startPtr = _lookup<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<va_list>)>>('__va_start');
|
late final ___va_startPtr =
|
||||||
late final ___va_start = ___va_startPtr.asFunction<void Function(ffi.Pointer<va_list>)>();
|
_lookup<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<va_list>)>>(
|
||||||
|
'__va_start');
|
||||||
|
late final ___va_start =
|
||||||
|
___va_startPtr.asFunction<void Function(ffi.Pointer<va_list>)>();
|
||||||
|
|
||||||
void __security_init_cookie() {
|
void __security_init_cookie() {
|
||||||
return ___security_init_cookie();
|
return ___security_init_cookie();
|
||||||
}
|
}
|
||||||
|
|
||||||
late final ___security_init_cookiePtr = _lookup<ffi.NativeFunction<ffi.Void Function()>>('__security_init_cookie');
|
late final ___security_init_cookiePtr =
|
||||||
late final ___security_init_cookie = ___security_init_cookiePtr.asFunction<void Function()>();
|
_lookup<ffi.NativeFunction<ffi.Void Function()>>(
|
||||||
|
'__security_init_cookie');
|
||||||
|
late final ___security_init_cookie =
|
||||||
|
___security_init_cookiePtr.asFunction<void Function()>();
|
||||||
|
|
||||||
void __security_check_cookie(
|
void __security_check_cookie(
|
||||||
int _StackCookie,
|
int _StackCookie,
|
||||||
|
|
@ -49,8 +59,10 @@ class TorrentLibrary {
|
||||||
}
|
}
|
||||||
|
|
||||||
late final ___security_check_cookiePtr =
|
late final ___security_check_cookiePtr =
|
||||||
_lookup<ffi.NativeFunction<ffi.Void Function(ffi.UintPtr)>>('__security_check_cookie');
|
_lookup<ffi.NativeFunction<ffi.Void Function(ffi.UintPtr)>>(
|
||||||
late final ___security_check_cookie = ___security_check_cookiePtr.asFunction<void Function(int)>();
|
'__security_check_cookie');
|
||||||
|
late final ___security_check_cookie =
|
||||||
|
___security_check_cookiePtr.asFunction<void Function(int)>();
|
||||||
|
|
||||||
void __report_gsfailure(
|
void __report_gsfailure(
|
||||||
int _StackCookie,
|
int _StackCookie,
|
||||||
|
|
@ -60,10 +72,14 @@ class TorrentLibrary {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
late final ___report_gsfailurePtr = _lookup<ffi.NativeFunction<ffi.Void Function(ffi.UintPtr)>>('__report_gsfailure');
|
late final ___report_gsfailurePtr =
|
||||||
late final ___report_gsfailure = ___report_gsfailurePtr.asFunction<void Function(int)>();
|
_lookup<ffi.NativeFunction<ffi.Void Function(ffi.UintPtr)>>(
|
||||||
|
'__report_gsfailure');
|
||||||
|
late final ___report_gsfailure =
|
||||||
|
___report_gsfailurePtr.asFunction<void Function(int)>();
|
||||||
|
|
||||||
late final ffi.Pointer<ffi.UintPtr> ___security_cookie = _lookup<ffi.UintPtr>('__security_cookie');
|
late final ffi.Pointer<ffi.UintPtr> ___security_cookie =
|
||||||
|
_lookup<ffi.UintPtr>('__security_cookie');
|
||||||
|
|
||||||
int get __security_cookie => ___security_cookie.value;
|
int get __security_cookie => ___security_cookie.value;
|
||||||
|
|
||||||
|
|
@ -74,16 +90,20 @@ class TorrentLibrary {
|
||||||
}
|
}
|
||||||
|
|
||||||
late final __invalid_parameter_noinfoPtr =
|
late final __invalid_parameter_noinfoPtr =
|
||||||
_lookup<ffi.NativeFunction<ffi.Void Function()>>('_invalid_parameter_noinfo');
|
_lookup<ffi.NativeFunction<ffi.Void Function()>>(
|
||||||
late final __invalid_parameter_noinfo = __invalid_parameter_noinfoPtr.asFunction<void Function()>();
|
'_invalid_parameter_noinfo');
|
||||||
|
late final __invalid_parameter_noinfo =
|
||||||
|
__invalid_parameter_noinfoPtr.asFunction<void Function()>();
|
||||||
|
|
||||||
void _invalid_parameter_noinfo_noreturn() {
|
void _invalid_parameter_noinfo_noreturn() {
|
||||||
return __invalid_parameter_noinfo_noreturn();
|
return __invalid_parameter_noinfo_noreturn();
|
||||||
}
|
}
|
||||||
|
|
||||||
late final __invalid_parameter_noinfo_noreturnPtr =
|
late final __invalid_parameter_noinfo_noreturnPtr =
|
||||||
_lookup<ffi.NativeFunction<ffi.Void Function()>>('_invalid_parameter_noinfo_noreturn');
|
_lookup<ffi.NativeFunction<ffi.Void Function()>>(
|
||||||
late final __invalid_parameter_noinfo_noreturn = __invalid_parameter_noinfo_noreturnPtr.asFunction<void Function()>();
|
'_invalid_parameter_noinfo_noreturn');
|
||||||
|
late final __invalid_parameter_noinfo_noreturn =
|
||||||
|
__invalid_parameter_noinfo_noreturnPtr.asFunction<void Function()>();
|
||||||
|
|
||||||
void _invoke_watson(
|
void _invoke_watson(
|
||||||
ffi.Pointer<ffi.WChar> _Expression,
|
ffi.Pointer<ffi.WChar> _Expression,
|
||||||
|
|
@ -103,16 +123,22 @@ class TorrentLibrary {
|
||||||
|
|
||||||
late final __invoke_watsonPtr = _lookup<
|
late final __invoke_watsonPtr = _lookup<
|
||||||
ffi.NativeFunction<
|
ffi.NativeFunction<
|
||||||
ffi.Void Function(ffi.Pointer<ffi.WChar>, ffi.Pointer<ffi.WChar>, ffi.Pointer<ffi.WChar>, ffi.UnsignedInt,
|
ffi.Void Function(
|
||||||
|
ffi.Pointer<ffi.WChar>,
|
||||||
|
ffi.Pointer<ffi.WChar>,
|
||||||
|
ffi.Pointer<ffi.WChar>,
|
||||||
|
ffi.UnsignedInt,
|
||||||
ffi.UintPtr)>>('_invoke_watson');
|
ffi.UintPtr)>>('_invoke_watson');
|
||||||
late final __invoke_watson = __invoke_watsonPtr
|
late final __invoke_watson = __invoke_watsonPtr.asFunction<
|
||||||
.asFunction<void Function(ffi.Pointer<ffi.WChar>, ffi.Pointer<ffi.WChar>, ffi.Pointer<ffi.WChar>, int, int)>();
|
void Function(ffi.Pointer<ffi.WChar>, ffi.Pointer<ffi.WChar>,
|
||||||
|
ffi.Pointer<ffi.WChar>, int, int)>();
|
||||||
|
|
||||||
ffi.Pointer<ffi.Int> _errno() {
|
ffi.Pointer<ffi.Int> _errno() {
|
||||||
return __errno();
|
return __errno();
|
||||||
}
|
}
|
||||||
|
|
||||||
late final __errnoPtr = _lookup<ffi.NativeFunction<ffi.Pointer<ffi.Int> Function()>>('_errno');
|
late final __errnoPtr =
|
||||||
|
_lookup<ffi.NativeFunction<ffi.Pointer<ffi.Int> Function()>>('_errno');
|
||||||
late final __errno = __errnoPtr.asFunction<ffi.Pointer<ffi.Int> Function()>();
|
late final __errno = __errnoPtr.asFunction<ffi.Pointer<ffi.Int> Function()>();
|
||||||
|
|
||||||
int _set_errno(
|
int _set_errno(
|
||||||
|
|
@ -123,7 +149,8 @@ class TorrentLibrary {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
late final __set_errnoPtr = _lookup<ffi.NativeFunction<errno_t Function(ffi.Int)>>('_set_errno');
|
late final __set_errnoPtr =
|
||||||
|
_lookup<ffi.NativeFunction<errno_t Function(ffi.Int)>>('_set_errno');
|
||||||
late final __set_errno = __set_errnoPtr.asFunction<int Function(int)>();
|
late final __set_errno = __set_errnoPtr.asFunction<int Function(int)>();
|
||||||
|
|
||||||
int _get_errno(
|
int _get_errno(
|
||||||
|
|
@ -134,21 +161,26 @@ class TorrentLibrary {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
late final __get_errnoPtr = _lookup<ffi.NativeFunction<errno_t Function(ffi.Pointer<ffi.Int>)>>('_get_errno');
|
late final __get_errnoPtr =
|
||||||
late final __get_errno = __get_errnoPtr.asFunction<int Function(ffi.Pointer<ffi.Int>)>();
|
_lookup<ffi.NativeFunction<errno_t Function(ffi.Pointer<ffi.Int>)>>(
|
||||||
|
'_get_errno');
|
||||||
|
late final __get_errno =
|
||||||
|
__get_errnoPtr.asFunction<int Function(ffi.Pointer<ffi.Int>)>();
|
||||||
|
|
||||||
int __threadid() {
|
int __threadid() {
|
||||||
return ___threadid();
|
return ___threadid();
|
||||||
}
|
}
|
||||||
|
|
||||||
late final ___threadidPtr = _lookup<ffi.NativeFunction<ffi.UnsignedLong Function()>>('__threadid');
|
late final ___threadidPtr =
|
||||||
|
_lookup<ffi.NativeFunction<ffi.UnsignedLong Function()>>('__threadid');
|
||||||
late final ___threadid = ___threadidPtr.asFunction<int Function()>();
|
late final ___threadid = ___threadidPtr.asFunction<int Function()>();
|
||||||
|
|
||||||
int __threadhandle() {
|
int __threadhandle() {
|
||||||
return ___threadhandle();
|
return ___threadhandle();
|
||||||
}
|
}
|
||||||
|
|
||||||
late final ___threadhandlePtr = _lookup<ffi.NativeFunction<ffi.UintPtr Function()>>('__threadhandle');
|
late final ___threadhandlePtr =
|
||||||
|
_lookup<ffi.NativeFunction<ffi.UintPtr Function()>>('__threadhandle');
|
||||||
late final ___threadhandle = ___threadhandlePtr.asFunction<int Function()>();
|
late final ___threadhandle = ___threadhandlePtr.asFunction<int Function()>();
|
||||||
|
|
||||||
double cabs(
|
double cabs(
|
||||||
|
|
@ -159,7 +191,8 @@ class TorrentLibrary {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
late final _cabsPtr = _lookup<ffi.NativeFunction<ffi.Double Function(_Dcomplex)>>('cabs');
|
late final _cabsPtr =
|
||||||
|
_lookup<ffi.NativeFunction<ffi.Double Function(_Dcomplex)>>('cabs');
|
||||||
late final _cabs = _cabsPtr.asFunction<double Function(_Dcomplex)>();
|
late final _cabs = _cabsPtr.asFunction<double Function(_Dcomplex)>();
|
||||||
|
|
||||||
_Dcomplex cacos(
|
_Dcomplex cacos(
|
||||||
|
|
@ -170,7 +203,8 @@ class TorrentLibrary {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
late final _cacosPtr = _lookup<ffi.NativeFunction<_Dcomplex Function(_Dcomplex)>>('cacos');
|
late final _cacosPtr =
|
||||||
|
_lookup<ffi.NativeFunction<_Dcomplex Function(_Dcomplex)>>('cacos');
|
||||||
late final _cacos = _cacosPtr.asFunction<_Dcomplex Function(_Dcomplex)>();
|
late final _cacos = _cacosPtr.asFunction<_Dcomplex Function(_Dcomplex)>();
|
||||||
|
|
||||||
_Dcomplex cacosh(
|
_Dcomplex cacosh(
|
||||||
|
|
@ -181,7 +215,8 @@ class TorrentLibrary {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
late final _cacoshPtr = _lookup<ffi.NativeFunction<_Dcomplex Function(_Dcomplex)>>('cacosh');
|
late final _cacoshPtr =
|
||||||
|
_lookup<ffi.NativeFunction<_Dcomplex Function(_Dcomplex)>>('cacosh');
|
||||||
late final _cacosh = _cacoshPtr.asFunction<_Dcomplex Function(_Dcomplex)>();
|
late final _cacosh = _cacoshPtr.asFunction<_Dcomplex Function(_Dcomplex)>();
|
||||||
|
|
||||||
double carg(
|
double carg(
|
||||||
|
|
@ -192,7 +227,8 @@ class TorrentLibrary {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
late final _cargPtr = _lookup<ffi.NativeFunction<ffi.Double Function(_Dcomplex)>>('carg');
|
late final _cargPtr =
|
||||||
|
_lookup<ffi.NativeFunction<ffi.Double Function(_Dcomplex)>>('carg');
|
||||||
late final _carg = _cargPtr.asFunction<double Function(_Dcomplex)>();
|
late final _carg = _cargPtr.asFunction<double Function(_Dcomplex)>();
|
||||||
|
|
||||||
_Dcomplex casin(
|
_Dcomplex casin(
|
||||||
|
|
@ -203,7 +239,8 @@ class TorrentLibrary {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
late final _casinPtr = _lookup<ffi.NativeFunction<_Dcomplex Function(_Dcomplex)>>('casin');
|
late final _casinPtr =
|
||||||
|
_lookup<ffi.NativeFunction<_Dcomplex Function(_Dcomplex)>>('casin');
|
||||||
late final _casin = _casinPtr.asFunction<_Dcomplex Function(_Dcomplex)>();
|
late final _casin = _casinPtr.asFunction<_Dcomplex Function(_Dcomplex)>();
|
||||||
|
|
||||||
_Dcomplex casinh(
|
_Dcomplex casinh(
|
||||||
|
|
@ -214,7 +251,8 @@ class TorrentLibrary {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
late final _casinhPtr = _lookup<ffi.NativeFunction<_Dcomplex Function(_Dcomplex)>>('casinh');
|
late final _casinhPtr =
|
||||||
|
_lookup<ffi.NativeFunction<_Dcomplex Function(_Dcomplex)>>('casinh');
|
||||||
late final _casinh = _casinhPtr.asFunction<_Dcomplex Function(_Dcomplex)>();
|
late final _casinh = _casinhPtr.asFunction<_Dcomplex Function(_Dcomplex)>();
|
||||||
|
|
||||||
_Dcomplex catan(
|
_Dcomplex catan(
|
||||||
|
|
@ -225,7 +263,8 @@ class TorrentLibrary {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
late final _catanPtr = _lookup<ffi.NativeFunction<_Dcomplex Function(_Dcomplex)>>('catan');
|
late final _catanPtr =
|
||||||
|
_lookup<ffi.NativeFunction<_Dcomplex Function(_Dcomplex)>>('catan');
|
||||||
late final _catan = _catanPtr.asFunction<_Dcomplex Function(_Dcomplex)>();
|
late final _catan = _catanPtr.asFunction<_Dcomplex Function(_Dcomplex)>();
|
||||||
|
|
||||||
_Dcomplex catanh(
|
_Dcomplex catanh(
|
||||||
|
|
@ -236,7 +275,8 @@ class TorrentLibrary {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
late final _catanhPtr = _lookup<ffi.NativeFunction<_Dcomplex Function(_Dcomplex)>>('catanh');
|
late final _catanhPtr =
|
||||||
|
_lookup<ffi.NativeFunction<_Dcomplex Function(_Dcomplex)>>('catanh');
|
||||||
late final _catanh = _catanhPtr.asFunction<_Dcomplex Function(_Dcomplex)>();
|
late final _catanh = _catanhPtr.asFunction<_Dcomplex Function(_Dcomplex)>();
|
||||||
|
|
||||||
_Dcomplex ccos(
|
_Dcomplex ccos(
|
||||||
|
|
@ -247,7 +287,8 @@ class TorrentLibrary {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
late final _ccosPtr = _lookup<ffi.NativeFunction<_Dcomplex Function(_Dcomplex)>>('ccos');
|
late final _ccosPtr =
|
||||||
|
_lookup<ffi.NativeFunction<_Dcomplex Function(_Dcomplex)>>('ccos');
|
||||||
late final _ccos = _ccosPtr.asFunction<_Dcomplex Function(_Dcomplex)>();
|
late final _ccos = _ccosPtr.asFunction<_Dcomplex Function(_Dcomplex)>();
|
||||||
|
|
||||||
_Dcomplex ccosh(
|
_Dcomplex ccosh(
|
||||||
|
|
@ -258,7 +299,8 @@ class TorrentLibrary {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
late final _ccoshPtr = _lookup<ffi.NativeFunction<_Dcomplex Function(_Dcomplex)>>('ccosh');
|
late final _ccoshPtr =
|
||||||
|
_lookup<ffi.NativeFunction<_Dcomplex Function(_Dcomplex)>>('ccosh');
|
||||||
late final _ccosh = _ccoshPtr.asFunction<_Dcomplex Function(_Dcomplex)>();
|
late final _ccosh = _ccoshPtr.asFunction<_Dcomplex Function(_Dcomplex)>();
|
||||||
|
|
||||||
_Dcomplex cexp(
|
_Dcomplex cexp(
|
||||||
|
|
@ -269,7 +311,8 @@ class TorrentLibrary {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
late final _cexpPtr = _lookup<ffi.NativeFunction<_Dcomplex Function(_Dcomplex)>>('cexp');
|
late final _cexpPtr =
|
||||||
|
_lookup<ffi.NativeFunction<_Dcomplex Function(_Dcomplex)>>('cexp');
|
||||||
late final _cexp = _cexpPtr.asFunction<_Dcomplex Function(_Dcomplex)>();
|
late final _cexp = _cexpPtr.asFunction<_Dcomplex Function(_Dcomplex)>();
|
||||||
|
|
||||||
double cimag(
|
double cimag(
|
||||||
|
|
@ -280,7 +323,8 @@ class TorrentLibrary {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
late final _cimagPtr = _lookup<ffi.NativeFunction<ffi.Double Function(_Dcomplex)>>('cimag');
|
late final _cimagPtr =
|
||||||
|
_lookup<ffi.NativeFunction<ffi.Double Function(_Dcomplex)>>('cimag');
|
||||||
late final _cimag = _cimagPtr.asFunction<double Function(_Dcomplex)>();
|
late final _cimag = _cimagPtr.asFunction<double Function(_Dcomplex)>();
|
||||||
|
|
||||||
_Dcomplex clog(
|
_Dcomplex clog(
|
||||||
|
|
@ -291,7 +335,8 @@ class TorrentLibrary {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
late final _clogPtr = _lookup<ffi.NativeFunction<_Dcomplex Function(_Dcomplex)>>('clog');
|
late final _clogPtr =
|
||||||
|
_lookup<ffi.NativeFunction<_Dcomplex Function(_Dcomplex)>>('clog');
|
||||||
late final _clog = _clogPtr.asFunction<_Dcomplex Function(_Dcomplex)>();
|
late final _clog = _clogPtr.asFunction<_Dcomplex Function(_Dcomplex)>();
|
||||||
|
|
||||||
_Dcomplex clog10(
|
_Dcomplex clog10(
|
||||||
|
|
@ -302,7 +347,8 @@ class TorrentLibrary {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
late final _clog10Ptr = _lookup<ffi.NativeFunction<_Dcomplex Function(_Dcomplex)>>('clog10');
|
late final _clog10Ptr =
|
||||||
|
_lookup<ffi.NativeFunction<_Dcomplex Function(_Dcomplex)>>('clog10');
|
||||||
late final _clog10 = _clog10Ptr.asFunction<_Dcomplex Function(_Dcomplex)>();
|
late final _clog10 = _clog10Ptr.asFunction<_Dcomplex Function(_Dcomplex)>();
|
||||||
|
|
||||||
_Dcomplex conj(
|
_Dcomplex conj(
|
||||||
|
|
@ -313,7 +359,8 @@ class TorrentLibrary {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
late final _conjPtr = _lookup<ffi.NativeFunction<_Dcomplex Function(_Dcomplex)>>('conj');
|
late final _conjPtr =
|
||||||
|
_lookup<ffi.NativeFunction<_Dcomplex Function(_Dcomplex)>>('conj');
|
||||||
late final _conj = _conjPtr.asFunction<_Dcomplex Function(_Dcomplex)>();
|
late final _conj = _conjPtr.asFunction<_Dcomplex Function(_Dcomplex)>();
|
||||||
|
|
||||||
_Dcomplex cpow(
|
_Dcomplex cpow(
|
||||||
|
|
@ -326,8 +373,11 @@ class TorrentLibrary {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
late final _cpowPtr = _lookup<ffi.NativeFunction<_Dcomplex Function(_Dcomplex, _Dcomplex)>>('cpow');
|
late final _cpowPtr =
|
||||||
late final _cpow = _cpowPtr.asFunction<_Dcomplex Function(_Dcomplex, _Dcomplex)>();
|
_lookup<ffi.NativeFunction<_Dcomplex Function(_Dcomplex, _Dcomplex)>>(
|
||||||
|
'cpow');
|
||||||
|
late final _cpow =
|
||||||
|
_cpowPtr.asFunction<_Dcomplex Function(_Dcomplex, _Dcomplex)>();
|
||||||
|
|
||||||
_Dcomplex cproj(
|
_Dcomplex cproj(
|
||||||
_Dcomplex _Z,
|
_Dcomplex _Z,
|
||||||
|
|
@ -337,7 +387,8 @@ class TorrentLibrary {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
late final _cprojPtr = _lookup<ffi.NativeFunction<_Dcomplex Function(_Dcomplex)>>('cproj');
|
late final _cprojPtr =
|
||||||
|
_lookup<ffi.NativeFunction<_Dcomplex Function(_Dcomplex)>>('cproj');
|
||||||
late final _cproj = _cprojPtr.asFunction<_Dcomplex Function(_Dcomplex)>();
|
late final _cproj = _cprojPtr.asFunction<_Dcomplex Function(_Dcomplex)>();
|
||||||
|
|
||||||
double creal(
|
double creal(
|
||||||
|
|
@ -348,7 +399,8 @@ class TorrentLibrary {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
late final _crealPtr = _lookup<ffi.NativeFunction<ffi.Double Function(_Dcomplex)>>('creal');
|
late final _crealPtr =
|
||||||
|
_lookup<ffi.NativeFunction<ffi.Double Function(_Dcomplex)>>('creal');
|
||||||
late final _creal = _crealPtr.asFunction<double Function(_Dcomplex)>();
|
late final _creal = _crealPtr.asFunction<double Function(_Dcomplex)>();
|
||||||
|
|
||||||
_Dcomplex csin(
|
_Dcomplex csin(
|
||||||
|
|
@ -359,7 +411,8 @@ class TorrentLibrary {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
late final _csinPtr = _lookup<ffi.NativeFunction<_Dcomplex Function(_Dcomplex)>>('csin');
|
late final _csinPtr =
|
||||||
|
_lookup<ffi.NativeFunction<_Dcomplex Function(_Dcomplex)>>('csin');
|
||||||
late final _csin = _csinPtr.asFunction<_Dcomplex Function(_Dcomplex)>();
|
late final _csin = _csinPtr.asFunction<_Dcomplex Function(_Dcomplex)>();
|
||||||
|
|
||||||
_Dcomplex csinh(
|
_Dcomplex csinh(
|
||||||
|
|
@ -370,7 +423,8 @@ class TorrentLibrary {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
late final _csinhPtr = _lookup<ffi.NativeFunction<_Dcomplex Function(_Dcomplex)>>('csinh');
|
late final _csinhPtr =
|
||||||
|
_lookup<ffi.NativeFunction<_Dcomplex Function(_Dcomplex)>>('csinh');
|
||||||
late final _csinh = _csinhPtr.asFunction<_Dcomplex Function(_Dcomplex)>();
|
late final _csinh = _csinhPtr.asFunction<_Dcomplex Function(_Dcomplex)>();
|
||||||
|
|
||||||
_Dcomplex csqrt(
|
_Dcomplex csqrt(
|
||||||
|
|
@ -381,7 +435,8 @@ class TorrentLibrary {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
late final _csqrtPtr = _lookup<ffi.NativeFunction<_Dcomplex Function(_Dcomplex)>>('csqrt');
|
late final _csqrtPtr =
|
||||||
|
_lookup<ffi.NativeFunction<_Dcomplex Function(_Dcomplex)>>('csqrt');
|
||||||
late final _csqrt = _csqrtPtr.asFunction<_Dcomplex Function(_Dcomplex)>();
|
late final _csqrt = _csqrtPtr.asFunction<_Dcomplex Function(_Dcomplex)>();
|
||||||
|
|
||||||
_Dcomplex ctan(
|
_Dcomplex ctan(
|
||||||
|
|
@ -392,7 +447,8 @@ class TorrentLibrary {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
late final _ctanPtr = _lookup<ffi.NativeFunction<_Dcomplex Function(_Dcomplex)>>('ctan');
|
late final _ctanPtr =
|
||||||
|
_lookup<ffi.NativeFunction<_Dcomplex Function(_Dcomplex)>>('ctan');
|
||||||
late final _ctan = _ctanPtr.asFunction<_Dcomplex Function(_Dcomplex)>();
|
late final _ctan = _ctanPtr.asFunction<_Dcomplex Function(_Dcomplex)>();
|
||||||
|
|
||||||
_Dcomplex ctanh(
|
_Dcomplex ctanh(
|
||||||
|
|
@ -403,7 +459,8 @@ class TorrentLibrary {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
late final _ctanhPtr = _lookup<ffi.NativeFunction<_Dcomplex Function(_Dcomplex)>>('ctanh');
|
late final _ctanhPtr =
|
||||||
|
_lookup<ffi.NativeFunction<_Dcomplex Function(_Dcomplex)>>('ctanh');
|
||||||
late final _ctanh = _ctanhPtr.asFunction<_Dcomplex Function(_Dcomplex)>();
|
late final _ctanh = _ctanhPtr.asFunction<_Dcomplex Function(_Dcomplex)>();
|
||||||
|
|
||||||
double norm(
|
double norm(
|
||||||
|
|
@ -414,7 +471,8 @@ class TorrentLibrary {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
late final _normPtr = _lookup<ffi.NativeFunction<ffi.Double Function(_Dcomplex)>>('norm');
|
late final _normPtr =
|
||||||
|
_lookup<ffi.NativeFunction<ffi.Double Function(_Dcomplex)>>('norm');
|
||||||
late final _norm = _normPtr.asFunction<double Function(_Dcomplex)>();
|
late final _norm = _normPtr.asFunction<double Function(_Dcomplex)>();
|
||||||
|
|
||||||
double cabsf(
|
double cabsf(
|
||||||
|
|
@ -425,7 +483,8 @@ class TorrentLibrary {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
late final _cabsfPtr = _lookup<ffi.NativeFunction<ffi.Float Function(_Fcomplex)>>('cabsf');
|
late final _cabsfPtr =
|
||||||
|
_lookup<ffi.NativeFunction<ffi.Float Function(_Fcomplex)>>('cabsf');
|
||||||
late final _cabsf = _cabsfPtr.asFunction<double Function(_Fcomplex)>();
|
late final _cabsf = _cabsfPtr.asFunction<double Function(_Fcomplex)>();
|
||||||
|
|
||||||
_Fcomplex cacosf(
|
_Fcomplex cacosf(
|
||||||
|
|
@ -436,7 +495,8 @@ class TorrentLibrary {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
late final _cacosfPtr = _lookup<ffi.NativeFunction<_Fcomplex Function(_Fcomplex)>>('cacosf');
|
late final _cacosfPtr =
|
||||||
|
_lookup<ffi.NativeFunction<_Fcomplex Function(_Fcomplex)>>('cacosf');
|
||||||
late final _cacosf = _cacosfPtr.asFunction<_Fcomplex Function(_Fcomplex)>();
|
late final _cacosf = _cacosfPtr.asFunction<_Fcomplex Function(_Fcomplex)>();
|
||||||
|
|
||||||
_Fcomplex cacoshf(
|
_Fcomplex cacoshf(
|
||||||
|
|
@ -447,7 +507,8 @@ class TorrentLibrary {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
late final _cacoshfPtr = _lookup<ffi.NativeFunction<_Fcomplex Function(_Fcomplex)>>('cacoshf');
|
late final _cacoshfPtr =
|
||||||
|
_lookup<ffi.NativeFunction<_Fcomplex Function(_Fcomplex)>>('cacoshf');
|
||||||
late final _cacoshf = _cacoshfPtr.asFunction<_Fcomplex Function(_Fcomplex)>();
|
late final _cacoshf = _cacoshfPtr.asFunction<_Fcomplex Function(_Fcomplex)>();
|
||||||
|
|
||||||
double cargf(
|
double cargf(
|
||||||
|
|
@ -458,7 +519,8 @@ class TorrentLibrary {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
late final _cargfPtr = _lookup<ffi.NativeFunction<ffi.Float Function(_Fcomplex)>>('cargf');
|
late final _cargfPtr =
|
||||||
|
_lookup<ffi.NativeFunction<ffi.Float Function(_Fcomplex)>>('cargf');
|
||||||
late final _cargf = _cargfPtr.asFunction<double Function(_Fcomplex)>();
|
late final _cargf = _cargfPtr.asFunction<double Function(_Fcomplex)>();
|
||||||
|
|
||||||
_Fcomplex casinf(
|
_Fcomplex casinf(
|
||||||
|
|
@ -469,7 +531,8 @@ class TorrentLibrary {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
late final _casinfPtr = _lookup<ffi.NativeFunction<_Fcomplex Function(_Fcomplex)>>('casinf');
|
late final _casinfPtr =
|
||||||
|
_lookup<ffi.NativeFunction<_Fcomplex Function(_Fcomplex)>>('casinf');
|
||||||
late final _casinf = _casinfPtr.asFunction<_Fcomplex Function(_Fcomplex)>();
|
late final _casinf = _casinfPtr.asFunction<_Fcomplex Function(_Fcomplex)>();
|
||||||
|
|
||||||
_Fcomplex casinhf(
|
_Fcomplex casinhf(
|
||||||
|
|
@ -480,7 +543,8 @@ class TorrentLibrary {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
late final _casinhfPtr = _lookup<ffi.NativeFunction<_Fcomplex Function(_Fcomplex)>>('casinhf');
|
late final _casinhfPtr =
|
||||||
|
_lookup<ffi.NativeFunction<_Fcomplex Function(_Fcomplex)>>('casinhf');
|
||||||
late final _casinhf = _casinhfPtr.asFunction<_Fcomplex Function(_Fcomplex)>();
|
late final _casinhf = _casinhfPtr.asFunction<_Fcomplex Function(_Fcomplex)>();
|
||||||
|
|
||||||
_Fcomplex catanf(
|
_Fcomplex catanf(
|
||||||
|
|
@ -491,7 +555,8 @@ class TorrentLibrary {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
late final _catanfPtr = _lookup<ffi.NativeFunction<_Fcomplex Function(_Fcomplex)>>('catanf');
|
late final _catanfPtr =
|
||||||
|
_lookup<ffi.NativeFunction<_Fcomplex Function(_Fcomplex)>>('catanf');
|
||||||
late final _catanf = _catanfPtr.asFunction<_Fcomplex Function(_Fcomplex)>();
|
late final _catanf = _catanfPtr.asFunction<_Fcomplex Function(_Fcomplex)>();
|
||||||
|
|
||||||
_Fcomplex catanhf(
|
_Fcomplex catanhf(
|
||||||
|
|
@ -502,7 +567,8 @@ class TorrentLibrary {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
late final _catanhfPtr = _lookup<ffi.NativeFunction<_Fcomplex Function(_Fcomplex)>>('catanhf');
|
late final _catanhfPtr =
|
||||||
|
_lookup<ffi.NativeFunction<_Fcomplex Function(_Fcomplex)>>('catanhf');
|
||||||
late final _catanhf = _catanhfPtr.asFunction<_Fcomplex Function(_Fcomplex)>();
|
late final _catanhf = _catanhfPtr.asFunction<_Fcomplex Function(_Fcomplex)>();
|
||||||
|
|
||||||
_Fcomplex ccosf(
|
_Fcomplex ccosf(
|
||||||
|
|
@ -513,7 +579,8 @@ class TorrentLibrary {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
late final _ccosfPtr = _lookup<ffi.NativeFunction<_Fcomplex Function(_Fcomplex)>>('ccosf');
|
late final _ccosfPtr =
|
||||||
|
_lookup<ffi.NativeFunction<_Fcomplex Function(_Fcomplex)>>('ccosf');
|
||||||
late final _ccosf = _ccosfPtr.asFunction<_Fcomplex Function(_Fcomplex)>();
|
late final _ccosf = _ccosfPtr.asFunction<_Fcomplex Function(_Fcomplex)>();
|
||||||
|
|
||||||
_Fcomplex ccoshf(
|
_Fcomplex ccoshf(
|
||||||
|
|
@ -524,7 +591,8 @@ class TorrentLibrary {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
late final _ccoshfPtr = _lookup<ffi.NativeFunction<_Fcomplex Function(_Fcomplex)>>('ccoshf');
|
late final _ccoshfPtr =
|
||||||
|
_lookup<ffi.NativeFunction<_Fcomplex Function(_Fcomplex)>>('ccoshf');
|
||||||
late final _ccoshf = _ccoshfPtr.asFunction<_Fcomplex Function(_Fcomplex)>();
|
late final _ccoshf = _ccoshfPtr.asFunction<_Fcomplex Function(_Fcomplex)>();
|
||||||
|
|
||||||
_Fcomplex cexpf(
|
_Fcomplex cexpf(
|
||||||
|
|
@ -535,7 +603,8 @@ class TorrentLibrary {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
late final _cexpfPtr = _lookup<ffi.NativeFunction<_Fcomplex Function(_Fcomplex)>>('cexpf');
|
late final _cexpfPtr =
|
||||||
|
_lookup<ffi.NativeFunction<_Fcomplex Function(_Fcomplex)>>('cexpf');
|
||||||
late final _cexpf = _cexpfPtr.asFunction<_Fcomplex Function(_Fcomplex)>();
|
late final _cexpf = _cexpfPtr.asFunction<_Fcomplex Function(_Fcomplex)>();
|
||||||
|
|
||||||
double cimagf(
|
double cimagf(
|
||||||
|
|
@ -546,7 +615,8 @@ class TorrentLibrary {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
late final _cimagfPtr = _lookup<ffi.NativeFunction<ffi.Float Function(_Fcomplex)>>('cimagf');
|
late final _cimagfPtr =
|
||||||
|
_lookup<ffi.NativeFunction<ffi.Float Function(_Fcomplex)>>('cimagf');
|
||||||
late final _cimagf = _cimagfPtr.asFunction<double Function(_Fcomplex)>();
|
late final _cimagf = _cimagfPtr.asFunction<double Function(_Fcomplex)>();
|
||||||
|
|
||||||
_Fcomplex clogf(
|
_Fcomplex clogf(
|
||||||
|
|
@ -557,7 +627,8 @@ class TorrentLibrary {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
late final _clogfPtr = _lookup<ffi.NativeFunction<_Fcomplex Function(_Fcomplex)>>('clogf');
|
late final _clogfPtr =
|
||||||
|
_lookup<ffi.NativeFunction<_Fcomplex Function(_Fcomplex)>>('clogf');
|
||||||
late final _clogf = _clogfPtr.asFunction<_Fcomplex Function(_Fcomplex)>();
|
late final _clogf = _clogfPtr.asFunction<_Fcomplex Function(_Fcomplex)>();
|
||||||
|
|
||||||
_Fcomplex clog10f(
|
_Fcomplex clog10f(
|
||||||
|
|
@ -568,7 +639,8 @@ class TorrentLibrary {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
late final _clog10fPtr = _lookup<ffi.NativeFunction<_Fcomplex Function(_Fcomplex)>>('clog10f');
|
late final _clog10fPtr =
|
||||||
|
_lookup<ffi.NativeFunction<_Fcomplex Function(_Fcomplex)>>('clog10f');
|
||||||
late final _clog10f = _clog10fPtr.asFunction<_Fcomplex Function(_Fcomplex)>();
|
late final _clog10f = _clog10fPtr.asFunction<_Fcomplex Function(_Fcomplex)>();
|
||||||
|
|
||||||
_Fcomplex conjf(
|
_Fcomplex conjf(
|
||||||
|
|
@ -579,7 +651,8 @@ class TorrentLibrary {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
late final _conjfPtr = _lookup<ffi.NativeFunction<_Fcomplex Function(_Fcomplex)>>('conjf');
|
late final _conjfPtr =
|
||||||
|
_lookup<ffi.NativeFunction<_Fcomplex Function(_Fcomplex)>>('conjf');
|
||||||
late final _conjf = _conjfPtr.asFunction<_Fcomplex Function(_Fcomplex)>();
|
late final _conjf = _conjfPtr.asFunction<_Fcomplex Function(_Fcomplex)>();
|
||||||
|
|
||||||
_Fcomplex cpowf(
|
_Fcomplex cpowf(
|
||||||
|
|
@ -592,8 +665,11 @@ class TorrentLibrary {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
late final _cpowfPtr = _lookup<ffi.NativeFunction<_Fcomplex Function(_Fcomplex, _Fcomplex)>>('cpowf');
|
late final _cpowfPtr =
|
||||||
late final _cpowf = _cpowfPtr.asFunction<_Fcomplex Function(_Fcomplex, _Fcomplex)>();
|
_lookup<ffi.NativeFunction<_Fcomplex Function(_Fcomplex, _Fcomplex)>>(
|
||||||
|
'cpowf');
|
||||||
|
late final _cpowf =
|
||||||
|
_cpowfPtr.asFunction<_Fcomplex Function(_Fcomplex, _Fcomplex)>();
|
||||||
|
|
||||||
_Fcomplex cprojf(
|
_Fcomplex cprojf(
|
||||||
_Fcomplex _Z,
|
_Fcomplex _Z,
|
||||||
|
|
@ -603,7 +679,8 @@ class TorrentLibrary {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
late final _cprojfPtr = _lookup<ffi.NativeFunction<_Fcomplex Function(_Fcomplex)>>('cprojf');
|
late final _cprojfPtr =
|
||||||
|
_lookup<ffi.NativeFunction<_Fcomplex Function(_Fcomplex)>>('cprojf');
|
||||||
late final _cprojf = _cprojfPtr.asFunction<_Fcomplex Function(_Fcomplex)>();
|
late final _cprojf = _cprojfPtr.asFunction<_Fcomplex Function(_Fcomplex)>();
|
||||||
|
|
||||||
double crealf(
|
double crealf(
|
||||||
|
|
@ -614,7 +691,8 @@ class TorrentLibrary {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
late final _crealfPtr = _lookup<ffi.NativeFunction<ffi.Float Function(_Fcomplex)>>('crealf');
|
late final _crealfPtr =
|
||||||
|
_lookup<ffi.NativeFunction<ffi.Float Function(_Fcomplex)>>('crealf');
|
||||||
late final _crealf = _crealfPtr.asFunction<double Function(_Fcomplex)>();
|
late final _crealf = _crealfPtr.asFunction<double Function(_Fcomplex)>();
|
||||||
|
|
||||||
_Fcomplex csinf(
|
_Fcomplex csinf(
|
||||||
|
|
@ -625,7 +703,8 @@ class TorrentLibrary {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
late final _csinfPtr = _lookup<ffi.NativeFunction<_Fcomplex Function(_Fcomplex)>>('csinf');
|
late final _csinfPtr =
|
||||||
|
_lookup<ffi.NativeFunction<_Fcomplex Function(_Fcomplex)>>('csinf');
|
||||||
late final _csinf = _csinfPtr.asFunction<_Fcomplex Function(_Fcomplex)>();
|
late final _csinf = _csinfPtr.asFunction<_Fcomplex Function(_Fcomplex)>();
|
||||||
|
|
||||||
_Fcomplex csinhf(
|
_Fcomplex csinhf(
|
||||||
|
|
@ -636,7 +715,8 @@ class TorrentLibrary {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
late final _csinhfPtr = _lookup<ffi.NativeFunction<_Fcomplex Function(_Fcomplex)>>('csinhf');
|
late final _csinhfPtr =
|
||||||
|
_lookup<ffi.NativeFunction<_Fcomplex Function(_Fcomplex)>>('csinhf');
|
||||||
late final _csinhf = _csinhfPtr.asFunction<_Fcomplex Function(_Fcomplex)>();
|
late final _csinhf = _csinhfPtr.asFunction<_Fcomplex Function(_Fcomplex)>();
|
||||||
|
|
||||||
_Fcomplex csqrtf(
|
_Fcomplex csqrtf(
|
||||||
|
|
@ -647,7 +727,8 @@ class TorrentLibrary {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
late final _csqrtfPtr = _lookup<ffi.NativeFunction<_Fcomplex Function(_Fcomplex)>>('csqrtf');
|
late final _csqrtfPtr =
|
||||||
|
_lookup<ffi.NativeFunction<_Fcomplex Function(_Fcomplex)>>('csqrtf');
|
||||||
late final _csqrtf = _csqrtfPtr.asFunction<_Fcomplex Function(_Fcomplex)>();
|
late final _csqrtf = _csqrtfPtr.asFunction<_Fcomplex Function(_Fcomplex)>();
|
||||||
|
|
||||||
_Fcomplex ctanf(
|
_Fcomplex ctanf(
|
||||||
|
|
@ -658,7 +739,8 @@ class TorrentLibrary {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
late final _ctanfPtr = _lookup<ffi.NativeFunction<_Fcomplex Function(_Fcomplex)>>('ctanf');
|
late final _ctanfPtr =
|
||||||
|
_lookup<ffi.NativeFunction<_Fcomplex Function(_Fcomplex)>>('ctanf');
|
||||||
late final _ctanf = _ctanfPtr.asFunction<_Fcomplex Function(_Fcomplex)>();
|
late final _ctanf = _ctanfPtr.asFunction<_Fcomplex Function(_Fcomplex)>();
|
||||||
|
|
||||||
_Fcomplex ctanhf(
|
_Fcomplex ctanhf(
|
||||||
|
|
@ -669,7 +751,8 @@ class TorrentLibrary {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
late final _ctanhfPtr = _lookup<ffi.NativeFunction<_Fcomplex Function(_Fcomplex)>>('ctanhf');
|
late final _ctanhfPtr =
|
||||||
|
_lookup<ffi.NativeFunction<_Fcomplex Function(_Fcomplex)>>('ctanhf');
|
||||||
late final _ctanhf = _ctanhfPtr.asFunction<_Fcomplex Function(_Fcomplex)>();
|
late final _ctanhf = _ctanhfPtr.asFunction<_Fcomplex Function(_Fcomplex)>();
|
||||||
|
|
||||||
double normf(
|
double normf(
|
||||||
|
|
@ -680,7 +763,8 @@ class TorrentLibrary {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
late final _normfPtr = _lookup<ffi.NativeFunction<ffi.Float Function(_Fcomplex)>>('normf');
|
late final _normfPtr =
|
||||||
|
_lookup<ffi.NativeFunction<ffi.Float Function(_Fcomplex)>>('normf');
|
||||||
late final _normf = _normfPtr.asFunction<double Function(_Fcomplex)>();
|
late final _normf = _normfPtr.asFunction<double Function(_Fcomplex)>();
|
||||||
|
|
||||||
_Dcomplex _Cbuild(
|
_Dcomplex _Cbuild(
|
||||||
|
|
@ -693,8 +777,11 @@ class TorrentLibrary {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
late final __CbuildPtr = _lookup<ffi.NativeFunction<_Dcomplex Function(ffi.Double, ffi.Double)>>('_Cbuild');
|
late final __CbuildPtr =
|
||||||
late final __Cbuild = __CbuildPtr.asFunction<_Dcomplex Function(double, double)>();
|
_lookup<ffi.NativeFunction<_Dcomplex Function(ffi.Double, ffi.Double)>>(
|
||||||
|
'_Cbuild');
|
||||||
|
late final __Cbuild =
|
||||||
|
__CbuildPtr.asFunction<_Dcomplex Function(double, double)>();
|
||||||
|
|
||||||
_Dcomplex _Cmulcc(
|
_Dcomplex _Cmulcc(
|
||||||
_Dcomplex _X,
|
_Dcomplex _X,
|
||||||
|
|
@ -706,8 +793,11 @@ class TorrentLibrary {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
late final __CmulccPtr = _lookup<ffi.NativeFunction<_Dcomplex Function(_Dcomplex, _Dcomplex)>>('_Cmulcc');
|
late final __CmulccPtr =
|
||||||
late final __Cmulcc = __CmulccPtr.asFunction<_Dcomplex Function(_Dcomplex, _Dcomplex)>();
|
_lookup<ffi.NativeFunction<_Dcomplex Function(_Dcomplex, _Dcomplex)>>(
|
||||||
|
'_Cmulcc');
|
||||||
|
late final __Cmulcc =
|
||||||
|
__CmulccPtr.asFunction<_Dcomplex Function(_Dcomplex, _Dcomplex)>();
|
||||||
|
|
||||||
_Dcomplex _Cmulcr(
|
_Dcomplex _Cmulcr(
|
||||||
_Dcomplex _X,
|
_Dcomplex _X,
|
||||||
|
|
@ -719,8 +809,11 @@ class TorrentLibrary {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
late final __CmulcrPtr = _lookup<ffi.NativeFunction<_Dcomplex Function(_Dcomplex, ffi.Double)>>('_Cmulcr');
|
late final __CmulcrPtr =
|
||||||
late final __Cmulcr = __CmulcrPtr.asFunction<_Dcomplex Function(_Dcomplex, double)>();
|
_lookup<ffi.NativeFunction<_Dcomplex Function(_Dcomplex, ffi.Double)>>(
|
||||||
|
'_Cmulcr');
|
||||||
|
late final __Cmulcr =
|
||||||
|
__CmulcrPtr.asFunction<_Dcomplex Function(_Dcomplex, double)>();
|
||||||
|
|
||||||
_Fcomplex _FCbuild(
|
_Fcomplex _FCbuild(
|
||||||
double _Re,
|
double _Re,
|
||||||
|
|
@ -732,8 +825,11 @@ class TorrentLibrary {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
late final __FCbuildPtr = _lookup<ffi.NativeFunction<_Fcomplex Function(ffi.Float, ffi.Float)>>('_FCbuild');
|
late final __FCbuildPtr =
|
||||||
late final __FCbuild = __FCbuildPtr.asFunction<_Fcomplex Function(double, double)>();
|
_lookup<ffi.NativeFunction<_Fcomplex Function(ffi.Float, ffi.Float)>>(
|
||||||
|
'_FCbuild');
|
||||||
|
late final __FCbuild =
|
||||||
|
__FCbuildPtr.asFunction<_Fcomplex Function(double, double)>();
|
||||||
|
|
||||||
_Fcomplex _FCmulcc(
|
_Fcomplex _FCmulcc(
|
||||||
_Fcomplex _X,
|
_Fcomplex _X,
|
||||||
|
|
@ -745,8 +841,11 @@ class TorrentLibrary {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
late final __FCmulccPtr = _lookup<ffi.NativeFunction<_Fcomplex Function(_Fcomplex, _Fcomplex)>>('_FCmulcc');
|
late final __FCmulccPtr =
|
||||||
late final __FCmulcc = __FCmulccPtr.asFunction<_Fcomplex Function(_Fcomplex, _Fcomplex)>();
|
_lookup<ffi.NativeFunction<_Fcomplex Function(_Fcomplex, _Fcomplex)>>(
|
||||||
|
'_FCmulcc');
|
||||||
|
late final __FCmulcc =
|
||||||
|
__FCmulccPtr.asFunction<_Fcomplex Function(_Fcomplex, _Fcomplex)>();
|
||||||
|
|
||||||
_Fcomplex _FCmulcr(
|
_Fcomplex _FCmulcr(
|
||||||
_Fcomplex _X,
|
_Fcomplex _X,
|
||||||
|
|
@ -758,8 +857,11 @@ class TorrentLibrary {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
late final __FCmulcrPtr = _lookup<ffi.NativeFunction<_Fcomplex Function(_Fcomplex, ffi.Float)>>('_FCmulcr');
|
late final __FCmulcrPtr =
|
||||||
late final __FCmulcr = __FCmulcrPtr.asFunction<_Fcomplex Function(_Fcomplex, double)>();
|
_lookup<ffi.NativeFunction<_Fcomplex Function(_Fcomplex, ffi.Float)>>(
|
||||||
|
'_FCmulcr');
|
||||||
|
late final __FCmulcr =
|
||||||
|
__FCmulcrPtr.asFunction<_Fcomplex Function(_Fcomplex, double)>();
|
||||||
|
|
||||||
Start_return Start(
|
Start_return Start(
|
||||||
ffi.Pointer<ffi.Char> mcfg,
|
ffi.Pointer<ffi.Char> mcfg,
|
||||||
|
|
@ -769,8 +871,11 @@ class TorrentLibrary {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
late final _StartPtr = _lookup<ffi.NativeFunction<Start_return Function(ffi.Pointer<ffi.Char>)>>('Start');
|
late final _StartPtr =
|
||||||
late final _Start = _StartPtr.asFunction<Start_return Function(ffi.Pointer<ffi.Char>)>();
|
_lookup<ffi.NativeFunction<Start_return Function(ffi.Pointer<ffi.Char>)>>(
|
||||||
|
'Start');
|
||||||
|
late final _Start =
|
||||||
|
_StartPtr.asFunction<Start_return Function(ffi.Pointer<ffi.Char>)>();
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef va_list = ffi.Pointer<ffi.Char>;
|
typedef va_list = ffi.Pointer<ffi.Char>;
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,8 @@ void main(List<String> args) async {
|
||||||
'Failed to find an installed WebView2 runtime or non-stable Microsoft Edge installation.');
|
'Failed to find an installed WebView2 runtime or non-stable Microsoft Edge installation.');
|
||||||
final document = await getApplicationDocumentsDirectory();
|
final document = await getApplicationDocumentsDirectory();
|
||||||
webViewEnvironment = await WebViewEnvironment.create(
|
webViewEnvironment = await WebViewEnvironment.create(
|
||||||
settings: WebViewEnvironmentSettings(userDataFolder: p.join(document.path, 'flutter_inappwebview')));
|
settings: WebViewEnvironmentSettings(
|
||||||
|
userDataFolder: p.join(document.path, 'flutter_inappwebview')));
|
||||||
}
|
}
|
||||||
isar = await StorageProvider().initDB(null, inspector: kDebugMode);
|
isar = await StorageProvider().initDB(null, inspector: kDebugMode);
|
||||||
await StorageProvider().requestPermission();
|
await StorageProvider().requestPermission();
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,10 @@ class Category {
|
||||||
Id? id;
|
Id? id;
|
||||||
String? name;
|
String? name;
|
||||||
bool? forManga;
|
bool? forManga;
|
||||||
Category({this.id = Isar.autoIncrement, required this.name, required this.forManga});
|
Category(
|
||||||
|
{this.id = Isar.autoIncrement,
|
||||||
|
required this.name,
|
||||||
|
required this.forManga});
|
||||||
|
|
||||||
Category.fromJson(Map<String, dynamic> json) {
|
Category.fromJson(Map<String, dynamic> json) {
|
||||||
id = json['id'];
|
id = json['id'];
|
||||||
|
|
@ -15,5 +18,6 @@ class Category {
|
||||||
forManga = json['forManga'];
|
forManga = json['forManga'];
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {'id': id, 'name': name, 'forManga': forManga};
|
Map<String, dynamic> toJson() =>
|
||||||
|
{'id': id, 'name': name, 'forManga': forManga};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,13 @@ class UpdatedChapter {
|
||||||
bool? isRead;
|
bool? isRead;
|
||||||
String? lastPageRead;
|
String? lastPageRead;
|
||||||
bool? deleted;
|
bool? deleted;
|
||||||
UpdatedChapter({this.chapterId, this.mangaId, this.isBookmarked, this.isRead, this.lastPageRead, this.deleted});
|
UpdatedChapter(
|
||||||
|
{this.chapterId,
|
||||||
|
this.mangaId,
|
||||||
|
this.isBookmarked,
|
||||||
|
this.isRead,
|
||||||
|
this.lastPageRead,
|
||||||
|
this.deleted});
|
||||||
UpdatedChapter.fromJson(Map<String, dynamic> json) {
|
UpdatedChapter.fromJson(Map<String, dynamic> json) {
|
||||||
chapterId = json['chapterId'];
|
chapterId = json['chapterId'];
|
||||||
mangaId = json['mangaId'];
|
mangaId = json['mangaId'];
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,11 @@ class History {
|
||||||
mangaId = json['mangaId'];
|
mangaId = json['mangaId'];
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, dynamic> toJson() =>
|
Map<String, dynamic> toJson() => {
|
||||||
{'chapterId': chapterId, 'date': date, 'id': id, 'isManga': isManga, 'mangaId': mangaId};
|
'chapterId': chapterId,
|
||||||
|
'date': date,
|
||||||
|
'id': id,
|
||||||
|
'isManga': isManga,
|
||||||
|
'mangaId': mangaId
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -118,4 +118,11 @@ class Manga {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Status { ongoing, completed, canceled, unknown, onHiatus, publishingFinished }
|
enum Status {
|
||||||
|
ongoing,
|
||||||
|
completed,
|
||||||
|
canceled,
|
||||||
|
unknown,
|
||||||
|
onHiatus,
|
||||||
|
publishingFinished
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -280,45 +280,62 @@ class Settings {
|
||||||
|
|
||||||
Settings.fromJson(Map<String, dynamic> json) {
|
Settings.fromJson(Map<String, dynamic> json) {
|
||||||
animatePageTransitions = json['animatePageTransitions'];
|
animatePageTransitions = json['animatePageTransitions'];
|
||||||
animeDisplayType = DisplayType.values[json['animeDisplayType'] ?? DisplayType.compactGrid.index];
|
animeDisplayType = DisplayType
|
||||||
|
.values[json['animeDisplayType'] ?? DisplayType.compactGrid.index];
|
||||||
animeLibraryDownloadedChapters = json['animeLibraryDownloadedChapters'];
|
animeLibraryDownloadedChapters = json['animeLibraryDownloadedChapters'];
|
||||||
animeLibraryLocalSource = json['animeLibraryLocalSource'];
|
animeLibraryLocalSource = json['animeLibraryLocalSource'];
|
||||||
animeLibraryShowCategoryTabs = json['animeLibraryShowCategoryTabs'];
|
animeLibraryShowCategoryTabs = json['animeLibraryShowCategoryTabs'];
|
||||||
animeLibraryShowContinueReadingButton = json['animeLibraryShowContinueReadingButton'];
|
animeLibraryShowContinueReadingButton =
|
||||||
|
json['animeLibraryShowContinueReadingButton'];
|
||||||
animeLibraryShowLanguage = json['animeLibraryShowLanguage'];
|
animeLibraryShowLanguage = json['animeLibraryShowLanguage'];
|
||||||
animeLibraryShowNumbersOfItems = json['animeLibraryShowNumbersOfItems'];
|
animeLibraryShowNumbersOfItems = json['animeLibraryShowNumbersOfItems'];
|
||||||
autoExtensionsUpdates = json['autoExtensionsUpdates'];
|
autoExtensionsUpdates = json['autoExtensionsUpdates'];
|
||||||
backgroundColor = BackgroundColor.values[json['backgroundColor'] ?? BackgroundColor.black.index];
|
backgroundColor = BackgroundColor
|
||||||
|
.values[json['backgroundColor'] ?? BackgroundColor.black.index];
|
||||||
if (json['chapterFilterBookmarkedList'] != null) {
|
if (json['chapterFilterBookmarkedList'] != null) {
|
||||||
chapterFilterBookmarkedList =
|
chapterFilterBookmarkedList =
|
||||||
(json['chapterFilterBookmarkedList'] as List).map((e) => ChapterFilterBookmarked.fromJson(e)).toList();
|
(json['chapterFilterBookmarkedList'] as List)
|
||||||
|
.map((e) => ChapterFilterBookmarked.fromJson(e))
|
||||||
|
.toList();
|
||||||
}
|
}
|
||||||
if (json['chapterFilterDownloadedList'] != null) {
|
if (json['chapterFilterDownloadedList'] != null) {
|
||||||
chapterFilterDownloadedList =
|
chapterFilterDownloadedList =
|
||||||
(json['chapterFilterDownloadedList'] as List).map((e) => ChapterFilterDownloaded.fromJson(e)).toList();
|
(json['chapterFilterDownloadedList'] as List)
|
||||||
|
.map((e) => ChapterFilterDownloaded.fromJson(e))
|
||||||
|
.toList();
|
||||||
}
|
}
|
||||||
if (json['chapterFilterUnreadList'] != null) {
|
if (json['chapterFilterUnreadList'] != null) {
|
||||||
chapterFilterUnreadList =
|
chapterFilterUnreadList = (json['chapterFilterUnreadList'] as List)
|
||||||
(json['chapterFilterUnreadList'] as List).map((e) => ChapterFilterUnread.fromJson(e)).toList();
|
.map((e) => ChapterFilterUnread.fromJson(e))
|
||||||
|
.toList();
|
||||||
}
|
}
|
||||||
if (json['chapterPageIndexList'] != null) {
|
if (json['chapterPageIndexList'] != null) {
|
||||||
chapterPageIndexList = (json['chapterPageIndexList'] as List).map((e) => ChapterPageIndex.fromJson(e)).toList();
|
chapterPageIndexList = (json['chapterPageIndexList'] as List)
|
||||||
|
.map((e) => ChapterPageIndex.fromJson(e))
|
||||||
|
.toList();
|
||||||
}
|
}
|
||||||
if (json['chapterPageUrlsList'] != null) {
|
if (json['chapterPageUrlsList'] != null) {
|
||||||
chapterPageUrlsList = (json['chapterPageUrlsList'] as List).map((e) => ChapterPageurls.fromJson(e)).toList();
|
chapterPageUrlsList = (json['chapterPageUrlsList'] as List)
|
||||||
|
.map((e) => ChapterPageurls.fromJson(e))
|
||||||
|
.toList();
|
||||||
}
|
}
|
||||||
checkForExtensionUpdates = json['checkForExtensionUpdates'];
|
checkForExtensionUpdates = json['checkForExtensionUpdates'];
|
||||||
if (json['cookiesList'] != null) {
|
if (json['cookiesList'] != null) {
|
||||||
cookiesList = (json['cookiesList'] as List).map((e) => MCookie.fromJson(e)).toList();
|
cookiesList = (json['cookiesList'] as List)
|
||||||
|
.map((e) => MCookie.fromJson(e))
|
||||||
|
.toList();
|
||||||
}
|
}
|
||||||
cropBorders = json['cropBorders'];
|
cropBorders = json['cropBorders'];
|
||||||
dateFormat = json['dateFormat'];
|
dateFormat = json['dateFormat'];
|
||||||
defaultReaderMode = ReaderMode.values[json['defaultReaderMode'] ?? ReaderMode.vertical.index];
|
defaultReaderMode = ReaderMode
|
||||||
|
.values[json['defaultReaderMode'] ?? ReaderMode.vertical.index];
|
||||||
displayType = DisplayType.values[json['displayType']];
|
displayType = DisplayType.values[json['displayType']];
|
||||||
doubleTapAnimationSpeed = json['doubleTapAnimationSpeed'];
|
doubleTapAnimationSpeed = json['doubleTapAnimationSpeed'];
|
||||||
downloadLocation = json['downloadLocation'];
|
downloadLocation = json['downloadLocation'];
|
||||||
downloadOnlyOnWifi = json['downloadOnlyOnWifi'];
|
downloadOnlyOnWifi = json['downloadOnlyOnWifi'];
|
||||||
filterScanlatorList = (json['filterScanlatorList'] as List?)?.map((e) => FilterScanlator.fromJson(e)).toList();
|
filterScanlatorList = (json['filterScanlatorList'] as List?)
|
||||||
|
?.map((e) => FilterScanlator.fromJson(e))
|
||||||
|
.toList();
|
||||||
flexColorSchemeBlendLevel = json['flexColorSchemeBlendLevel'] is double
|
flexColorSchemeBlendLevel = json['flexColorSchemeBlendLevel'] is double
|
||||||
? json['flexColorSchemeBlendLevel']
|
? json['flexColorSchemeBlendLevel']
|
||||||
: (json['flexColorSchemeBlendLevel'] as int).toDouble();
|
: (json['flexColorSchemeBlendLevel'] as int).toDouble();
|
||||||
|
|
@ -330,7 +347,8 @@ class Settings {
|
||||||
libraryFilterAnimeDownloadType = json['libraryFilterAnimeDownloadType'];
|
libraryFilterAnimeDownloadType = json['libraryFilterAnimeDownloadType'];
|
||||||
libraryFilterAnimeStartedType = json['libraryFilterAnimeStartedType'];
|
libraryFilterAnimeStartedType = json['libraryFilterAnimeStartedType'];
|
||||||
libraryFilterAnimeUnreadType = json['libraryFilterAnimeUnreadType'];
|
libraryFilterAnimeUnreadType = json['libraryFilterAnimeUnreadType'];
|
||||||
libraryFilterMangasBookMarkedType = json['libraryFilterMangasBookMarkedType'];
|
libraryFilterMangasBookMarkedType =
|
||||||
|
json['libraryFilterMangasBookMarkedType'];
|
||||||
libraryFilterMangasDownloadType = json['libraryFilterMangasDownloadType'];
|
libraryFilterMangasDownloadType = json['libraryFilterMangasDownloadType'];
|
||||||
libraryFilterMangasStartedType = json['libraryFilterMangasStartedType'];
|
libraryFilterMangasStartedType = json['libraryFilterMangasStartedType'];
|
||||||
libraryFilterMangasUnreadType = json['libraryFilterMangasUnreadType'];
|
libraryFilterMangasUnreadType = json['libraryFilterMangasUnreadType'];
|
||||||
|
|
@ -339,28 +357,41 @@ class Settings {
|
||||||
libraryShowContinueReadingButton = json['libraryShowContinueReadingButton'];
|
libraryShowContinueReadingButton = json['libraryShowContinueReadingButton'];
|
||||||
libraryShowLanguage = json['libraryShowLanguage'];
|
libraryShowLanguage = json['libraryShowLanguage'];
|
||||||
libraryShowNumbersOfItems = json['libraryShowNumbersOfItems'];
|
libraryShowNumbersOfItems = json['libraryShowNumbersOfItems'];
|
||||||
locale = json['locale'] != null ? L10nLocale.fromJson(json['locale']) : null;
|
locale =
|
||||||
|
json['locale'] != null ? L10nLocale.fromJson(json['locale']) : null;
|
||||||
onlyIncludePinnedSources = json['onlyIncludePinnedSources'];
|
onlyIncludePinnedSources = json['onlyIncludePinnedSources'];
|
||||||
pagePreloadAmount = json['pagePreloadAmount'];
|
pagePreloadAmount = json['pagePreloadAmount'];
|
||||||
if (json['personalPageModeList'] != null) {
|
if (json['personalPageModeList'] != null) {
|
||||||
personalPageModeList = (json['personalPageModeList'] as List).map((e) => PersonalPageMode.fromJson(e)).toList();
|
personalPageModeList = (json['personalPageModeList'] as List)
|
||||||
|
.map((e) => PersonalPageMode.fromJson(e))
|
||||||
|
.toList();
|
||||||
}
|
}
|
||||||
if (json['personalReaderModeList'] != null) {
|
if (json['personalReaderModeList'] != null) {
|
||||||
personalReaderModeList =
|
personalReaderModeList = (json['personalReaderModeList'] as List)
|
||||||
(json['personalReaderModeList'] as List).map((e) => PersonalReaderMode.fromJson(e)).toList();
|
.map((e) => PersonalReaderMode.fromJson(e))
|
||||||
|
.toList();
|
||||||
}
|
}
|
||||||
pureBlackDarkMode = json['pureBlackDarkMode'];
|
pureBlackDarkMode = json['pureBlackDarkMode'];
|
||||||
relativeTimesTamps = json['relativeTimesTamps'];
|
relativeTimesTamps = json['relativeTimesTamps'];
|
||||||
saveAsCBZArchive = json['saveAsCBZArchive'];
|
saveAsCBZArchive = json['saveAsCBZArchive'];
|
||||||
scaleType = ScaleType.values[json['scaleType'] ?? ScaleType.fitScreen.index];
|
scaleType =
|
||||||
|
ScaleType.values[json['scaleType'] ?? ScaleType.fitScreen.index];
|
||||||
showPagesNumber = json['showPagesNumber'];
|
showPagesNumber = json['showPagesNumber'];
|
||||||
if (json['sortChapterList'] != null) {
|
if (json['sortChapterList'] != null) {
|
||||||
sortChapterList = (json['sortChapterList'] as List).map((e) => SortChapter.fromJson(e)).toList();
|
sortChapterList = (json['sortChapterList'] as List)
|
||||||
|
.map((e) => SortChapter.fromJson(e))
|
||||||
|
.toList();
|
||||||
}
|
}
|
||||||
sortLibraryAnime = json['sortLibraryAnime'] != null ? SortLibraryManga.fromJson(json['sortLibraryAnime']) : null;
|
sortLibraryAnime = json['sortLibraryAnime'] != null
|
||||||
sortLibraryManga = json['sortLibraryManga'] != null ? SortLibraryManga.fromJson(json['sortLibraryManga']) : null;
|
? SortLibraryManga.fromJson(json['sortLibraryAnime'])
|
||||||
|
: null;
|
||||||
|
sortLibraryManga = json['sortLibraryManga'] != null
|
||||||
|
? SortLibraryManga.fromJson(json['sortLibraryManga'])
|
||||||
|
: null;
|
||||||
if (json['autoScrollPages'] != null) {
|
if (json['autoScrollPages'] != null) {
|
||||||
autoScrollPages = (json['autoScrollPages'] as List).map((e) => AutoScrollPages.fromJson(e)).toList();
|
autoScrollPages = (json['autoScrollPages'] as List)
|
||||||
|
.map((e) => AutoScrollPages.fromJson(e))
|
||||||
|
.toList();
|
||||||
}
|
}
|
||||||
themeIsDark = json['themeIsDark'];
|
themeIsDark = json['themeIsDark'];
|
||||||
userAgent = json['userAgent'];
|
userAgent = json['userAgent'];
|
||||||
|
|
@ -384,17 +415,22 @@ class Settings {
|
||||||
aniSkipTimeoutLength = json['aniSkipTimeoutLength'];
|
aniSkipTimeoutLength = json['aniSkipTimeoutLength'];
|
||||||
btServerAddress = json['btServerAddress'];
|
btServerAddress = json['btServerAddress'];
|
||||||
btServerPort = json['btServerPort'];
|
btServerPort = json['btServerPort'];
|
||||||
customColorFilter =
|
customColorFilter = json['customColorFilter'] != null
|
||||||
json['customColorFilter'] != null ? CustomColorFilter.fromJson(json['customColorFilter']) : null;
|
? CustomColorFilter.fromJson(json['customColorFilter'])
|
||||||
|
: null;
|
||||||
enableCustomColorFilter = json['enableCustomColorFilter'];
|
enableCustomColorFilter = json['enableCustomColorFilter'];
|
||||||
colorFilterBlendMode = ColorFilterBlendMode.values[json['colorFilterBlendMode'] ?? ColorFilterBlendMode.none];
|
colorFilterBlendMode = ColorFilterBlendMode
|
||||||
playerSubtitleSettings =
|
.values[json['colorFilterBlendMode'] ?? ColorFilterBlendMode.none];
|
||||||
json['playerSubtitleSettings'] != null ? PlayerSubtitleSettings.fromJson(json['playerSubtitleSettings']) : null;
|
playerSubtitleSettings = json['playerSubtitleSettings'] != null
|
||||||
mangaHomeDisplayType = DisplayType.values[json['mangaHomeDisplayType'] ?? DisplayType.comfortableGrid.index];
|
? PlayerSubtitleSettings.fromJson(json['playerSubtitleSettings'])
|
||||||
|
: null;
|
||||||
|
mangaHomeDisplayType = DisplayType.values[
|
||||||
|
json['mangaHomeDisplayType'] ?? DisplayType.comfortableGrid.index];
|
||||||
appFontFamily = json['appFontFamily'];
|
appFontFamily = json['appFontFamily'];
|
||||||
mangaGridSize = json['mangaGridSize'];
|
mangaGridSize = json['mangaGridSize'];
|
||||||
animeGridSize = json['animeGridSize'];
|
animeGridSize = json['animeGridSize'];
|
||||||
disableSectionType = SectionType.values[json['disableSectionType'] ?? SectionType.all];
|
disableSectionType =
|
||||||
|
SectionType.values[json['disableSectionType'] ?? SectionType.all];
|
||||||
useLibass = json['useLibass'];
|
useLibass = json['useLibass'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -404,16 +440,22 @@ class Settings {
|
||||||
'animeLibraryDownloadedChapters': animeLibraryDownloadedChapters,
|
'animeLibraryDownloadedChapters': animeLibraryDownloadedChapters,
|
||||||
'animeLibraryLocalSource': animeLibraryLocalSource,
|
'animeLibraryLocalSource': animeLibraryLocalSource,
|
||||||
'animeLibraryShowCategoryTabs': animeLibraryShowCategoryTabs,
|
'animeLibraryShowCategoryTabs': animeLibraryShowCategoryTabs,
|
||||||
'animeLibraryShowContinueReadingButton': animeLibraryShowContinueReadingButton,
|
'animeLibraryShowContinueReadingButton':
|
||||||
|
animeLibraryShowContinueReadingButton,
|
||||||
'animeLibraryShowLanguage': animeLibraryShowLanguage,
|
'animeLibraryShowLanguage': animeLibraryShowLanguage,
|
||||||
'animeLibraryShowNumbersOfItems': animeLibraryShowNumbersOfItems,
|
'animeLibraryShowNumbersOfItems': animeLibraryShowNumbersOfItems,
|
||||||
'autoExtensionsUpdates': autoExtensionsUpdates,
|
'autoExtensionsUpdates': autoExtensionsUpdates,
|
||||||
'backgroundColor': backgroundColor.index,
|
'backgroundColor': backgroundColor.index,
|
||||||
'chapterFilterBookmarkedList': chapterFilterBookmarkedList?.map((v) => v.toJson()).toList(),
|
'chapterFilterBookmarkedList':
|
||||||
'chapterFilterDownloadedList': chapterFilterDownloadedList?.map((v) => v.toJson()).toList(),
|
chapterFilterBookmarkedList?.map((v) => v.toJson()).toList(),
|
||||||
'chapterFilterUnreadList': chapterFilterUnreadList?.map((v) => v.toJson()).toList(),
|
'chapterFilterDownloadedList':
|
||||||
'chapterPageIndexList': chapterPageIndexList?.map((v) => v.toJson()).toList(),
|
chapterFilterDownloadedList?.map((v) => v.toJson()).toList(),
|
||||||
'chapterPageUrlsList': chapterPageUrlsList?.map((v) => v.toJson()).toList(),
|
'chapterFilterUnreadList':
|
||||||
|
chapterFilterUnreadList?.map((v) => v.toJson()).toList(),
|
||||||
|
'chapterPageIndexList':
|
||||||
|
chapterPageIndexList?.map((v) => v.toJson()).toList(),
|
||||||
|
'chapterPageUrlsList':
|
||||||
|
chapterPageUrlsList?.map((v) => v.toJson()).toList(),
|
||||||
'checkForExtensionUpdates': checkForExtensionUpdates,
|
'checkForExtensionUpdates': checkForExtensionUpdates,
|
||||||
'cookiesList': cookiesList,
|
'cookiesList': cookiesList,
|
||||||
'cropBorders': cropBorders,
|
'cropBorders': cropBorders,
|
||||||
|
|
@ -445,8 +487,10 @@ class Settings {
|
||||||
'locale': locale?.toJson(),
|
'locale': locale?.toJson(),
|
||||||
'onlyIncludePinnedSources': onlyIncludePinnedSources,
|
'onlyIncludePinnedSources': onlyIncludePinnedSources,
|
||||||
'pagePreloadAmount': pagePreloadAmount,
|
'pagePreloadAmount': pagePreloadAmount,
|
||||||
'personalPageModeList': personalPageModeList?.map((v) => v.toJson()).toList(),
|
'personalPageModeList':
|
||||||
'personalReaderModeList': personalReaderModeList?.map((v) => v.toJson()).toList(),
|
personalPageModeList?.map((v) => v.toJson()).toList(),
|
||||||
|
'personalReaderModeList':
|
||||||
|
personalReaderModeList?.map((v) => v.toJson()).toList(),
|
||||||
'pureBlackDarkMode': pureBlackDarkMode,
|
'pureBlackDarkMode': pureBlackDarkMode,
|
||||||
'relativeTimesTamps': relativeTimesTamps,
|
'relativeTimesTamps': relativeTimesTamps,
|
||||||
'saveAsCBZArchive': saveAsCBZArchive,
|
'saveAsCBZArchive': saveAsCBZArchive,
|
||||||
|
|
@ -477,10 +521,12 @@ class Settings {
|
||||||
'btServerAddress': btServerAddress,
|
'btServerAddress': btServerAddress,
|
||||||
'btServerPort': btServerPort,
|
'btServerPort': btServerPort,
|
||||||
'fullScreenReader': fullScreenReader,
|
'fullScreenReader': fullScreenReader,
|
||||||
if (customColorFilter != null) 'customColorFilter': customColorFilter!.toJson(),
|
if (customColorFilter != null)
|
||||||
|
'customColorFilter': customColorFilter!.toJson(),
|
||||||
'enableCustomColorFilter': enableCustomColorFilter,
|
'enableCustomColorFilter': enableCustomColorFilter,
|
||||||
'colorFilterBlendMode': colorFilterBlendMode.index,
|
'colorFilterBlendMode': colorFilterBlendMode.index,
|
||||||
if (playerSubtitleSettings != null) 'playerSubtitleSettings': playerSubtitleSettings!.toJson(),
|
if (playerSubtitleSettings != null)
|
||||||
|
'playerSubtitleSettings': playerSubtitleSettings!.toJson(),
|
||||||
'mangaHomeDisplayType': mangaHomeDisplayType.index,
|
'mangaHomeDisplayType': mangaHomeDisplayType.index,
|
||||||
'appFontFamily': appFontFamily,
|
'appFontFamily': appFontFamily,
|
||||||
'mangaGridSize': mangaGridSize,
|
'mangaGridSize': mangaGridSize,
|
||||||
|
|
@ -549,7 +595,8 @@ class SortChapter {
|
||||||
reverse = json['reverse'];
|
reverse = json['reverse'];
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {'index': index, 'mangaId': mangaId, 'reverse': reverse};
|
Map<String, dynamic> toJson() =>
|
||||||
|
{'index': index, 'mangaId': mangaId, 'reverse': reverse};
|
||||||
}
|
}
|
||||||
|
|
||||||
@embedded
|
@embedded
|
||||||
|
|
@ -604,7 +651,8 @@ class ChapterPageurls {
|
||||||
urls = json['headers']?.cast<String>();
|
urls = json['headers']?.cast<String>();
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {'chapterId': chapterId, 'urls': urls, 'headers': headers};
|
Map<String, dynamic> toJson() =>
|
||||||
|
{'chapterId': chapterId, 'urls': urls, 'headers': headers};
|
||||||
}
|
}
|
||||||
|
|
||||||
@embedded
|
@embedded
|
||||||
|
|
@ -634,7 +682,8 @@ class PersonalReaderMode {
|
||||||
readerMode = ReaderMode.values[json['readerMode']];
|
readerMode = ReaderMode.values[json['readerMode']];
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {'mangaId': mangaId, 'readerMode': readerMode.index};
|
Map<String, dynamic> toJson() =>
|
||||||
|
{'mangaId': mangaId, 'readerMode': readerMode.index};
|
||||||
}
|
}
|
||||||
|
|
||||||
@embedded
|
@embedded
|
||||||
|
|
@ -642,7 +691,8 @@ class AutoScrollPages {
|
||||||
int? mangaId;
|
int? mangaId;
|
||||||
double? pageOffset;
|
double? pageOffset;
|
||||||
bool? autoScroll;
|
bool? autoScroll;
|
||||||
AutoScrollPages({this.mangaId, this.pageOffset = 10, this.autoScroll = false});
|
AutoScrollPages(
|
||||||
|
{this.mangaId, this.pageOffset = 10, this.autoScroll = false});
|
||||||
|
|
||||||
AutoScrollPages.fromJson(Map<String, dynamic> json) {
|
AutoScrollPages.fromJson(Map<String, dynamic> json) {
|
||||||
mangaId = json['mangaId'];
|
mangaId = json['mangaId'];
|
||||||
|
|
@ -650,7 +700,8 @@ class AutoScrollPages {
|
||||||
autoScroll = json['autoScroll'];
|
autoScroll = json['autoScroll'];
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {'mangaId': mangaId, 'pageOffset': pageOffset, 'autoScroll': autoScroll};
|
Map<String, dynamic> toJson() =>
|
||||||
|
{'mangaId': mangaId, 'pageOffset': pageOffset, 'autoScroll': autoScroll};
|
||||||
}
|
}
|
||||||
|
|
||||||
@embedded
|
@embedded
|
||||||
|
|
@ -666,10 +717,18 @@ class PersonalPageMode {
|
||||||
pageMode = PageMode.values[json['pageMode']];
|
pageMode = PageMode.values[json['pageMode']];
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {'mangaId': mangaId, 'pageMode': pageMode.index};
|
Map<String, dynamic> toJson() =>
|
||||||
|
{'mangaId': mangaId, 'pageMode': pageMode.index};
|
||||||
}
|
}
|
||||||
|
|
||||||
enum ReaderMode { vertical, ltr, rtl, verticalContinuous, webtoon, horizontalContinuous }
|
enum ReaderMode {
|
||||||
|
vertical,
|
||||||
|
ltr,
|
||||||
|
rtl,
|
||||||
|
verticalContinuous,
|
||||||
|
webtoon,
|
||||||
|
horizontalContinuous
|
||||||
|
}
|
||||||
|
|
||||||
enum PageMode { onePage, doublePage }
|
enum PageMode { onePage, doublePage }
|
||||||
|
|
||||||
|
|
@ -684,7 +743,8 @@ class FilterScanlator {
|
||||||
scanlators = json['scanlators']?.cast<String>();
|
scanlators = json['scanlators']?.cast<String>();
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {'mangaId': mangaId, 'scanlators': scanlators};
|
Map<String, dynamic> toJson() =>
|
||||||
|
{'mangaId': mangaId, 'scanlators': scanlators};
|
||||||
}
|
}
|
||||||
|
|
||||||
@embedded
|
@embedded
|
||||||
|
|
@ -698,7 +758,8 @@ class L10nLocale {
|
||||||
languageCode = json['languageCode'];
|
languageCode = json['languageCode'];
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {'countryCode': countryCode, 'languageCode': languageCode};
|
Map<String, dynamic> toJson() =>
|
||||||
|
{'countryCode': countryCode, 'languageCode': languageCode};
|
||||||
}
|
}
|
||||||
|
|
||||||
@embedded
|
@embedded
|
||||||
|
|
|
||||||
|
|
@ -115,7 +115,8 @@ class Source {
|
||||||
additionalParams = json['additionalParams'] ?? "";
|
additionalParams = json['additionalParams'] ?? "";
|
||||||
isObsolete = json['isObsolete'];
|
isObsolete = json['isObsolete'];
|
||||||
isLocal = json['isLocal'];
|
isLocal = json['isLocal'];
|
||||||
sourceCodeLanguage = SourceCodeLanguage.values[json['sourceCodeLanguage'] ?? 0];
|
sourceCodeLanguage =
|
||||||
|
SourceCodeLanguage.values[json['sourceCodeLanguage'] ?? 0];
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
Map<String, dynamic> toJson() => {
|
||||||
|
|
|
||||||
|
|
@ -83,4 +83,14 @@ class Track {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
enum TrackStatus { reading, completed, onHold, dropped, planToRead, rereading, watching, planToWatch, reWatching }
|
enum TrackStatus {
|
||||||
|
reading,
|
||||||
|
completed,
|
||||||
|
onHold,
|
||||||
|
dropped,
|
||||||
|
planToRead,
|
||||||
|
rereading,
|
||||||
|
watching,
|
||||||
|
planToWatch,
|
||||||
|
reWatching
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,5 +26,6 @@ class TrackPreference {
|
||||||
prefs = json['prefs'];
|
prefs = json['prefs'];
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {'syncId': syncId, 'username': username, 'oAuth': oAuth, 'prefs': prefs};
|
Map<String, dynamic> toJson() =>
|
||||||
|
{'syncId': syncId, 'username': username, 'oAuth': oAuth, 'prefs': prefs};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,13 +8,20 @@ class Video {
|
||||||
List<Track>? subtitles;
|
List<Track>? subtitles;
|
||||||
List<Track>? audios;
|
List<Track>? audios;
|
||||||
|
|
||||||
Video(this.url, this.quality, this.originalUrl, {this.headers, this.subtitles, this.audios});
|
Video(this.url, this.quality, this.originalUrl,
|
||||||
|
{this.headers, this.subtitles, this.audios});
|
||||||
factory Video.fromJson(Map<String, dynamic> json) {
|
factory Video.fromJson(Map<String, dynamic> json) {
|
||||||
return Video(
|
return Video(
|
||||||
json['url'].toString().trim(), json['quality'].toString().trim(), json['originalUrl'].toString().trim(),
|
json['url'].toString().trim(),
|
||||||
|
json['quality'].toString().trim(),
|
||||||
|
json['originalUrl'].toString().trim(),
|
||||||
headers: (json['headers'] as Map?)?.toMapStringString,
|
headers: (json['headers'] as Map?)?.toMapStringString,
|
||||||
subtitles: json['subtitles'] != null ? (json['subtitles'] as List).map((e) => Track.fromJson(e)).toList() : [],
|
subtitles: json['subtitles'] != null
|
||||||
audios: json['audios'] != null ? (json['audios'] as List).map((e) => Track.fromJson(e)).toList() : []);
|
? (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() => {
|
Map<String, dynamic> toJson() => {
|
||||||
'url': url,
|
'url': url,
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,8 @@ class _AnimePlayerViewState extends riv.ConsumerState<AnimePlayerView> {
|
||||||
for (var infoHash in _infoHashList) {
|
for (var infoHash in _infoHashList) {
|
||||||
MTorrentServer().removeTorrent(infoHash);
|
MTorrentServer().removeTorrent(infoHash);
|
||||||
}
|
}
|
||||||
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: SystemUiOverlay.values);
|
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual,
|
||||||
|
overlays: SystemUiOverlay.values);
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -64,13 +65,15 @@ class _AnimePlayerViewState extends riv.ConsumerState<AnimePlayerView> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final serversData = ref.watch(getVideoListProvider(episode: widget.episode));
|
final serversData =
|
||||||
|
ref.watch(getVideoListProvider(episode: widget.episode));
|
||||||
SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersive);
|
SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersive);
|
||||||
return serversData.when(
|
return serversData.when(
|
||||||
data: (data) {
|
data: (data) {
|
||||||
final (videos, isLocal, infoHashList) = data;
|
final (videos, isLocal, infoHashList) = data;
|
||||||
_infoHashList = infoHashList;
|
_infoHashList = infoHashList;
|
||||||
if (videos.isEmpty && !(widget.episode.manga.value!.isLocalArchive ?? false)) {
|
if (videos.isEmpty &&
|
||||||
|
!(widget.episode.manga.value!.isLocalArchive ?? false)) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
|
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
|
|
@ -102,7 +105,8 @@ class _AnimePlayerViewState extends riv.ConsumerState<AnimePlayerView> {
|
||||||
title: const Text(''),
|
title: const Text(''),
|
||||||
leading: BackButton(
|
leading: BackButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: SystemUiOverlay.values);
|
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual,
|
||||||
|
overlays: SystemUiOverlay.values);
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|
@ -120,7 +124,8 @@ class _AnimePlayerViewState extends riv.ConsumerState<AnimePlayerView> {
|
||||||
leading: BackButton(
|
leading: BackButton(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: SystemUiOverlay.values);
|
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual,
|
||||||
|
overlays: SystemUiOverlay.values);
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|
@ -150,18 +155,24 @@ class AnimeStreamPage extends riv.ConsumerStatefulWidget {
|
||||||
riv.ConsumerState<AnimeStreamPage> createState() => _AnimeStreamPageState();
|
riv.ConsumerState<AnimeStreamPage> createState() => _AnimeStreamPageState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _AnimeStreamPageState extends riv.ConsumerState<AnimeStreamPage> with TickerProviderStateMixin {
|
class _AnimeStreamPageState extends riv.ConsumerState<AnimeStreamPage>
|
||||||
|
with TickerProviderStateMixin {
|
||||||
late final GlobalKey<VideoState> _key = GlobalKey<VideoState>();
|
late final GlobalKey<VideoState> _key = GlobalKey<VideoState>();
|
||||||
late final useLibass = ref.read(useLibassStateProvider);
|
late final useLibass = ref.read(useLibassStateProvider);
|
||||||
late final Player _player = Player(configuration: PlayerConfiguration(libass: useLibass));
|
late final Player _player =
|
||||||
|
Player(configuration: PlayerConfiguration(libass: useLibass));
|
||||||
late final VideoController _controller = VideoController(_player);
|
late final VideoController _controller = VideoController(_player);
|
||||||
late final _streamController = ref.read(animeStreamControllerProvider(episode: widget.episode).notifier);
|
late final _streamController =
|
||||||
|
ref.read(animeStreamControllerProvider(episode: widget.episode).notifier);
|
||||||
late final _firstVid = widget.videos.first;
|
late final _firstVid = widget.videos.first;
|
||||||
late final ValueNotifier<VideoPrefs?> _video = ValueNotifier(VideoPrefs(
|
late final ValueNotifier<VideoPrefs?> _video = ValueNotifier(VideoPrefs(
|
||||||
videoTrack: VideoTrack(_firstVid.originalUrl, _firstVid.quality, _firstVid.quality), headers: _firstVid.headers));
|
videoTrack: VideoTrack(
|
||||||
|
_firstVid.originalUrl, _firstVid.quality, _firstVid.quality),
|
||||||
|
headers: _firstVid.headers));
|
||||||
final ValueNotifier<double> _playbackSpeed = ValueNotifier(1.0);
|
final ValueNotifier<double> _playbackSpeed = ValueNotifier(1.0);
|
||||||
final ValueNotifier<bool> _enterFullScreen = ValueNotifier(false);
|
final ValueNotifier<bool> _enterFullScreen = ValueNotifier(false);
|
||||||
late final ValueNotifier<Duration> _currentPosition = ValueNotifier(_streamController.geTCurrentPosition());
|
late final ValueNotifier<Duration> _currentPosition =
|
||||||
|
ValueNotifier(_streamController.geTCurrentPosition());
|
||||||
final ValueNotifier<Duration?> _currentTotalDuration = ValueNotifier(null);
|
final ValueNotifier<Duration?> _currentTotalDuration = ValueNotifier(null);
|
||||||
final ValueNotifier<bool> _showFitLabel = ValueNotifier(false);
|
final ValueNotifier<bool> _showFitLabel = ValueNotifier(false);
|
||||||
final ValueNotifier<bool> _isCompleted = ValueNotifier(false);
|
final ValueNotifier<bool> _isCompleted = ValueNotifier(false);
|
||||||
|
|
@ -175,9 +186,12 @@ class _AnimeStreamPageState extends riv.ConsumerState<AnimeStreamPage> with Tick
|
||||||
bool _hasEndingSkip = false;
|
bool _hasEndingSkip = false;
|
||||||
bool _initSubtitleAndAudio = true;
|
bool _initSubtitleAndAudio = true;
|
||||||
|
|
||||||
late final StreamSubscription<Duration> _currentPositionSub = _player.stream.position.listen(
|
late final StreamSubscription<Duration> _currentPositionSub =
|
||||||
|
_player.stream.position.listen(
|
||||||
(position) async {
|
(position) async {
|
||||||
_isCompleted.value = _player.state.duration.inSeconds - _currentPosition.value.inSeconds <= 10;
|
_isCompleted.value =
|
||||||
|
_player.state.duration.inSeconds - _currentPosition.value.inSeconds <=
|
||||||
|
10;
|
||||||
_currentPosition.value = position;
|
_currentPosition.value = position;
|
||||||
|
|
||||||
if (_firstVid.subtitles?.isNotEmpty ?? false) {
|
if (_firstVid.subtitles?.isNotEmpty ?? false) {
|
||||||
|
|
@ -191,8 +205,10 @@ class _AnimeStreamPageState extends riv.ConsumerState<AnimeStreamPage> with Tick
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
try {
|
try {
|
||||||
if (_firstVid.audios?.isNotEmpty ?? false) {
|
if (_firstVid.audios?.isNotEmpty ?? false) {
|
||||||
_player.setAudioTrack(AudioTrack.uri(_firstVid.audios!.first.file ?? "",
|
_player.setAudioTrack(AudioTrack.uri(
|
||||||
title: _firstVid.audios!.first.label, language: _firstVid.audios!.first.label));
|
_firstVid.audios!.first.file ?? "",
|
||||||
|
title: _firstVid.audios!.first.label,
|
||||||
|
language: _firstVid.audios!.first.label));
|
||||||
}
|
}
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
}
|
}
|
||||||
|
|
@ -201,13 +217,15 @@ class _AnimeStreamPageState extends riv.ConsumerState<AnimeStreamPage> with Tick
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
late final StreamSubscription<Duration> _currentTotalDurationSub = _player.stream.duration.listen(
|
late final StreamSubscription<Duration> _currentTotalDurationSub =
|
||||||
|
_player.stream.duration.listen(
|
||||||
(duration) {
|
(duration) {
|
||||||
_currentTotalDuration.value = duration;
|
_currentTotalDuration.value = duration;
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
late final StreamSubscription<bool> _completed = _player.stream.completed.listen((val) {
|
late final StreamSubscription<bool> _completed =
|
||||||
|
_player.stream.completed.listen((val) {
|
||||||
if (_streamController.getEpisodeIndex().$1 != 0 && val == true) {
|
if (_streamController.getEpisodeIndex().$1 != 0 && val == true) {
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
pushToNewEpisode(context, _streamController.getNextEpisode());
|
pushToNewEpisode(context, _streamController.getNextEpisode());
|
||||||
|
|
@ -231,12 +249,14 @@ class _AnimeStreamPageState extends riv.ConsumerState<AnimeStreamPage> with Tick
|
||||||
_loadAndroidFont().then(
|
_loadAndroidFont().then(
|
||||||
(_) {
|
(_) {
|
||||||
_player.open(Media(_video.value!.videoTrack!.id,
|
_player.open(Media(_video.value!.videoTrack!.id,
|
||||||
httpHeaders: _video.value!.headers, start: _streamController.geTCurrentPosition()));
|
httpHeaders: _video.value!.headers,
|
||||||
|
start: _streamController.geTCurrentPosition()));
|
||||||
if (widget.isTorrent) {
|
if (widget.isTorrent) {
|
||||||
Future.delayed(const Duration(seconds: 10)).then((_) {
|
Future.delayed(const Duration(seconds: 10)).then((_) {
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
_player.open(Media(_video.value!.videoTrack!.id,
|
_player.open(Media(_video.value!.videoTrack!.id,
|
||||||
httpHeaders: _video.value!.headers, start: _streamController.geTCurrentPosition()));
|
httpHeaders: _video.value!.headers,
|
||||||
|
start: _streamController.geTCurrentPosition()));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -253,11 +273,14 @@ class _AnimeStreamPageState extends riv.ConsumerState<AnimeStreamPage> with Tick
|
||||||
final subDir = await getApplicationDocumentsDirectory();
|
final subDir = await getApplicationDocumentsDirectory();
|
||||||
final fontPath = path.join(subDir.path, 'subfont.ttf');
|
final fontPath = path.join(subDir.path, 'subfont.ttf');
|
||||||
final data = await rootBundle.load('assets/fonts/subfont.ttf');
|
final data = await rootBundle.load('assets/fonts/subfont.ttf');
|
||||||
final bytes = data.buffer.asInt8List(data.offsetInBytes, data.lengthInBytes);
|
final bytes =
|
||||||
|
data.buffer.asInt8List(data.offsetInBytes, data.lengthInBytes);
|
||||||
final fontFile = await File(fontPath).create(recursive: true);
|
final fontFile = await File(fontPath).create(recursive: true);
|
||||||
await fontFile.writeAsBytes(bytes);
|
await fontFile.writeAsBytes(bytes);
|
||||||
await (_player.platform as NativePlayer).setProperty('sub-fonts-dir', subDir.path);
|
await (_player.platform as NativePlayer)
|
||||||
await (_player.platform as NativePlayer).setProperty('sub-font', 'Droid Sans Fallback');
|
.setProperty('sub-fonts-dir', subDir.path);
|
||||||
|
await (_player.platform as NativePlayer)
|
||||||
|
.setProperty('sub-font', 'Droid Sans Fallback');
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -265,12 +288,14 @@ class _AnimeStreamPageState extends riv.ConsumerState<AnimeStreamPage> with Tick
|
||||||
void _initAniSkip() async {
|
void _initAniSkip() async {
|
||||||
await _player.stream.buffer.first;
|
await _player.stream.buffer.first;
|
||||||
_streamController.getAniSkipResults((result) {
|
_streamController.getAniSkipResults((result) {
|
||||||
final openingRes = result.where((element) => element.skipType == "op").toList();
|
final openingRes =
|
||||||
|
result.where((element) => element.skipType == "op").toList();
|
||||||
_hasOpeningSkip = openingRes.isNotEmpty;
|
_hasOpeningSkip = openingRes.isNotEmpty;
|
||||||
if (_hasOpeningSkip) {
|
if (_hasOpeningSkip) {
|
||||||
_openingResult = openingRes.first;
|
_openingResult = openingRes.first;
|
||||||
}
|
}
|
||||||
final endingRes = result.where((element) => element.skipType == "ed").toList();
|
final endingRes =
|
||||||
|
result.where((element) => element.skipType == "ed").toList();
|
||||||
_hasEndingSkip = endingRes.isNotEmpty;
|
_hasEndingSkip = endingRes.isNotEmpty;
|
||||||
if (_hasEndingSkip) {
|
if (_hasEndingSkip) {
|
||||||
_endingResult = endingRes.first;
|
_endingResult = endingRes.first;
|
||||||
|
|
@ -295,14 +320,17 @@ class _AnimeStreamPageState extends riv.ConsumerState<AnimeStreamPage> with Tick
|
||||||
}
|
}
|
||||||
|
|
||||||
void _setCurrentPosition(bool save) {
|
void _setCurrentPosition(bool save) {
|
||||||
_streamController.setCurrentPosition(_currentPosition.value, _currentTotalDuration.value, save: save);
|
_streamController.setCurrentPosition(
|
||||||
|
_currentPosition.value, _currentTotalDuration.value,
|
||||||
|
save: save);
|
||||||
_streamController.setAnimeHistoryUpdate();
|
_streamController.setAnimeHistoryUpdate();
|
||||||
_streamController.checkAndSyncProgress();
|
_streamController.checkAndSyncProgress();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _setLandscapeMode(bool state) {
|
void _setLandscapeMode(bool state) {
|
||||||
if (state) {
|
if (state) {
|
||||||
SystemChrome.setPreferredOrientations([DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
|
SystemChrome.setPreferredOrientations(
|
||||||
|
[DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
|
||||||
} else {
|
} else {
|
||||||
SystemChrome.setPreferredOrientations([
|
SystemChrome.setPreferredOrientations([
|
||||||
DeviceOrientation.portraitUp,
|
DeviceOrientation.portraitUp,
|
||||||
|
|
@ -317,7 +345,8 @@ class _AnimeStreamPageState extends riv.ConsumerState<AnimeStreamPage> with Tick
|
||||||
children: [
|
children: [
|
||||||
Flexible(
|
Flexible(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: EdgeInsets.symmetric(horizontal: MediaQuery.of(context).padding.top),
|
padding: EdgeInsets.symmetric(
|
||||||
|
horizontal: MediaQuery.of(context).padding.top),
|
||||||
child: Text(text,
|
child: Text(text,
|
||||||
style: Theme.of(context).textTheme.bodyLarge!.copyWith(
|
style: Theme.of(context).textTheme.bodyLarge!.copyWith(
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
|
|
@ -331,7 +360,8 @@ class _AnimeStreamPageState extends riv.ConsumerState<AnimeStreamPage> with Tick
|
||||||
|
|
||||||
Widget _videoQualityWidget(BuildContext context) {
|
Widget _videoQualityWidget(BuildContext context) {
|
||||||
List<VideoPrefs> videoQuality = _player.state.tracks.video
|
List<VideoPrefs> videoQuality = _player.state.tracks.video
|
||||||
.where((element) => element.w != null && element.h != null && widget.isLocal)
|
.where((element) =>
|
||||||
|
element.w != null && element.h != null && widget.isLocal)
|
||||||
.toList()
|
.toList()
|
||||||
.map((e) => VideoPrefs(videoTrack: e, isLocal: true))
|
.map((e) => VideoPrefs(videoTrack: e, isLocal: true))
|
||||||
.toList();
|
.toList();
|
||||||
|
|
@ -339,7 +369,9 @@ class _AnimeStreamPageState extends riv.ConsumerState<AnimeStreamPage> with Tick
|
||||||
if (widget.videos.isNotEmpty && !widget.isLocal) {
|
if (widget.videos.isNotEmpty && !widget.isLocal) {
|
||||||
for (var video in widget.videos) {
|
for (var video in widget.videos) {
|
||||||
videoQuality.add(VideoPrefs(
|
videoQuality.add(VideoPrefs(
|
||||||
videoTrack: VideoTrack(video.url, video.quality, video.quality), headers: video.headers, isLocal: false));
|
videoTrack: VideoTrack(video.url, video.quality, video.quality),
|
||||||
|
headers: video.headers,
|
||||||
|
isLocal: false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -347,21 +379,27 @@ class _AnimeStreamPageState extends riv.ConsumerState<AnimeStreamPage> with Tick
|
||||||
padding: const EdgeInsets.symmetric(vertical: 15, horizontal: 12),
|
padding: const EdgeInsets.symmetric(vertical: 15, horizontal: 12),
|
||||||
child: Column(
|
child: Column(
|
||||||
children: videoQuality.map((quality) {
|
children: videoQuality.map((quality) {
|
||||||
final selected = _video.value!.videoTrack!.title == quality.videoTrack!.title || widget.isLocal;
|
final selected =
|
||||||
|
_video.value!.videoTrack!.title == quality.videoTrack!.title ||
|
||||||
|
widget.isLocal;
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
child: textWidget(widget.isLocal ? _firstVid.quality : quality.videoTrack!.title!, selected),
|
child: textWidget(
|
||||||
|
widget.isLocal ? _firstVid.quality : quality.videoTrack!.title!,
|
||||||
|
selected),
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
_video.value = quality;
|
_video.value = quality;
|
||||||
if (quality.isLocal) {
|
if (quality.isLocal) {
|
||||||
if (widget.isLocal) {
|
if (widget.isLocal) {
|
||||||
_player.setVideoTrack(quality.videoTrack!);
|
_player.setVideoTrack(quality.videoTrack!);
|
||||||
} else {
|
} else {
|
||||||
_player
|
_player.open(Media(quality.videoTrack!.id,
|
||||||
.open(Media(quality.videoTrack!.id, httpHeaders: quality.headers, start: _currentPosition.value));
|
httpHeaders: quality.headers,
|
||||||
|
start: _currentPosition.value));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_player
|
_player.open(Media(quality.videoTrack!.id,
|
||||||
.open(Media(quality.videoTrack!.id, httpHeaders: quality.headers, start: _currentPosition.value));
|
httpHeaders: quality.headers,
|
||||||
|
start: _currentPosition.value));
|
||||||
}
|
}
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
},
|
},
|
||||||
|
|
@ -419,8 +457,10 @@ class _AnimeStreamPageState extends riv.ConsumerState<AnimeStreamPage> with Tick
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _videoSubtitle(BuildContext context, Function(bool) hasSubtitleTrack) {
|
Widget _videoSubtitle(BuildContext context, Function(bool) hasSubtitleTrack) {
|
||||||
List<VideoPrefs> videoSubtitle =
|
List<VideoPrefs> videoSubtitle = _player.state.tracks.subtitle
|
||||||
_player.state.tracks.subtitle.toList().map((e) => VideoPrefs(isLocal: true, subtitle: e)).toList();
|
.toList()
|
||||||
|
.map((e) => VideoPrefs(isLocal: true, subtitle: e))
|
||||||
|
.toList();
|
||||||
|
|
||||||
List<String> subs = [];
|
List<String> subs = [];
|
||||||
if (widget.videos.isNotEmpty && !widget.isLocal) {
|
if (widget.videos.isNotEmpty && !widget.isLocal) {
|
||||||
|
|
@ -443,7 +483,10 @@ class _AnimeStreamPageState extends riv.ConsumerState<AnimeStreamPage> with Tick
|
||||||
videoSubtitle = videoSubtitle
|
videoSubtitle = videoSubtitle
|
||||||
.map((e) {
|
.map((e) {
|
||||||
VideoPrefs vid = e;
|
VideoPrefs vid = e;
|
||||||
vid.title = vid.subtitle?.title ?? vid.subtitle?.language ?? vid.subtitle?.channels ?? "";
|
vid.title = vid.subtitle?.title ??
|
||||||
|
vid.subtitle?.language ??
|
||||||
|
vid.subtitle?.channels ??
|
||||||
|
"";
|
||||||
return vid;
|
return vid;
|
||||||
})
|
})
|
||||||
.toList()
|
.toList()
|
||||||
|
|
@ -451,11 +494,16 @@ class _AnimeStreamPageState extends riv.ConsumerState<AnimeStreamPage> with Tick
|
||||||
.toList();
|
.toList();
|
||||||
videoSubtitle.sort((a, b) => a.title!.compareTo(b.title!));
|
videoSubtitle.sort((a, b) => a.title!.compareTo(b.title!));
|
||||||
hasSubtitleTrack.call(videoSubtitle.isNotEmpty);
|
hasSubtitleTrack.call(videoSubtitle.isNotEmpty);
|
||||||
videoSubtitle.insert(0, VideoPrefs(isLocal: false, subtitle: SubtitleTrack.no()));
|
videoSubtitle.insert(
|
||||||
|
0, VideoPrefs(isLocal: false, subtitle: SubtitleTrack.no()));
|
||||||
List<VideoPrefs> videoSubtitleLast = [];
|
List<VideoPrefs> videoSubtitleLast = [];
|
||||||
for (var element in videoSubtitle) {
|
for (var element in videoSubtitle) {
|
||||||
final contains = videoSubtitleLast.any((sub) {
|
final contains = videoSubtitleLast.any((sub) {
|
||||||
return (sub.title ?? sub.subtitle?.title ?? sub.subtitle?.language ?? sub.subtitle?.channels ?? "None") ==
|
return (sub.title ??
|
||||||
|
sub.subtitle?.title ??
|
||||||
|
sub.subtitle?.language ??
|
||||||
|
sub.subtitle?.channels ??
|
||||||
|
"None") ==
|
||||||
(element.title ??
|
(element.title ??
|
||||||
element.subtitle?.title ??
|
element.subtitle?.title ??
|
||||||
element.subtitle?.language ??
|
element.subtitle?.language ??
|
||||||
|
|
@ -470,9 +518,17 @@ class _AnimeStreamPageState extends riv.ConsumerState<AnimeStreamPage> with Tick
|
||||||
padding: const EdgeInsets.symmetric(vertical: 15, horizontal: 12),
|
padding: const EdgeInsets.symmetric(vertical: 15, horizontal: 12),
|
||||||
child: Column(
|
child: Column(
|
||||||
children: videoSubtitleLast.toSet().toList().map((sub) {
|
children: videoSubtitleLast.toSet().toList().map((sub) {
|
||||||
final title = sub.title ?? sub.subtitle?.title ?? sub.subtitle?.language ?? sub.subtitle?.channels ?? "None";
|
final title = sub.title ??
|
||||||
|
sub.subtitle?.title ??
|
||||||
|
sub.subtitle?.language ??
|
||||||
|
sub.subtitle?.channels ??
|
||||||
|
"None";
|
||||||
|
|
||||||
final selected = (title == (subtitle.title ?? subtitle.language ?? subtitle.channels ?? "None")) ||
|
final selected = (title ==
|
||||||
|
(subtitle.title ??
|
||||||
|
subtitle.language ??
|
||||||
|
subtitle.channels ??
|
||||||
|
"None")) ||
|
||||||
(subtitle.id == "no" && title == "None");
|
(subtitle.id == "no" && title == "None");
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
|
|
@ -489,8 +545,10 @@ class _AnimeStreamPageState extends riv.ConsumerState<AnimeStreamPage> with Tick
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _videoAudios(BuildContext context) {
|
Widget _videoAudios(BuildContext context) {
|
||||||
List<VideoPrefs> videoAudio =
|
List<VideoPrefs> videoAudio = _player.state.tracks.audio
|
||||||
_player.state.tracks.audio.toList().map((e) => VideoPrefs(isLocal: true, audio: e)).toList();
|
.toList()
|
||||||
|
.map((e) => VideoPrefs(isLocal: true, audio: e))
|
||||||
|
.toList();
|
||||||
|
|
||||||
List<String> audios = [];
|
List<String> audios = [];
|
||||||
if (widget.videos.isNotEmpty && !widget.isLocal) {
|
if (widget.videos.isNotEmpty && !widget.isLocal) {
|
||||||
|
|
@ -498,7 +556,9 @@ class _AnimeStreamPageState extends riv.ConsumerState<AnimeStreamPage> with Tick
|
||||||
for (var audio in video.audios ?? []) {
|
for (var audio in video.audios ?? []) {
|
||||||
if (!audios.contains(audio.file)) {
|
if (!audios.contains(audio.file)) {
|
||||||
videoAudio.add(VideoPrefs(
|
videoAudio.add(VideoPrefs(
|
||||||
isLocal: false, audio: AudioTrack.uri(audio.file!, title: audio.label, language: audio.label)));
|
isLocal: false,
|
||||||
|
audio: AudioTrack.uri(audio.file!,
|
||||||
|
title: audio.label, language: audio.label)));
|
||||||
audios.add(audio.file!);
|
audios.add(audio.file!);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -508,7 +568,10 @@ class _AnimeStreamPageState extends riv.ConsumerState<AnimeStreamPage> with Tick
|
||||||
videoAudio = videoAudio
|
videoAudio = videoAudio
|
||||||
.map((e) {
|
.map((e) {
|
||||||
VideoPrefs vid = e;
|
VideoPrefs vid = e;
|
||||||
vid.title = vid.audio?.title ?? vid.audio?.language ?? vid.audio?.channels ?? "";
|
vid.title = vid.audio?.title ??
|
||||||
|
vid.audio?.language ??
|
||||||
|
vid.audio?.channels ??
|
||||||
|
"";
|
||||||
return vid;
|
return vid;
|
||||||
})
|
})
|
||||||
.toList()
|
.toList()
|
||||||
|
|
@ -520,8 +583,13 @@ class _AnimeStreamPageState extends riv.ConsumerState<AnimeStreamPage> with Tick
|
||||||
padding: const EdgeInsets.symmetric(vertical: 15, horizontal: 12),
|
padding: const EdgeInsets.symmetric(vertical: 15, horizontal: 12),
|
||||||
child: Column(
|
child: Column(
|
||||||
children: videoAudio.toSet().toList().map((aud) {
|
children: videoAudio.toSet().toList().map((aud) {
|
||||||
final title = aud.title ?? aud.audio?.title ?? aud.audio?.language ?? aud.audio?.channels ?? "None";
|
final title = aud.title ??
|
||||||
final selected = (aud.audio == audio) || (audio.id == "no" && title == "None");
|
aud.audio?.title ??
|
||||||
|
aud.audio?.language ??
|
||||||
|
aud.audio?.channels ??
|
||||||
|
"None";
|
||||||
|
final selected =
|
||||||
|
(aud.audio == audio) || (audio.id == "no" && title == "None");
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
|
|
@ -542,8 +610,10 @@ class _AnimeStreamPageState extends riv.ConsumerState<AnimeStreamPage> with Tick
|
||||||
|
|
||||||
void _togglePlaybackSpeed() {
|
void _togglePlaybackSpeed() {
|
||||||
List<double> allowedSpeeds = [0.25, 0.5, 0.75, 1.0, 1.25, 1.50, 1.75, 2.0];
|
List<double> allowedSpeeds = [0.25, 0.5, 0.75, 1.0, 1.25, 1.50, 1.75, 2.0];
|
||||||
if (allowedSpeeds.indexOf(_playbackSpeed.value) < allowedSpeeds.length - 1) {
|
if (allowedSpeeds.indexOf(_playbackSpeed.value) <
|
||||||
_setPlaybackSpeed(allowedSpeeds[allowedSpeeds.indexOf(_playbackSpeed.value) + 1]);
|
allowedSpeeds.length - 1) {
|
||||||
|
_setPlaybackSpeed(
|
||||||
|
allowedSpeeds[allowedSpeeds.indexOf(_playbackSpeed.value) + 1]);
|
||||||
} else {
|
} else {
|
||||||
_setPlaybackSpeed(allowedSpeeds[0]);
|
_setPlaybackSpeed(allowedSpeeds[0]);
|
||||||
}
|
}
|
||||||
|
|
@ -576,20 +646,26 @@ class _AnimeStreamPageState extends riv.ConsumerState<AnimeStreamPage> with Tick
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _seekToWidget() {
|
Widget _seekToWidget() {
|
||||||
final defaultSkipIntroLength = ref.watch(defaultSkipIntroLengthStateProvider);
|
final defaultSkipIntroLength =
|
||||||
|
ref.watch(defaultSkipIntroLengthStateProvider);
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 5),
|
padding: const EdgeInsets.symmetric(vertical: 5),
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
height: 35,
|
height: 35,
|
||||||
child: ElevatedButton(
|
child: ElevatedButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
_tempPosition.value = Duration(seconds: defaultSkipIntroLength + _currentPosition.value.inSeconds);
|
_tempPosition.value = Duration(
|
||||||
await _player.seek(Duration(seconds: _currentPosition.value.inSeconds + defaultSkipIntroLength));
|
seconds: defaultSkipIntroLength +
|
||||||
|
_currentPosition.value.inSeconds);
|
||||||
|
await _player.seek(Duration(
|
||||||
|
seconds: _currentPosition.value.inSeconds +
|
||||||
|
defaultSkipIntroLength));
|
||||||
_tempPosition.value = null;
|
_tempPosition.value = null;
|
||||||
},
|
},
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8.0),
|
||||||
child: Text("+$defaultSkipIntroLength", style: const TextStyle(fontWeight: FontWeight.w100)),
|
child: Text("+$defaultSkipIntroLength",
|
||||||
|
style: const TextStyle(fontWeight: FontWeight.w100)),
|
||||||
)),
|
)),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
@ -631,7 +707,8 @@ class _AnimeStreamPageState extends riv.ConsumerState<AnimeStreamPage> with Tick
|
||||||
_togglePlaybackSpeed();
|
_togglePlaybackSpeed();
|
||||||
}),
|
}),
|
||||||
IconButton(
|
IconButton(
|
||||||
icon: const Icon(Icons.fit_screen_outlined, color: Colors.white),
|
icon: const Icon(Icons.fit_screen_outlined,
|
||||||
|
color: Colors.white),
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
_changeFitLabel(ref);
|
_changeFitLabel(ref);
|
||||||
},
|
},
|
||||||
|
|
@ -644,7 +721,9 @@ class _AnimeStreamPageState extends riv.ConsumerState<AnimeStreamPage> with Tick
|
||||||
_setLandscapeMode(!snapshot);
|
_setLandscapeMode(!snapshot);
|
||||||
_enterFullScreen.value = !snapshot;
|
_enterFullScreen.value = !snapshot;
|
||||||
},
|
},
|
||||||
icon: Icon(snapshot ? Icons.fullscreen_exit : Icons.fullscreen),
|
icon: Icon(snapshot
|
||||||
|
? Icons.fullscreen_exit
|
||||||
|
: Icons.fullscreen),
|
||||||
iconSize: 25,
|
iconSize: 25,
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
);
|
);
|
||||||
|
|
@ -661,7 +740,8 @@ class _AnimeStreamPageState extends riv.ConsumerState<AnimeStreamPage> with Tick
|
||||||
|
|
||||||
Widget _desktopBottomButtonBar(BuildContext context) {
|
Widget _desktopBottomButtonBar(BuildContext context) {
|
||||||
bool hasPrevEpisode = _streamController.getEpisodeIndex().$1 + 1 !=
|
bool hasPrevEpisode = _streamController.getEpisodeIndex().$1 + 1 !=
|
||||||
_streamController.getEpisodesLength(_streamController.getEpisodeIndex().$2);
|
_streamController
|
||||||
|
.getEpisodesLength(_streamController.getEpisodeIndex().$2);
|
||||||
bool hasNextEpisode = _streamController.getEpisodeIndex().$1 != 0;
|
bool hasNextEpisode = _streamController.getEpisodeIndex().$1 != 0;
|
||||||
final skipDuration = ref.watch(defaultDoubleTapToSkipLengthStateProvider);
|
final skipDuration = ref.watch(defaultDoubleTapToSkipLengthStateProvider);
|
||||||
return Column(
|
return Column(
|
||||||
|
|
@ -675,7 +755,8 @@ class _AnimeStreamPageState extends riv.ConsumerState<AnimeStreamPage> with Tick
|
||||||
if (hasPrevEpisode)
|
if (hasPrevEpisode)
|
||||||
IconButton(
|
IconButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
pushToNewEpisode(context, _streamController.getPrevEpisode());
|
pushToNewEpisode(
|
||||||
|
context, _streamController.getPrevEpisode());
|
||||||
},
|
},
|
||||||
icon: const Icon(
|
icon: const Icon(
|
||||||
Icons.skip_previous,
|
Icons.skip_previous,
|
||||||
|
|
@ -688,7 +769,8 @@ class _AnimeStreamPageState extends riv.ConsumerState<AnimeStreamPage> with Tick
|
||||||
if (hasNextEpisode)
|
if (hasNextEpisode)
|
||||||
IconButton(
|
IconButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
pushToNewEpisode(context, _streamController.getNextEpisode());
|
pushToNewEpisode(
|
||||||
|
context, _streamController.getNextEpisode());
|
||||||
},
|
},
|
||||||
icon: const Icon(Icons.skip_next, color: Colors.white),
|
icon: const Icon(Icons.skip_next, color: Colors.white),
|
||||||
),
|
),
|
||||||
|
|
@ -697,8 +779,12 @@ class _AnimeStreamPageState extends riv.ConsumerState<AnimeStreamPage> with Tick
|
||||||
width: 50,
|
width: 50,
|
||||||
child: IconButton(
|
child: IconButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
_tempPosition.value = Duration(seconds: skipDuration - _currentPosition.value.inSeconds);
|
_tempPosition.value = Duration(
|
||||||
await _player.seek(Duration(seconds: _currentPosition.value.inSeconds - skipDuration));
|
seconds:
|
||||||
|
skipDuration - _currentPosition.value.inSeconds);
|
||||||
|
await _player.seek(Duration(
|
||||||
|
seconds:
|
||||||
|
_currentPosition.value.inSeconds - skipDuration));
|
||||||
_tempPosition.value = null;
|
_tempPosition.value = null;
|
||||||
},
|
},
|
||||||
icon: Stack(
|
icon: Stack(
|
||||||
|
|
@ -716,7 +802,8 @@ class _AnimeStreamPageState extends riv.ConsumerState<AnimeStreamPage> with Tick
|
||||||
padding: const EdgeInsets.only(top: 2),
|
padding: const EdgeInsets.only(top: 2),
|
||||||
child: Text(
|
child: Text(
|
||||||
skipDuration.toString(),
|
skipDuration.toString(),
|
||||||
style: const TextStyle(fontSize: 9, color: Colors.white),
|
style: const TextStyle(
|
||||||
|
fontSize: 9, color: Colors.white),
|
||||||
),
|
),
|
||||||
)),
|
)),
|
||||||
),
|
),
|
||||||
|
|
@ -729,8 +816,12 @@ class _AnimeStreamPageState extends riv.ConsumerState<AnimeStreamPage> with Tick
|
||||||
width: 50,
|
width: 50,
|
||||||
child: IconButton(
|
child: IconButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
_tempPosition.value = Duration(seconds: skipDuration + _currentPosition.value.inSeconds);
|
_tempPosition.value = Duration(
|
||||||
await _player.seek(Duration(seconds: _currentPosition.value.inSeconds + skipDuration));
|
seconds:
|
||||||
|
skipDuration + _currentPosition.value.inSeconds);
|
||||||
|
await _player.seek(Duration(
|
||||||
|
seconds:
|
||||||
|
_currentPosition.value.inSeconds + skipDuration));
|
||||||
_tempPosition.value = null;
|
_tempPosition.value = null;
|
||||||
},
|
},
|
||||||
icon: Stack(
|
icon: Stack(
|
||||||
|
|
@ -748,7 +839,8 @@ class _AnimeStreamPageState extends riv.ConsumerState<AnimeStreamPage> with Tick
|
||||||
padding: const EdgeInsets.only(top: 2),
|
padding: const EdgeInsets.only(top: 2),
|
||||||
child: Text(
|
child: Text(
|
||||||
skipDuration.toString(),
|
skipDuration.toString(),
|
||||||
style: const TextStyle(fontSize: 9, color: Colors.white),
|
style: const TextStyle(
|
||||||
|
fontSize: 9, color: Colors.white),
|
||||||
),
|
),
|
||||||
)),
|
)),
|
||||||
),
|
),
|
||||||
|
|
@ -762,7 +854,8 @@ class _AnimeStreamPageState extends riv.ConsumerState<AnimeStreamPage> with Tick
|
||||||
ValueListenableBuilder(
|
ValueListenableBuilder(
|
||||||
valueListenable: _tempPosition,
|
valueListenable: _tempPosition,
|
||||||
builder: (context, value, child) =>
|
builder: (context, value, child) =>
|
||||||
CustomMaterialDesktopPositionIndicator(delta: value, controller: _controller),
|
CustomMaterialDesktopPositionIndicator(
|
||||||
|
delta: value, controller: _controller),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
@ -789,7 +882,8 @@ class _AnimeStreamPageState extends riv.ConsumerState<AnimeStreamPage> with Tick
|
||||||
_togglePlaybackSpeed();
|
_togglePlaybackSpeed();
|
||||||
}),
|
}),
|
||||||
IconButton(
|
IconButton(
|
||||||
icon: const Icon(Icons.fit_screen_outlined, color: Colors.white),
|
icon: const Icon(Icons.fit_screen_outlined,
|
||||||
|
color: Colors.white),
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
_changeFitLabel(ref);
|
_changeFitLabel(ref);
|
||||||
},
|
},
|
||||||
|
|
@ -810,7 +904,10 @@ class _AnimeStreamPageState extends riv.ConsumerState<AnimeStreamPage> with Tick
|
||||||
valueListenable: _enterFullScreen,
|
valueListenable: _enterFullScreen,
|
||||||
builder: (context, fullScreen, _) {
|
builder: (context, fullScreen, _) {
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: EdgeInsets.only(top: !_isDesktop && !fullScreen ? MediaQuery.of(context).padding.top : 0),
|
padding: EdgeInsets.only(
|
||||||
|
top: !_isDesktop && !fullScreen
|
||||||
|
? MediaQuery.of(context).padding.top
|
||||||
|
: 0),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
BackButton(
|
BackButton(
|
||||||
|
|
@ -825,7 +922,8 @@ class _AnimeStreamPageState extends riv.ConsumerState<AnimeStreamPage> with Tick
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: SystemUiOverlay.values);
|
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual,
|
||||||
|
overlays: SystemUiOverlay.values);
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
}
|
}
|
||||||
|
|
@ -839,7 +937,8 @@ class _AnimeStreamPageState extends riv.ConsumerState<AnimeStreamPage> with Tick
|
||||||
width: context.width(0.8),
|
width: context.width(0.8),
|
||||||
child: Text(
|
child: Text(
|
||||||
widget.episode.manga.value!.name!,
|
widget.episode.manga.value!.name!,
|
||||||
style: const TextStyle(fontWeight: FontWeight.bold, color: Colors.white),
|
style: const TextStyle(
|
||||||
|
fontWeight: FontWeight.bold, color: Colors.white),
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -848,7 +947,9 @@ class _AnimeStreamPageState extends riv.ConsumerState<AnimeStreamPage> with Tick
|
||||||
child: Text(
|
child: Text(
|
||||||
widget.episode.name!,
|
widget.episode.name!,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 12, fontWeight: FontWeight.w400, color: Colors.white.withValues(alpha: 0.7)),
|
fontSize: 12,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
color: Colors.white.withValues(alpha: 0.7)),
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -924,7 +1025,8 @@ class _AnimeStreamPageState extends riv.ConsumerState<AnimeStreamPage> with Tick
|
||||||
void _resize(BoxFit fit) async {
|
void _resize(BoxFit fit) async {
|
||||||
await Future.delayed(const Duration(milliseconds: 100));
|
await Future.delayed(const Duration(milliseconds: 100));
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
_key.currentState?.update(fit: fit, width: context.width(1), height: context.height(1));
|
_key.currentState?.update(
|
||||||
|
fit: fit, width: context.width(1), height: context.height(1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -934,7 +1036,8 @@ class _AnimeStreamPageState extends riv.ConsumerState<AnimeStreamPage> with Tick
|
||||||
return Stack(
|
return Stack(
|
||||||
children: [
|
children: [
|
||||||
Video(
|
Video(
|
||||||
subtitleViewConfiguration: SubtitleViewConfiguration(visible: false, style: subtileTextStyle(ref)),
|
subtitleViewConfiguration: SubtitleViewConfiguration(
|
||||||
|
visible: false, style: subtileTextStyle(ref)),
|
||||||
fit: fit,
|
fit: fit,
|
||||||
key: _key,
|
key: _key,
|
||||||
controls: (state) => _isDesktop
|
controls: (state) => _isDesktop
|
||||||
|
|
@ -976,8 +1079,10 @@ class _AnimeStreamPageState extends riv.ConsumerState<AnimeStreamPage> with Tick
|
||||||
builder: (context, value, child) {
|
builder: (context, value, child) {
|
||||||
if (_hasOpeningSkip || _hasEndingSkip) {
|
if (_hasOpeningSkip || _hasEndingSkip) {
|
||||||
if (_hasOpeningSkip) {
|
if (_hasOpeningSkip) {
|
||||||
if (_openingResult!.interval!.startTime!.ceil() <= value.inSeconds &&
|
if (_openingResult!.interval!.startTime!.ceil() <=
|
||||||
_openingResult!.interval!.endTime!.toInt() > value.inSeconds) {
|
value.inSeconds &&
|
||||||
|
_openingResult!.interval!.endTime!.toInt() >
|
||||||
|
value.inSeconds) {
|
||||||
_showAniSkipOpeningButton.value = true;
|
_showAniSkipOpeningButton.value = true;
|
||||||
_showAniSkipEndingButton.value = false;
|
_showAniSkipEndingButton.value = false;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -985,8 +1090,10 @@ class _AnimeStreamPageState extends riv.ConsumerState<AnimeStreamPage> with Tick
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (_hasEndingSkip) {
|
if (_hasEndingSkip) {
|
||||||
if (_endingResult!.interval!.startTime!.ceil() <= value.inSeconds &&
|
if (_endingResult!.interval!.startTime!.ceil() <=
|
||||||
_endingResult!.interval!.endTime!.toInt() > value.inSeconds) {
|
value.inSeconds &&
|
||||||
|
_endingResult!.interval!.endTime!.toInt() >
|
||||||
|
value.inSeconds) {
|
||||||
_showAniSkipEndingButton.value = true;
|
_showAniSkipEndingButton.value = true;
|
||||||
_showAniSkipOpeningButton.value = false;
|
_showAniSkipOpeningButton.value = false;
|
||||||
}
|
}
|
||||||
|
|
@ -995,9 +1102,12 @@ class _AnimeStreamPageState extends riv.ConsumerState<AnimeStreamPage> with Tick
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Consumer(builder: (context, ref, _) {
|
return Consumer(builder: (context, ref, _) {
|
||||||
late final enableAniSkip = ref.watch(enableAniSkipStateProvider);
|
late final enableAniSkip =
|
||||||
late final enableAutoSkip = ref.watch(enableAutoSkipStateProvider);
|
ref.watch(enableAniSkipStateProvider);
|
||||||
late final aniSkipTimeoutLength = ref.watch(aniSkipTimeoutLengthStateProvider);
|
late final enableAutoSkip =
|
||||||
|
ref.watch(enableAutoSkipStateProvider);
|
||||||
|
late final aniSkipTimeoutLength =
|
||||||
|
ref.watch(aniSkipTimeoutLengthStateProvider);
|
||||||
return ValueListenableBuilder(
|
return ValueListenableBuilder(
|
||||||
valueListenable: _showAniSkipOpeningButton,
|
valueListenable: _showAniSkipOpeningButton,
|
||||||
builder: (context, showAniSkipOpENINGButton, child) {
|
builder: (context, showAniSkipOpENINGButton, child) {
|
||||||
|
|
@ -1055,11 +1165,13 @@ Widget seekIndicatorTextWidget(Duration duration, Duration currentPosition) {
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
Duration(seconds: value).label(),
|
Duration(seconds: value).label(),
|
||||||
style: const TextStyle(fontSize: 65.0, fontWeight: FontWeight.bold, color: Colors.white),
|
style: const TextStyle(
|
||||||
|
fontSize: 65.0, fontWeight: FontWeight.bold, color: Colors.white),
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
"[${swipeDuration > 0 ? "+${Duration(seconds: swipeDuration).label()}" : "-${Duration(seconds: swipeDuration).label()}"}]",
|
"[${swipeDuration > 0 ? "+${Duration(seconds: swipeDuration).label()}" : "-${Duration(seconds: swipeDuration).label()}"}]",
|
||||||
style: const TextStyle(fontSize: 40.0, color: Colors.white, fontWeight: FontWeight.bold),
|
style: const TextStyle(
|
||||||
|
fontSize: 40.0, color: Colors.white, fontWeight: FontWeight.bold),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
@ -1072,5 +1184,11 @@ class VideoPrefs {
|
||||||
AudioTrack? audio;
|
AudioTrack? audio;
|
||||||
bool isLocal;
|
bool isLocal;
|
||||||
final Map<String, String>? headers;
|
final Map<String, String>? headers;
|
||||||
VideoPrefs({this.videoTrack, this.isLocal = true, this.headers, this.subtitle, this.audio, this.title});
|
VideoPrefs(
|
||||||
|
{this.videoTrack,
|
||||||
|
this.isLocal = true,
|
||||||
|
this.headers,
|
||||||
|
this.subtitle,
|
||||||
|
this.audio,
|
||||||
|
this.title});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -104,13 +104,17 @@ class AnimeStreamController extends _$AnimeStreamController {
|
||||||
}
|
}
|
||||||
|
|
||||||
int getEpisodesLength(bool isInFilterList) {
|
int getEpisodesLength(bool isInFilterList) {
|
||||||
return isInFilterList ? getAnime().getFilteredChapterList().length : getAnime().chapters.length;
|
return isInFilterList
|
||||||
|
? getAnime().getFilteredChapterList().length
|
||||||
|
: getAnime().chapters.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
Duration geTCurrentPosition() {
|
Duration geTCurrentPosition() {
|
||||||
if (incognitoMode) return Duration.zero;
|
if (incognitoMode) return Duration.zero;
|
||||||
String position = episode.lastPageRead ?? "0";
|
String position = episode.lastPageRead ?? "0";
|
||||||
return Duration(milliseconds: episode.isRead! ? 0 : int.parse(position.isEmpty ? "0" : position));
|
return Duration(
|
||||||
|
milliseconds:
|
||||||
|
episode.isRead! ? 0 : int.parse(position.isEmpty ? "0" : position));
|
||||||
}
|
}
|
||||||
|
|
||||||
void setAnimeHistoryUpdate() {
|
void setAnimeHistoryUpdate() {
|
||||||
|
|
@ -122,7 +126,8 @@ class AnimeStreamController extends _$AnimeStreamController {
|
||||||
});
|
});
|
||||||
History? history;
|
History? history;
|
||||||
|
|
||||||
final empty = isar.historys.filter().mangaIdEqualTo(getAnime().id).isEmptySync();
|
final empty =
|
||||||
|
isar.historys.filter().mangaIdEqualTo(getAnime().id).isEmptySync();
|
||||||
|
|
||||||
if (empty) {
|
if (empty) {
|
||||||
history = History(
|
history = History(
|
||||||
|
|
@ -132,7 +137,10 @@ class AnimeStreamController extends _$AnimeStreamController {
|
||||||
chapterId: episode.id)
|
chapterId: episode.id)
|
||||||
..chapter.value = episode;
|
..chapter.value = episode;
|
||||||
} else {
|
} else {
|
||||||
history = (isar.historys.filter().mangaIdEqualTo(getAnime().id).findFirstSync())!
|
history = (isar.historys
|
||||||
|
.filter()
|
||||||
|
.mangaIdEqualTo(getAnime().id)
|
||||||
|
.findFirstSync())!
|
||||||
..chapterId = episode.id
|
..chapterId = episode.id
|
||||||
..chapter.value = episode
|
..chapter.value = episode
|
||||||
..date = DateTime.now().millisecondsSinceEpoch.toString();
|
..date = DateTime.now().millisecondsSinceEpoch.toString();
|
||||||
|
|
@ -150,19 +158,25 @@ class AnimeStreamController extends _$AnimeStreamController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void setCurrentPosition(Duration duration, Duration? totalDuration, {bool save = false}) {
|
void setCurrentPosition(Duration duration, Duration? totalDuration,
|
||||||
|
{bool save = false}) {
|
||||||
if (episode.isRead!) return;
|
if (episode.isRead!) return;
|
||||||
if (incognitoMode) return;
|
if (incognitoMode) return;
|
||||||
final markEpisodeAsSeenType = ref.watch(markEpisodeAsSeenTypeStateProvider);
|
final markEpisodeAsSeenType = ref.watch(markEpisodeAsSeenTypeStateProvider);
|
||||||
final isWatch = totalDuration != null && totalDuration != Duration.zero && duration != Duration.zero
|
final isWatch = totalDuration != null &&
|
||||||
? duration.inSeconds >= ((totalDuration.inSeconds * markEpisodeAsSeenType) / 100).ceil()
|
totalDuration != Duration.zero &&
|
||||||
|
duration != Duration.zero
|
||||||
|
? duration.inSeconds >=
|
||||||
|
((totalDuration.inSeconds * markEpisodeAsSeenType) / 100).ceil()
|
||||||
: false;
|
: false;
|
||||||
if (isWatch || save) {
|
if (isWatch || save) {
|
||||||
final ep = episode;
|
final ep = episode;
|
||||||
isar.writeTxnSync(() {
|
isar.writeTxnSync(() {
|
||||||
ep.isRead = isWatch;
|
ep.isRead = isWatch;
|
||||||
ep.lastPageRead = (duration.inMilliseconds).toString();
|
ep.lastPageRead = (duration.inMilliseconds).toString();
|
||||||
ref.read(changedItemsManagerProvider(managerId: 1).notifier).addUpdatedChapter(ep, false, false);
|
ref
|
||||||
|
.read(changedItemsManagerProvider(managerId: 1).notifier)
|
||||||
|
.addUpdatedChapter(ep, false, false);
|
||||||
isar.chapters.putSync(ep);
|
isar.chapters.putSync(ep);
|
||||||
});
|
});
|
||||||
if (isWatch) {
|
if (isWatch) {
|
||||||
|
|
@ -172,10 +186,18 @@ class AnimeStreamController extends _$AnimeStreamController {
|
||||||
}
|
}
|
||||||
|
|
||||||
(int, int)? _getTrackId() {
|
(int, int)? _getTrackId() {
|
||||||
final malId =
|
final malId = isar.tracks
|
||||||
isar.tracks.filter().syncIdEqualTo(1).mangaIdEqualTo(episode.manga.value!.id!).findFirstSync()?.mediaId;
|
.filter()
|
||||||
final aniId =
|
.syncIdEqualTo(1)
|
||||||
isar.tracks.filter().syncIdEqualTo(2).mangaIdEqualTo(episode.manga.value!.id!).findFirstSync()?.mediaId;
|
.mangaIdEqualTo(episode.manga.value!.id!)
|
||||||
|
.findFirstSync()
|
||||||
|
?.mediaId;
|
||||||
|
final aniId = isar.tracks
|
||||||
|
.filter()
|
||||||
|
.syncIdEqualTo(2)
|
||||||
|
.mangaIdEqualTo(episode.manga.value!.id!)
|
||||||
|
.findFirstSync()
|
||||||
|
?.mediaId;
|
||||||
return switch (malId) {
|
return switch (malId) {
|
||||||
!= null => (malId, 1),
|
!= null => (malId, 1),
|
||||||
== null => switch (aniId) { != null => (aniId, 2), _ => null },
|
== null => switch (aniId) { != null => (aniId, 2), _ => null },
|
||||||
|
|
@ -183,14 +205,17 @@ class AnimeStreamController extends _$AnimeStreamController {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<Results>?> getAniSkipResults(Function(List<Results>) result) async {
|
Future<List<Results>?> getAniSkipResults(
|
||||||
|
Function(List<Results>) result) async {
|
||||||
await Future.delayed(const Duration(milliseconds: 300));
|
await Future.delayed(const Duration(milliseconds: 300));
|
||||||
if (ref.watch(enableAniSkipStateProvider)) {
|
if (ref.watch(enableAniSkipStateProvider)) {
|
||||||
final id = _getTrackId();
|
final id = _getTrackId();
|
||||||
if (id != null) {
|
if (id != null) {
|
||||||
final res = await ref
|
final res = await ref.read(aniSkipProvider.notifier).getResult(
|
||||||
.read(aniSkipProvider.notifier)
|
id,
|
||||||
.getResult(id, ChapterRecognition().parseChapterNumber(episode.manga.value!.name!, episode.name!), 0);
|
ChapterRecognition()
|
||||||
|
.parseChapterNumber(episode.manga.value!.name!, episode.name!),
|
||||||
|
0);
|
||||||
result.call(res ?? []);
|
result.call(res ?? []);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,15 +19,21 @@ class SubtitleSettingsState extends _$SubtitleSettingsState {
|
||||||
final settings = isar.settings.getSync(227);
|
final settings = isar.settings.getSync(227);
|
||||||
state = value;
|
state = value;
|
||||||
if (end) {
|
if (end) {
|
||||||
isar.writeTxnSync(() => isar.settings.putSync(settings!..playerSubtitleSettings = value));
|
isar.writeTxnSync(() =>
|
||||||
|
isar.settings.putSync(settings!..playerSubtitleSettings = value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void resetColor() {
|
void resetColor() {
|
||||||
final settings = isar.settings.getSync(227);
|
final settings = isar.settings.getSync(227);
|
||||||
state = PlayerSubtitleSettings(fontSize: state.fontSize, useBold: state.useBold, useItalic: state.useItalic);
|
state = PlayerSubtitleSettings(
|
||||||
|
fontSize: state.fontSize,
|
||||||
|
useBold: state.useBold,
|
||||||
|
useItalic: state.useItalic);
|
||||||
isar.writeTxnSync(() => isar.settings.putSync(settings!
|
isar.writeTxnSync(() => isar.settings.putSync(settings!
|
||||||
..playerSubtitleSettings =
|
..playerSubtitleSettings = PlayerSubtitleSettings(
|
||||||
PlayerSubtitleSettings(fontSize: state.fontSize, useBold: state.useBold, useItalic: state.useItalic)));
|
fontSize: state.fontSize,
|
||||||
|
useBold: state.useBold,
|
||||||
|
useItalic: state.useItalic)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,14 +20,18 @@ class AniSkipCountDownButton extends ConsumerStatefulWidget {
|
||||||
required this.timeoutLength});
|
required this.timeoutLength});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
ConsumerState<AniSkipCountDownButton> createState() => _AniSkipCountDownButtonState();
|
ConsumerState<AniSkipCountDownButton> createState() =>
|
||||||
|
_AniSkipCountDownButtonState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _AniSkipCountDownButtonState extends ConsumerState<AniSkipCountDownButton> with TickerProviderStateMixin {
|
class _AniSkipCountDownButtonState extends ConsumerState<AniSkipCountDownButton>
|
||||||
|
with TickerProviderStateMixin {
|
||||||
late AnimationController _controller;
|
late AnimationController _controller;
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
_controller = AnimationController(vsync: this, duration: Duration(seconds: widget.timeoutLength))..forward();
|
_controller = AnimationController(
|
||||||
|
vsync: this, duration: Duration(seconds: widget.timeoutLength))
|
||||||
|
..forward();
|
||||||
super.initState();
|
super.initState();
|
||||||
if (widget.active) {
|
if (widget.active) {
|
||||||
if (widget.autoSkip) {
|
if (widget.autoSkip) {
|
||||||
|
|
@ -50,7 +54,8 @@ class _AniSkipCountDownButtonState extends ConsumerState<AniSkipCountDownButton>
|
||||||
_isCompleted = true;
|
_isCompleted = true;
|
||||||
});
|
});
|
||||||
_controller.reset();
|
_controller.reset();
|
||||||
widget.player.seek(Duration(seconds: widget.aniSkipResult!.interval!.endTime!.ceil()));
|
widget.player.seek(
|
||||||
|
Duration(seconds: widget.aniSkipResult!.interval!.endTime!.ceil()));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _isCompleted = false;
|
bool _isCompleted = false;
|
||||||
|
|
@ -72,7 +77,8 @@ class _AniSkipCountDownButtonState extends ConsumerState<AniSkipCountDownButton>
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 40),
|
padding: const EdgeInsets.symmetric(horizontal: 40),
|
||||||
child: MaterialButton(
|
child: MaterialButton(
|
||||||
padding: const EdgeInsets.all(0),
|
padding: const EdgeInsets.all(0),
|
||||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(5)),
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(5)),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
_seekTo();
|
_seekTo();
|
||||||
},
|
},
|
||||||
|
|
@ -103,15 +109,21 @@ class _AniSkipCountDownButtonState extends ConsumerState<AniSkipCountDownButton>
|
||||||
),
|
),
|
||||||
Positioned.fill(
|
Positioned.fill(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 10),
|
padding:
|
||||||
|
const EdgeInsets.symmetric(horizontal: 10),
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
mainAxisAlignment:
|
||||||
|
MainAxisAlignment.spaceAround,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
widget.skipTypeText.toUpperCase(),
|
widget.skipTypeText.toUpperCase(),
|
||||||
style: const TextStyle(fontWeight: FontWeight.bold),
|
style: const TextStyle(
|
||||||
|
fontWeight: FontWeight.bold),
|
||||||
),
|
),
|
||||||
Text((widget.timeoutLength - (_controller.duration! * _controller.value).inSeconds)
|
Text((widget.timeoutLength -
|
||||||
|
(_controller.duration! *
|
||||||
|
_controller.value)
|
||||||
|
.inSeconds)
|
||||||
.toString()),
|
.toString()),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,12 @@ class CustomSeekBar extends StatefulWidget {
|
||||||
final Function(Duration)? onSeekStart;
|
final Function(Duration)? onSeekStart;
|
||||||
final Function(Duration)? onSeekEnd;
|
final Function(Duration)? onSeekEnd;
|
||||||
|
|
||||||
const CustomSeekBar({super.key, this.onSeekStart, this.onSeekEnd, required this.player, this.delta});
|
const CustomSeekBar(
|
||||||
|
{super.key,
|
||||||
|
this.onSeekStart,
|
||||||
|
this.onSeekEnd,
|
||||||
|
required this.player,
|
||||||
|
this.delta});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
CustomSeekBarState createState() => CustomSeekBarState();
|
CustomSeekBarState createState() => CustomSeekBarState();
|
||||||
|
|
@ -64,7 +69,8 @@ class CustomSeekBarState extends State<CustomSeekBar> {
|
||||||
width: 70,
|
width: 70,
|
||||||
child: Center(
|
child: Center(
|
||||||
child: Text(
|
child: Text(
|
||||||
(widget.delta ?? tempPosition ?? position).label(reference: duration),
|
(widget.delta ?? tempPosition ?? position)
|
||||||
|
.label(reference: duration),
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
height: 1.0,
|
height: 1.0,
|
||||||
fontSize: 12.0,
|
fontSize: 12.0,
|
||||||
|
|
@ -79,10 +85,15 @@ class CustomSeekBarState extends State<CustomSeekBar> {
|
||||||
),
|
),
|
||||||
child: Slider(
|
child: Slider(
|
||||||
max: max(duration.inMilliseconds.toDouble(), 0),
|
max: max(duration.inMilliseconds.toDouble(), 0),
|
||||||
value: max((widget.delta ?? tempPosition ?? position).inMilliseconds.toDouble(), 0),
|
value: max(
|
||||||
|
(widget.delta ?? tempPosition ?? position)
|
||||||
|
.inMilliseconds
|
||||||
|
.toDouble(),
|
||||||
|
0),
|
||||||
secondaryTrackValue: max(buffer.inMilliseconds.toDouble(), 0),
|
secondaryTrackValue: max(buffer.inMilliseconds.toDouble(), 0),
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
widget.onSeekStart?.call(Duration(milliseconds: value.toInt() - position.inMilliseconds));
|
widget.onSeekStart?.call(Duration(
|
||||||
|
milliseconds: value.toInt() - position.inMilliseconds));
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
setState(() {
|
setState(() {
|
||||||
tempPosition = Duration(milliseconds: value.toInt());
|
tempPosition = Duration(milliseconds: value.toInt());
|
||||||
|
|
@ -90,7 +101,8 @@ class CustomSeekBarState extends State<CustomSeekBar> {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onChangeEnd: (value) async {
|
onChangeEnd: (value) async {
|
||||||
widget.onSeekEnd?.call(Duration(milliseconds: value.toInt() - position.inMilliseconds));
|
widget.onSeekEnd?.call(Duration(
|
||||||
|
milliseconds: value.toInt() - position.inMilliseconds));
|
||||||
widget.player.seek(Duration(milliseconds: value.toInt()));
|
widget.player.seek(Duration(milliseconds: value.toInt()));
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,8 @@ class DesktopControllerWidget extends StatefulWidget {
|
||||||
required this.tempDuration});
|
required this.tempDuration});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<DesktopControllerWidget> createState() => _DesktopControllerWidgetState();
|
State<DesktopControllerWidget> createState() =>
|
||||||
|
_DesktopControllerWidgetState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _DesktopControllerWidgetState extends State<DesktopControllerWidget> {
|
class _DesktopControllerWidgetState extends State<DesktopControllerWidget> {
|
||||||
|
|
@ -151,26 +152,36 @@ class _DesktopControllerWidgetState extends State<DesktopControllerWidget> {
|
||||||
bindings: {
|
bindings: {
|
||||||
// Default key-board shortcuts.
|
// Default key-board shortcuts.
|
||||||
// https://support.google.com/youtube/answer/7631406
|
// https://support.google.com/youtube/answer/7631406
|
||||||
const SingleActivator(LogicalKeyboardKey.mediaPlay): () => widget.videoController.player.play(),
|
const SingleActivator(LogicalKeyboardKey.mediaPlay): () =>
|
||||||
const SingleActivator(LogicalKeyboardKey.mediaPause): () => widget.videoController.player.pause(),
|
widget.videoController.player.play(),
|
||||||
const SingleActivator(LogicalKeyboardKey.mediaPlayPause): () => widget.videoController.player.playOrPause(),
|
const SingleActivator(LogicalKeyboardKey.mediaPause): () =>
|
||||||
const SingleActivator(LogicalKeyboardKey.mediaTrackNext): () => widget.videoController.player.next(),
|
widget.videoController.player.pause(),
|
||||||
const SingleActivator(LogicalKeyboardKey.mediaTrackPrevious): () => widget.videoController.player.previous(),
|
const SingleActivator(LogicalKeyboardKey.mediaPlayPause): () =>
|
||||||
const SingleActivator(LogicalKeyboardKey.space): () => widget.videoController.player.playOrPause(),
|
widget.videoController.player.playOrPause(),
|
||||||
|
const SingleActivator(LogicalKeyboardKey.mediaTrackNext): () =>
|
||||||
|
widget.videoController.player.next(),
|
||||||
|
const SingleActivator(LogicalKeyboardKey.mediaTrackPrevious): () =>
|
||||||
|
widget.videoController.player.previous(),
|
||||||
|
const SingleActivator(LogicalKeyboardKey.space): () =>
|
||||||
|
widget.videoController.player.playOrPause(),
|
||||||
const SingleActivator(LogicalKeyboardKey.keyJ): () {
|
const SingleActivator(LogicalKeyboardKey.keyJ): () {
|
||||||
final rate = widget.videoController.player.state.position - const Duration(seconds: 10);
|
final rate = widget.videoController.player.state.position -
|
||||||
|
const Duration(seconds: 10);
|
||||||
widget.videoController.player.seek(rate);
|
widget.videoController.player.seek(rate);
|
||||||
},
|
},
|
||||||
const SingleActivator(LogicalKeyboardKey.keyL): () {
|
const SingleActivator(LogicalKeyboardKey.keyL): () {
|
||||||
final rate = widget.videoController.player.state.position + const Duration(seconds: 10);
|
final rate = widget.videoController.player.state.position +
|
||||||
|
const Duration(seconds: 10);
|
||||||
widget.videoController.player.seek(rate);
|
widget.videoController.player.seek(rate);
|
||||||
},
|
},
|
||||||
const SingleActivator(LogicalKeyboardKey.arrowLeft): () {
|
const SingleActivator(LogicalKeyboardKey.arrowLeft): () {
|
||||||
final rate = widget.videoController.player.state.position - const Duration(seconds: 5);
|
final rate = widget.videoController.player.state.position -
|
||||||
|
const Duration(seconds: 5);
|
||||||
widget.videoController.player.seek(rate);
|
widget.videoController.player.seek(rate);
|
||||||
},
|
},
|
||||||
const SingleActivator(LogicalKeyboardKey.arrowRight): () {
|
const SingleActivator(LogicalKeyboardKey.arrowRight): () {
|
||||||
final rate = widget.videoController.player.state.position + const Duration(seconds: 5);
|
final rate = widget.videoController.player.state.position +
|
||||||
|
const Duration(seconds: 5);
|
||||||
widget.videoController.player.seek(rate);
|
widget.videoController.player.seek(rate);
|
||||||
},
|
},
|
||||||
const SingleActivator(LogicalKeyboardKey.arrowUp): () {
|
const SingleActivator(LogicalKeyboardKey.arrowUp): () {
|
||||||
|
|
@ -182,7 +193,8 @@ class _DesktopControllerWidgetState extends State<DesktopControllerWidget> {
|
||||||
widget.videoController.player.setVolume(volume.clamp(0.0, 100.0));
|
widget.videoController.player.setVolume(volume.clamp(0.0, 100.0));
|
||||||
},
|
},
|
||||||
const SingleActivator(LogicalKeyboardKey.keyF): () => setFullScreen(),
|
const SingleActivator(LogicalKeyboardKey.keyF): () => setFullScreen(),
|
||||||
const SingleActivator(LogicalKeyboardKey.escape): () => setFullScreen(value: false),
|
const SingleActivator(LogicalKeyboardKey.escape): () =>
|
||||||
|
setFullScreen(value: false),
|
||||||
},
|
},
|
||||||
child: Stack(
|
child: Stack(
|
||||||
children: [
|
children: [
|
||||||
|
|
@ -192,7 +204,8 @@ class _DesktopControllerWidgetState extends State<DesktopControllerWidget> {
|
||||||
: Positioned(
|
: Positioned(
|
||||||
child: CustomSubtitleView(
|
child: CustomSubtitleView(
|
||||||
controller: widget.videoController,
|
controller: widget.videoController,
|
||||||
configuration: SubtitleViewConfiguration(style: subtileTextStyle(ref)),
|
configuration:
|
||||||
|
SubtitleViewConfiguration(style: subtileTextStyle(ref)),
|
||||||
)),
|
)),
|
||||||
),
|
),
|
||||||
Focus(
|
Focus(
|
||||||
|
|
@ -202,12 +215,16 @@ class _DesktopControllerWidgetState extends State<DesktopControllerWidget> {
|
||||||
? (e) {
|
? (e) {
|
||||||
if (e is PointerScrollEvent) {
|
if (e is PointerScrollEvent) {
|
||||||
if (e.delta.dy > 0) {
|
if (e.delta.dy > 0) {
|
||||||
final volume = widget.videoController.player.state.volume - 5.0;
|
final volume =
|
||||||
widget.videoController.player.setVolume(volume.clamp(0.0, 100.0));
|
widget.videoController.player.state.volume - 5.0;
|
||||||
|
widget.videoController.player
|
||||||
|
.setVolume(volume.clamp(0.0, 100.0));
|
||||||
}
|
}
|
||||||
if (e.delta.dy < 0) {
|
if (e.delta.dy < 0) {
|
||||||
final volume = widget.videoController.player.state.volume + 5.0;
|
final volume =
|
||||||
widget.videoController.player.setVolume(volume.clamp(0.0, 100.0));
|
widget.videoController.player.state.volume + 5.0;
|
||||||
|
widget.videoController.player
|
||||||
|
.setVolume(volume.clamp(0.0, 100.0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -226,12 +243,16 @@ class _DesktopControllerWidgetState extends State<DesktopControllerWidget> {
|
||||||
onPanUpdate: modifyVolumeOnScroll
|
onPanUpdate: modifyVolumeOnScroll
|
||||||
? (e) {
|
? (e) {
|
||||||
if (e.delta.dy > 0) {
|
if (e.delta.dy > 0) {
|
||||||
final volume = widget.videoController.player.state.volume - 5.0;
|
final volume =
|
||||||
widget.videoController.player.setVolume(volume.clamp(0.0, 100.0));
|
widget.videoController.player.state.volume - 5.0;
|
||||||
|
widget.videoController.player
|
||||||
|
.setVolume(volume.clamp(0.0, 100.0));
|
||||||
}
|
}
|
||||||
if (e.delta.dy < 0) {
|
if (e.delta.dy < 0) {
|
||||||
final volume = widget.videoController.player.state.volume + 5.0;
|
final volume =
|
||||||
widget.videoController.player.setVolume(volume.clamp(0.0, 100.0));
|
widget.videoController.player.state.volume + 5.0;
|
||||||
|
widget.videoController.player
|
||||||
|
.setVolume(volume.clamp(0.0, 100.0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
: null,
|
: null,
|
||||||
|
|
@ -239,7 +260,9 @@ class _DesktopControllerWidgetState extends State<DesktopControllerWidget> {
|
||||||
onHover: (_) => onHover(),
|
onHover: (_) => onHover(),
|
||||||
onEnter: (_) => onEnter(),
|
onEnter: (_) => onEnter(),
|
||||||
onExit: (_) => onExit(),
|
onExit: (_) => onExit(),
|
||||||
cursor: cursorVisible ? SystemMouseCursors.basic : SystemMouseCursors.none,
|
cursor: cursorVisible
|
||||||
|
? SystemMouseCursors.basic
|
||||||
|
: SystemMouseCursors.none,
|
||||||
child: Stack(
|
child: Stack(
|
||||||
children: [
|
children: [
|
||||||
AnimatedOpacity(
|
AnimatedOpacity(
|
||||||
|
|
@ -297,7 +320,9 @@ class _DesktopControllerWidgetState extends State<DesktopControllerWidget> {
|
||||||
Padding(
|
Padding(
|
||||||
padding: (
|
padding: (
|
||||||
// Add padding in fullscreen!
|
// Add padding in fullscreen!
|
||||||
isFullscreen(context) ? MediaQuery.of(context).padding : EdgeInsets.zero),
|
isFullscreen(context)
|
||||||
|
? MediaQuery.of(context).padding
|
||||||
|
: EdgeInsets.zero),
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
|
@ -315,20 +340,29 @@ class _DesktopControllerWidgetState extends State<DesktopControllerWidget> {
|
||||||
: 1.0,
|
: 1.0,
|
||||||
duration: controlsTransitionDuration,
|
duration: controlsTransitionDuration,
|
||||||
child: Center(
|
child: Center(
|
||||||
child: seekIndicatorTextWidget(Duration(seconds: swipeDuration),
|
child: seekIndicatorTextWidget(
|
||||||
widget.videoController.player.state.position))),
|
Duration(
|
||||||
|
seconds: swipeDuration),
|
||||||
|
widget.videoController.player
|
||||||
|
.state.position))),
|
||||||
),
|
),
|
||||||
widget.seekToWidget,
|
widget.seekToWidget,
|
||||||
Transform.translate(
|
Transform.translate(
|
||||||
offset: Offset.zero,
|
offset: Offset.zero,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 5),
|
padding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 5),
|
||||||
child: CustomSeekBar(
|
child: CustomSeekBar(
|
||||||
onSeekStart: (value) {
|
onSeekStart: (value) {
|
||||||
setState(() {
|
setState(() {
|
||||||
swipeDuration = value.inSeconds;
|
swipeDuration = value.inSeconds;
|
||||||
showSwipeDuration = true;
|
showSwipeDuration = true;
|
||||||
widget.tempDuration(widget.videoController.player.state.position + value);
|
widget.tempDuration(widget
|
||||||
|
.videoController
|
||||||
|
.player
|
||||||
|
.state
|
||||||
|
.position +
|
||||||
|
value);
|
||||||
});
|
});
|
||||||
_timer?.cancel();
|
_timer?.cancel();
|
||||||
},
|
},
|
||||||
|
|
@ -364,7 +398,9 @@ class _DesktopControllerWidgetState extends State<DesktopControllerWidget> {
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: (
|
padding: (
|
||||||
// Add padding in fullscreen!
|
// Add padding in fullscreen!
|
||||||
isFullscreen(context) ? MediaQuery.of(context).padding : EdgeInsets.zero),
|
isFullscreen(context)
|
||||||
|
? MediaQuery.of(context).padding
|
||||||
|
: EdgeInsets.zero),
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
Container(
|
Container(
|
||||||
|
|
@ -430,10 +466,12 @@ class CustomeMaterialDesktopPlayOrPauseButton extends StatefulWidget {
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
CustomeMaterialDesktopPlayOrPauseButtonState createState() => CustomeMaterialDesktopPlayOrPauseButtonState();
|
CustomeMaterialDesktopPlayOrPauseButtonState createState() =>
|
||||||
|
CustomeMaterialDesktopPlayOrPauseButtonState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class CustomeMaterialDesktopPlayOrPauseButtonState extends State<CustomeMaterialDesktopPlayOrPauseButton>
|
class CustomeMaterialDesktopPlayOrPauseButtonState
|
||||||
|
extends State<CustomeMaterialDesktopPlayOrPauseButton>
|
||||||
with SingleTickerProviderStateMixin {
|
with SingleTickerProviderStateMixin {
|
||||||
late final animation = AnimationController(
|
late final animation = AnimationController(
|
||||||
vsync: this,
|
vsync: this,
|
||||||
|
|
@ -497,10 +535,12 @@ class CustomMaterialDesktopVolumeButton extends StatefulWidget {
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
CustomMaterialDesktopVolumeButtonState createState() => CustomMaterialDesktopVolumeButtonState();
|
CustomMaterialDesktopVolumeButtonState createState() =>
|
||||||
|
CustomMaterialDesktopVolumeButtonState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class CustomMaterialDesktopVolumeButtonState extends State<CustomMaterialDesktopVolumeButton>
|
class CustomMaterialDesktopVolumeButtonState
|
||||||
|
extends State<CustomMaterialDesktopVolumeButton>
|
||||||
with SingleTickerProviderStateMixin {
|
with SingleTickerProviderStateMixin {
|
||||||
late double volume = widget.controller.player.state.volume;
|
late double volume = widget.controller.player.state.volume;
|
||||||
|
|
||||||
|
|
@ -663,13 +703,16 @@ class CustomMaterialDesktopPositionIndicator extends StatefulWidget {
|
||||||
final VideoController controller;
|
final VideoController controller;
|
||||||
final Duration? delta;
|
final Duration? delta;
|
||||||
|
|
||||||
const CustomMaterialDesktopPositionIndicator({super.key, required this.controller, this.delta});
|
const CustomMaterialDesktopPositionIndicator(
|
||||||
|
{super.key, required this.controller, this.delta});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
CustomMaterialDesktopPositionIndicatorState createState() => CustomMaterialDesktopPositionIndicatorState();
|
CustomMaterialDesktopPositionIndicatorState createState() =>
|
||||||
|
CustomMaterialDesktopPositionIndicatorState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class CustomMaterialDesktopPositionIndicatorState extends State<CustomMaterialDesktopPositionIndicator> {
|
class CustomMaterialDesktopPositionIndicatorState
|
||||||
|
extends State<CustomMaterialDesktopPositionIndicator> {
|
||||||
late Duration position = widget.controller.player.state.position;
|
late Duration position = widget.controller.player.state.position;
|
||||||
late Duration duration = widget.controller.player.state.duration;
|
late Duration duration = widget.controller.player.state.duration;
|
||||||
|
|
||||||
|
|
@ -755,10 +798,12 @@ class CustomMaterialDesktopFullscreenButton extends StatefulWidget {
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<CustomMaterialDesktopFullscreenButton> createState() => _CustomMaterialDesktopFullscreenButtonState();
|
State<CustomMaterialDesktopFullscreenButton> createState() =>
|
||||||
|
_CustomMaterialDesktopFullscreenButtonState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _CustomMaterialDesktopFullscreenButtonState extends State<CustomMaterialDesktopFullscreenButton> {
|
class _CustomMaterialDesktopFullscreenButtonState
|
||||||
|
extends State<CustomMaterialDesktopFullscreenButton> {
|
||||||
bool _isFullscreen = false;
|
bool _isFullscreen = false;
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
|
@ -769,7 +814,9 @@ class _CustomMaterialDesktopFullscreenButtonState extends State<CustomMaterialDe
|
||||||
_isFullscreen = isFullScreen;
|
_isFullscreen = isFullScreen;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
icon: _isFullscreen ? const Icon(Icons.fullscreen_exit) : const Icon(Icons.fullscreen),
|
icon: _isFullscreen
|
||||||
|
? const Icon(Icons.fullscreen_exit)
|
||||||
|
: const Icon(Icons.fullscreen),
|
||||||
iconSize: 25,
|
iconSize: 25,
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,8 @@ import 'package:flutter/material.dart';
|
||||||
class MediaIndicatorBuilder extends StatelessWidget {
|
class MediaIndicatorBuilder extends StatelessWidget {
|
||||||
final bool isVolumeIndicator;
|
final bool isVolumeIndicator;
|
||||||
final ValueNotifier<double> value;
|
final ValueNotifier<double> value;
|
||||||
const MediaIndicatorBuilder({super.key, required this.value, required this.isVolumeIndicator});
|
const MediaIndicatorBuilder(
|
||||||
|
{super.key, required this.value, required this.isVolumeIndicator});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
|
@ -12,7 +13,9 @@ class MediaIndicatorBuilder extends StatelessWidget {
|
||||||
builder: (context, value, child) => Padding(
|
builder: (context, value, child) => Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 40),
|
padding: const EdgeInsets.symmetric(horizontal: 40),
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment: isVolumeIndicator ? MainAxisAlignment.start : MainAxisAlignment.end,
|
mainAxisAlignment: isVolumeIndicator
|
||||||
|
? MainAxisAlignment.start
|
||||||
|
: MainAxisAlignment.end,
|
||||||
children: [
|
children: [
|
||||||
Container(
|
Container(
|
||||||
clipBehavior: Clip.antiAlias,
|
clipBehavior: Clip.antiAlias,
|
||||||
|
|
@ -42,8 +45,9 @@ class MediaIndicatorBuilder extends StatelessWidget {
|
||||||
),
|
),
|
||||||
child: SizedBox.fromSize(
|
child: SizedBox.fromSize(
|
||||||
size: const Size(130, 20),
|
size: const Size(130, 20),
|
||||||
child:
|
child: LinearProgressIndicator(
|
||||||
LinearProgressIndicator(value: value, backgroundColor: Colors.transparent)),
|
value: value,
|
||||||
|
backgroundColor: Colors.transparent)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -30,16 +30,19 @@ class MobileControllerWidget extends ConsumerStatefulWidget {
|
||||||
required this.videoStatekey});
|
required this.videoStatekey});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
ConsumerState<MobileControllerWidget> createState() => _MobileControllerWidgetState();
|
ConsumerState<MobileControllerWidget> createState() =>
|
||||||
|
_MobileControllerWidgetState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _MobileControllerWidgetState extends ConsumerState<MobileControllerWidget> {
|
class _MobileControllerWidgetState
|
||||||
|
extends ConsumerState<MobileControllerWidget> {
|
||||||
bool mount = true;
|
bool mount = true;
|
||||||
bool visible = true;
|
bool visible = true;
|
||||||
Duration controlsTransitionDuration = const Duration(milliseconds: 300);
|
Duration controlsTransitionDuration = const Duration(milliseconds: 300);
|
||||||
Color backdropColor = const Color(0x66000000);
|
Color backdropColor = const Color(0x66000000);
|
||||||
Timer? _timer;
|
Timer? _timer;
|
||||||
late final skipDuration = ref.watch(defaultDoubleTapToSkipLengthStateProvider);
|
late final skipDuration =
|
||||||
|
ref.watch(defaultDoubleTapToSkipLengthStateProvider);
|
||||||
final ValueNotifier<double> _brightnessValue = ValueNotifier(0.0);
|
final ValueNotifier<double> _brightnessValue = ValueNotifier(0.0);
|
||||||
final ValueNotifier<bool> _brightnessIndicator = ValueNotifier(false);
|
final ValueNotifier<bool> _brightnessIndicator = ValueNotifier(false);
|
||||||
Timer? _brightnessTimer;
|
Timer? _brightnessTimer;
|
||||||
|
|
@ -50,7 +53,8 @@ class _MobileControllerWidgetState extends ConsumerState<MobileControllerWidget>
|
||||||
// The default event stream in package:volume_controller is buggy.
|
// The default event stream in package:volume_controller is buggy.
|
||||||
bool _volumeInterceptEventStream = false;
|
bool _volumeInterceptEventStream = false;
|
||||||
|
|
||||||
Offset _dragInitialDelta = Offset.zero; // Initial position for horizontal drag
|
Offset _dragInitialDelta =
|
||||||
|
Offset.zero; // Initial position for horizontal drag
|
||||||
int swipeDuration = 0; // Duration to seek in video
|
int swipeDuration = 0; // Duration to seek in video
|
||||||
bool showSwipeDuration = false; // Whether to show the seek duration overlay
|
bool showSwipeDuration = false; // Whether to show the seek duration overlay
|
||||||
|
|
||||||
|
|
@ -188,15 +192,17 @@ class _MobileControllerWidgetState extends ConsumerState<MobileControllerWidget>
|
||||||
setState(() {
|
setState(() {
|
||||||
swipeDuration = seconds;
|
swipeDuration = seconds;
|
||||||
showSwipeDuration = true;
|
showSwipeDuration = true;
|
||||||
_seekBarDeltaValueNotifier =
|
_seekBarDeltaValueNotifier = Duration(
|
||||||
Duration(seconds: widget.videoController.player.state.position.inSeconds + seconds);
|
seconds: widget.videoController.player.state.position.inSeconds +
|
||||||
|
seconds);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void onHorizontalDragEnd() {
|
void onHorizontalDragEnd() {
|
||||||
if (swipeDuration != 0) {
|
if (swipeDuration != 0) {
|
||||||
Duration newPosition = widget.videoController.player.state.position + Duration(seconds: swipeDuration);
|
Duration newPosition = widget.videoController.player.state.position +
|
||||||
|
Duration(seconds: swipeDuration);
|
||||||
newPosition = newPosition.clamp(
|
newPosition = newPosition.clamp(
|
||||||
Duration.zero,
|
Duration.zero,
|
||||||
widget.videoController.player.state.duration,
|
widget.videoController.player.state.duration,
|
||||||
|
|
@ -233,7 +239,8 @@ class _MobileControllerWidgetState extends ConsumerState<MobileControllerWidget>
|
||||||
Future.microtask(() async {
|
Future.microtask(() async {
|
||||||
try {
|
try {
|
||||||
_brightnessValue.value = await ScreenBrightness.instance.application;
|
_brightnessValue.value = await ScreenBrightness.instance.application;
|
||||||
ScreenBrightness.instance.onApplicationScreenBrightnessChanged.listen((value) {
|
ScreenBrightness.instance.onApplicationScreenBrightnessChanged
|
||||||
|
.listen((value) {
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
_brightnessValue.value = value;
|
_brightnessValue.value = value;
|
||||||
}
|
}
|
||||||
|
|
@ -288,7 +295,8 @@ class _MobileControllerWidgetState extends ConsumerState<MobileControllerWidget>
|
||||||
: Positioned(
|
: Positioned(
|
||||||
child: CustomSubtitleView(
|
child: CustomSubtitleView(
|
||||||
controller: widget.videoController,
|
controller: widget.videoController,
|
||||||
configuration: SubtitleViewConfiguration(style: subtileTextStyle(ref)),
|
configuration:
|
||||||
|
SubtitleViewConfiguration(style: subtileTextStyle(ref)),
|
||||||
)),
|
)),
|
||||||
),
|
),
|
||||||
Focus(
|
Focus(
|
||||||
|
|
@ -329,7 +337,9 @@ class _MobileControllerWidgetState extends ConsumerState<MobileControllerWidget>
|
||||||
onTap: onTap,
|
onTap: onTap,
|
||||||
onDoubleTapDown: _handleTapDown,
|
onDoubleTapDown: _handleTapDown,
|
||||||
onDoubleTap: () {
|
onDoubleTap: () {
|
||||||
if (_tapPosition != null && _tapPosition!.dx > MediaQuery.of(context).size.width / 2) {
|
if (_tapPosition != null &&
|
||||||
|
_tapPosition!.dx >
|
||||||
|
MediaQuery.of(context).size.width / 2) {
|
||||||
onDoubleTapSeekForward();
|
onDoubleTapSeekForward();
|
||||||
} else {
|
} else {
|
||||||
onDoubleTapSeekBackward();
|
onDoubleTapSeekBackward();
|
||||||
|
|
@ -345,16 +355,19 @@ class _MobileControllerWidgetState extends ConsumerState<MobileControllerWidget>
|
||||||
final delta = e.delta.dy;
|
final delta = e.delta.dy;
|
||||||
final Offset position = e.localPosition;
|
final Offset position = e.localPosition;
|
||||||
|
|
||||||
if (position.dx <= MediaQuery.of(context).size.width / 2) {
|
if (position.dx <=
|
||||||
|
MediaQuery.of(context).size.width / 2) {
|
||||||
// Left side of screen swiped
|
// Left side of screen swiped
|
||||||
|
|
||||||
final brightness = _brightnessValue.value - delta / verticalGestureSensitivity;
|
final brightness = _brightnessValue.value -
|
||||||
|
delta / verticalGestureSensitivity;
|
||||||
final result = brightness.clamp(0.0, 1.0);
|
final result = brightness.clamp(0.0, 1.0);
|
||||||
setBrightness(result);
|
setBrightness(result);
|
||||||
} else {
|
} else {
|
||||||
// Right side of screen swiped
|
// Right side of screen swiped
|
||||||
|
|
||||||
final volume = _volumeValue.value - delta / verticalGestureSensitivity;
|
final volume = _volumeValue.value -
|
||||||
|
delta / verticalGestureSensitivity;
|
||||||
final result = volume.clamp(0.0, 1.0);
|
final result = volume.clamp(0.0, 1.0);
|
||||||
setVolume(result);
|
setVolume(result);
|
||||||
}
|
}
|
||||||
|
|
@ -368,7 +381,9 @@ class _MobileControllerWidgetState extends ConsumerState<MobileControllerWidget>
|
||||||
Padding(
|
Padding(
|
||||||
padding: (
|
padding: (
|
||||||
// Add padding in fullscreen!
|
// Add padding in fullscreen!
|
||||||
isFullscreen(context) ? MediaQuery.of(context).padding : EdgeInsets.zero),
|
isFullscreen(context)
|
||||||
|
? MediaQuery.of(context).padding
|
||||||
|
: EdgeInsets.zero),
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
|
@ -387,8 +402,11 @@ class _MobileControllerWidgetState extends ConsumerState<MobileControllerWidget>
|
||||||
duration: controlsTransitionDuration,
|
duration: controlsTransitionDuration,
|
||||||
child: Center(
|
child: Center(
|
||||||
child: Row(
|
child: Row(
|
||||||
children: mobilePrimaryButtonBar(context, widget.videoStatekey,
|
children: mobilePrimaryButtonBar(
|
||||||
widget.streamController, widget.videoController)),
|
context,
|
||||||
|
widget.videoStatekey,
|
||||||
|
widget.streamController,
|
||||||
|
widget.videoController)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -434,7 +452,9 @@ class _MobileControllerWidgetState extends ConsumerState<MobileControllerWidget>
|
||||||
),
|
),
|
||||||
// // Double-Tap Seek Seek-Bar:
|
// // Double-Tap Seek Seek-Bar:
|
||||||
if (!mount)
|
if (!mount)
|
||||||
if (_mountSeekBackwardButton || _mountSeekForwardButton || showSwipeDuration)
|
if (_mountSeekBackwardButton ||
|
||||||
|
_mountSeekForwardButton ||
|
||||||
|
showSwipeDuration)
|
||||||
Column(
|
Column(
|
||||||
children: [
|
children: [
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
|
|
@ -443,8 +463,9 @@ class _MobileControllerWidgetState extends ConsumerState<MobileControllerWidget>
|
||||||
children: [
|
children: [
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(bottom: 10),
|
padding: const EdgeInsets.only(bottom: 10),
|
||||||
child:
|
child: CustomSeekBar(
|
||||||
CustomSeekBar(delta: _seekBarDeltaValueNotifier, player: widget.videoController.player),
|
delta: _seekBarDeltaValueNotifier,
|
||||||
|
player: widget.videoController.player),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
@ -455,7 +476,9 @@ class _MobileControllerWidgetState extends ConsumerState<MobileControllerWidget>
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: (
|
padding: (
|
||||||
// Add padding in fullscreen!
|
// Add padding in fullscreen!
|
||||||
isFullscreen(context) ? MediaQuery.of(context).padding : EdgeInsets.zero),
|
isFullscreen(context)
|
||||||
|
? MediaQuery.of(context).padding
|
||||||
|
: EdgeInsets.zero),
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
Container(
|
Container(
|
||||||
|
|
@ -503,7 +526,8 @@ class _MobileControllerWidgetState extends ConsumerState<MobileControllerWidget>
|
||||||
curve: Curves.easeInOut,
|
curve: Curves.easeInOut,
|
||||||
opacity: value ? 1.0 : 0.0,
|
opacity: value ? 1.0 : 0.0,
|
||||||
duration: controlsTransitionDuration,
|
duration: controlsTransitionDuration,
|
||||||
child: MediaIndicatorBuilder(value: _volumeValue, isVolumeIndicator: true)),
|
child: MediaIndicatorBuilder(
|
||||||
|
value: _volumeValue, isVolumeIndicator: true)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
// // Brightness Indicator.
|
// // Brightness Indicator.
|
||||||
|
|
@ -514,7 +538,8 @@ class _MobileControllerWidgetState extends ConsumerState<MobileControllerWidget>
|
||||||
curve: Curves.easeInOut,
|
curve: Curves.easeInOut,
|
||||||
opacity: value ? 1.0 : 0.0,
|
opacity: value ? 1.0 : 0.0,
|
||||||
duration: controlsTransitionDuration,
|
duration: controlsTransitionDuration,
|
||||||
child: MediaIndicatorBuilder(value: _brightnessValue, isVolumeIndicator: false)),
|
child: MediaIndicatorBuilder(
|
||||||
|
value: _brightnessValue, isVolumeIndicator: false)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
// Seek Indicator.
|
// Seek Indicator.
|
||||||
|
|
@ -523,7 +548,8 @@ class _MobileControllerWidgetState extends ConsumerState<MobileControllerWidget>
|
||||||
duration: controlsTransitionDuration,
|
duration: controlsTransitionDuration,
|
||||||
opacity: showSwipeDuration ? 1 : 0,
|
opacity: showSwipeDuration ? 1 : 0,
|
||||||
child: seekIndicatorTextWidget(
|
child: seekIndicatorTextWidget(
|
||||||
Duration(seconds: swipeDuration), widget.videoController.player.state.position)),
|
Duration(seconds: swipeDuration),
|
||||||
|
widget.videoController.player.state.position)),
|
||||||
),
|
),
|
||||||
|
|
||||||
// Double-Tap Seek Button(s):
|
// Double-Tap Seek Button(s):
|
||||||
|
|
@ -554,20 +580,28 @@ class _MobileControllerWidgetState extends ConsumerState<MobileControllerWidget>
|
||||||
child: _BackwardSeekIndicator(
|
child: _BackwardSeekIndicator(
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_seekBarDeltaValueNotifier =
|
_seekBarDeltaValueNotifier = widget
|
||||||
widget.videoController.player.state.position - value;
|
.videoController
|
||||||
|
.player
|
||||||
|
.state
|
||||||
|
.position -
|
||||||
|
value;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
onSubmitted: (value) {
|
onSubmitted: (value) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_hideSeekBackwardButton = true;
|
_hideSeekBackwardButton = true;
|
||||||
});
|
});
|
||||||
var result = widget.videoController.player.state.position - value;
|
var result = widget.videoController.player
|
||||||
|
.state.position -
|
||||||
|
value;
|
||||||
result = result.clamp(
|
result = result.clamp(
|
||||||
Duration.zero,
|
Duration.zero,
|
||||||
widget.videoController.player.state.duration,
|
widget.videoController.player.state
|
||||||
|
.duration,
|
||||||
);
|
);
|
||||||
widget.videoController.player.seek(result);
|
widget.videoController.player
|
||||||
|
.seek(result);
|
||||||
},
|
},
|
||||||
skipDuration: skipDuration),
|
skipDuration: skipDuration),
|
||||||
)
|
)
|
||||||
|
|
@ -596,20 +630,28 @@ class _MobileControllerWidgetState extends ConsumerState<MobileControllerWidget>
|
||||||
child: _ForwardSeekIndicator(
|
child: _ForwardSeekIndicator(
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_seekBarDeltaValueNotifier =
|
_seekBarDeltaValueNotifier = widget
|
||||||
widget.videoController.player.state.position + value;
|
.videoController
|
||||||
|
.player
|
||||||
|
.state
|
||||||
|
.position +
|
||||||
|
value;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
onSubmitted: (value) {
|
onSubmitted: (value) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_hideSeekForwardButton = true;
|
_hideSeekForwardButton = true;
|
||||||
});
|
});
|
||||||
var result = widget.videoController.player.state.position + value;
|
var result = widget.videoController.player
|
||||||
|
.state.position +
|
||||||
|
value;
|
||||||
result = result.clamp(
|
result = result.clamp(
|
||||||
Duration.zero,
|
Duration.zero,
|
||||||
widget.videoController.player.state.duration,
|
widget.videoController.player.state
|
||||||
|
.duration,
|
||||||
);
|
);
|
||||||
widget.videoController.player.seek(result);
|
widget.videoController.player
|
||||||
|
.seek(result);
|
||||||
},
|
},
|
||||||
skipDuration: skipDuration),
|
skipDuration: skipDuration),
|
||||||
)
|
)
|
||||||
|
|
@ -814,10 +856,12 @@ class CustomMaterialPlayOrPauseButton extends StatefulWidget {
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
CustomMaterialPlayOrPauseButtonState createState() => CustomMaterialPlayOrPauseButtonState();
|
CustomMaterialPlayOrPauseButtonState createState() =>
|
||||||
|
CustomMaterialPlayOrPauseButtonState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class CustomMaterialPlayOrPauseButtonState extends State<CustomMaterialPlayOrPauseButton>
|
class CustomMaterialPlayOrPauseButtonState
|
||||||
|
extends State<CustomMaterialPlayOrPauseButton>
|
||||||
with SingleTickerProviderStateMixin {
|
with SingleTickerProviderStateMixin {
|
||||||
late final animation = AnimationController(
|
late final animation = AnimationController(
|
||||||
vsync: this,
|
vsync: this,
|
||||||
|
|
@ -871,8 +915,11 @@ class CustomMaterialPlayOrPauseButtonState extends State<CustomMaterialPlayOrPau
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Widget> mobilePrimaryButtonBar(BuildContext context, GlobalKey<VideoState> key,
|
List<Widget> mobilePrimaryButtonBar(
|
||||||
AnimeStreamController streamController, VideoController controller) {
|
BuildContext context,
|
||||||
|
GlobalKey<VideoState> key,
|
||||||
|
AnimeStreamController streamController,
|
||||||
|
VideoController controller) {
|
||||||
bool hasPrevEpisode = streamController.getEpisodeIndex().$1 + 1 !=
|
bool hasPrevEpisode = streamController.getEpisodeIndex().$1 + 1 !=
|
||||||
streamController.getEpisodesLength(streamController.getEpisodeIndex().$2);
|
streamController.getEpisodesLength(streamController.getEpisodeIndex().$2);
|
||||||
bool hasNextEpisode = streamController.getEpisodeIndex().$1 != 0;
|
bool hasNextEpisode = streamController.getEpisodeIndex().$1 != 0;
|
||||||
|
|
@ -885,7 +932,8 @@ List<Widget> mobilePrimaryButtonBar(BuildContext context, GlobalKey<VideoState>
|
||||||
if (isFullScreen) {
|
if (isFullScreen) {
|
||||||
key.currentState?.exitFullscreen();
|
key.currentState?.exitFullscreen();
|
||||||
}
|
}
|
||||||
pushReplacementMangaReaderView(context: context, chapter: streamController.getPrevEpisode());
|
pushReplacementMangaReaderView(
|
||||||
|
context: context, chapter: streamController.getPrevEpisode());
|
||||||
}
|
}
|
||||||
: null,
|
: null,
|
||||||
icon: Icon(
|
icon: Icon(
|
||||||
|
|
@ -909,7 +957,8 @@ List<Widget> mobilePrimaryButtonBar(BuildContext context, GlobalKey<VideoState>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
: null,
|
: null,
|
||||||
icon: Icon(Icons.skip_next, size: 35, color: hasPrevEpisode ? Colors.white : Colors.grey),
|
icon: Icon(Icons.skip_next,
|
||||||
|
size: 35, color: hasPrevEpisode ? Colors.white : Colors.grey),
|
||||||
),
|
),
|
||||||
const Spacer(flex: 3)
|
const Spacer(flex: 3)
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -43,9 +43,9 @@ class _FontSettingWidgetState extends ConsumerState<FontSettingWidget> {
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
iconButton(Icons.remove, () {
|
iconButton(Icons.remove, () {
|
||||||
ref
|
ref.read(subtitleSettingsStateProvider.notifier).set(
|
||||||
.read(subtitleSettingsStateProvider.notifier)
|
subtitleSettings..fontSize = subtitleSettings.fontSize! - 1,
|
||||||
.set(subtitleSettings..fontSize = subtitleSettings.fontSize! - 1, true);
|
true);
|
||||||
setState(() {});
|
setState(() {});
|
||||||
},
|
},
|
||||||
backgroundColor: context.dynamicWhiteBlackColor,
|
backgroundColor: context.dynamicWhiteBlackColor,
|
||||||
|
|
@ -54,12 +54,15 @@ class _FontSettingWidgetState extends ConsumerState<FontSettingWidget> {
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: 200,
|
width: 200,
|
||||||
child: TextFormField(
|
child: TextFormField(
|
||||||
controller: TextEditingController(text: subtitleSettings.fontSize.toString()),
|
controller: TextEditingController(
|
||||||
|
text: subtitleSettings.fontSize.toString()),
|
||||||
keyboardType: TextInputType.number,
|
keyboardType: TextInputType.number,
|
||||||
onChanged: (v) {
|
onChanged: (v) {
|
||||||
final val = int.tryParse(v);
|
final val = int.tryParse(v);
|
||||||
if (val != null) {
|
if (val != null) {
|
||||||
ref.read(subtitleSettingsStateProvider.notifier).set(subtitleSettings..fontSize = val, true);
|
ref
|
||||||
|
.read(subtitleSettingsStateProvider.notifier)
|
||||||
|
.set(subtitleSettings..fontSize = val, true);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
|
|
@ -67,40 +70,51 @@ class _FontSettingWidgetState extends ConsumerState<FontSettingWidget> {
|
||||||
isDense: true,
|
isDense: true,
|
||||||
filled: true,
|
filled: true,
|
||||||
fillColor: Colors.transparent,
|
fillColor: Colors.transparent,
|
||||||
enabledBorder: OutlineInputBorder(borderSide: BorderSide(color: context.dynamicThemeColor)),
|
enabledBorder: OutlineInputBorder(
|
||||||
focusedBorder: OutlineInputBorder(borderSide: BorderSide(color: context.dynamicThemeColor)),
|
borderSide:
|
||||||
border: OutlineInputBorder(borderSide: BorderSide(color: context.dynamicThemeColor))),
|
BorderSide(color: context.dynamicThemeColor)),
|
||||||
|
focusedBorder: OutlineInputBorder(
|
||||||
|
borderSide:
|
||||||
|
BorderSide(color: context.dynamicThemeColor)),
|
||||||
|
border: OutlineInputBorder(
|
||||||
|
borderSide:
|
||||||
|
BorderSide(color: context.dynamicThemeColor))),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
iconButton(Icons.add, () {
|
iconButton(Icons.add, () {
|
||||||
ref
|
ref.read(subtitleSettingsStateProvider.notifier).set(
|
||||||
.read(subtitleSettingsStateProvider.notifier)
|
subtitleSettings..fontSize = subtitleSettings.fontSize! + 1,
|
||||||
.set(subtitleSettings..fontSize = subtitleSettings.fontSize! + 1, true);
|
true);
|
||||||
setState(() {});
|
setState(() {});
|
||||||
},
|
},
|
||||||
backgroundColor: context.dynamicWhiteBlackColor,
|
backgroundColor: context.dynamicWhiteBlackColor,
|
||||||
iconColors: context.isLight ? Colors.white : Colors.black,
|
iconColors: context.isLight ? Colors.white : Colors.black,
|
||||||
size: 25),
|
size: 25),
|
||||||
iconButton(Icons.format_bold, () {
|
iconButton(Icons.format_bold, () {
|
||||||
ref
|
ref.read(subtitleSettingsStateProvider.notifier).set(
|
||||||
.read(subtitleSettingsStateProvider.notifier)
|
subtitleSettings..useBold = !subtitleSettings.useBold!,
|
||||||
.set(subtitleSettings..useBold = !subtitleSettings.useBold!, true);
|
true);
|
||||||
setState(() {});
|
|
||||||
}, iconColors: subtitleSettings.useBold! ? null : context.dynamicWhiteBlackColor.withValues(alpha: 0.5)),
|
|
||||||
iconButton(Icons.format_italic, () {
|
|
||||||
ref
|
|
||||||
.read(subtitleSettingsStateProvider.notifier)
|
|
||||||
.set(subtitleSettings..useItalic = !subtitleSettings.useItalic!, true);
|
|
||||||
setState(() {});
|
setState(() {});
|
||||||
},
|
},
|
||||||
iconColors:
|
iconColors: subtitleSettings.useBold!
|
||||||
subtitleSettings.useItalic! ? null : context.dynamicWhiteBlackColor.withValues(alpha: 0.5)),
|
? null
|
||||||
|
: context.dynamicWhiteBlackColor.withValues(alpha: 0.5)),
|
||||||
|
iconButton(Icons.format_italic, () {
|
||||||
|
ref.read(subtitleSettingsStateProvider.notifier).set(
|
||||||
|
subtitleSettings..useItalic = !subtitleSettings.useItalic!,
|
||||||
|
true);
|
||||||
|
setState(() {});
|
||||||
|
},
|
||||||
|
iconColors: subtitleSettings.useItalic!
|
||||||
|
? null
|
||||||
|
: context.dynamicWhiteBlackColor.withValues(alpha: 0.5)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8.0),
|
||||||
child: Text("Lorem ipsum dolor sit amet",
|
child: Text("Lorem ipsum dolor sit amet",
|
||||||
style: subtileTextStyle(ref).copyWith(fontSize: 22), textAlign: TextAlign.center),
|
style: subtileTextStyle(ref).copyWith(fontSize: 22),
|
||||||
|
textAlign: TextAlign.center),
|
||||||
),
|
),
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
|
|
@ -154,7 +168,8 @@ class _ColorSettingWidgetState extends ConsumerState<ColorSettingWidget> {
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.circular(5),
|
borderRadius: BorderRadius.circular(5),
|
||||||
color: color,
|
color: color,
|
||||||
border: Border.all(width: 2, color: context.dynamicWhiteBlackColor)),
|
border: Border.all(
|
||||||
|
width: 2, color: context.dynamicWhiteBlackColor)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Text("#${color.hexCode}", style: TextStyle(color: context.textColor)),
|
Text("#${color.hexCode}", style: TextStyle(color: context.textColor)),
|
||||||
|
|
@ -170,12 +185,15 @@ class _ColorSettingWidgetState extends ConsumerState<ColorSettingWidget> {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final subSets = ref.watch(subtitleSettingsStateProvider);
|
final subSets = ref.watch(subtitleSettingsStateProvider);
|
||||||
final textColor =
|
final textColor = Color.fromARGB(subSets.textColorA!, subSets.textColorR!,
|
||||||
Color.fromARGB(subSets.textColorA!, subSets.textColorR!, subSets.textColorG!, subSets.textColorB!);
|
subSets.textColorG!, subSets.textColorB!);
|
||||||
final borderColor =
|
final borderColor = Color.fromARGB(subSets.borderColorA!,
|
||||||
Color.fromARGB(subSets.borderColorA!, subSets.borderColorR!, subSets.borderColorG!, subSets.borderColorB!);
|
subSets.borderColorR!, subSets.borderColorG!, subSets.borderColorB!);
|
||||||
final backgroundColor = Color.fromARGB(
|
final backgroundColor = Color.fromARGB(
|
||||||
subSets.backgroundColorA!, subSets.backgroundColorR!, subSets.backgroundColorG!, subSets.backgroundColorB!);
|
subSets.backgroundColorA!,
|
||||||
|
subSets.backgroundColorR!,
|
||||||
|
subSets.backgroundColorG!,
|
||||||
|
subSets.backgroundColorB!);
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.all(20),
|
padding: const EdgeInsets.all(20),
|
||||||
child: Column(
|
child: Column(
|
||||||
|
|
@ -198,45 +216,72 @@ class _ColorSettingWidgetState extends ConsumerState<ColorSettingWidget> {
|
||||||
),
|
),
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
Expanded(flex: 3, child: button(context.l10n.text, "text", textColor)),
|
Expanded(
|
||||||
Expanded(flex: 3, child: button(context.l10n.border, "border", borderColor)),
|
flex: 3, child: button(context.l10n.text, "text", textColor)),
|
||||||
Expanded(flex: 3, child: button(context.l10n.background, "backgroud", backgroundColor)),
|
Expanded(
|
||||||
|
flex: 3,
|
||||||
|
child: button(context.l10n.border, "border", borderColor)),
|
||||||
|
Expanded(
|
||||||
|
flex: 3,
|
||||||
|
child: button(
|
||||||
|
context.l10n.background, "backgroud", backgroundColor)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8.0),
|
||||||
child: Text("Lorem ipsum dolor sit amet",
|
child: Text("Lorem ipsum dolor sit amet",
|
||||||
style: subtileTextStyle(ref).copyWith(fontSize: 22), textAlign: TextAlign.center),
|
style: subtileTextStyle(ref).copyWith(fontSize: 22),
|
||||||
|
textAlign: TextAlign.center),
|
||||||
),
|
),
|
||||||
if (selector == "text") ...[
|
if (selector == "text") ...[
|
||||||
rgbaFilterWidget(subSets.textColorA!, subSets.textColorR!, subSets.textColorG!, subSets.textColorB!, (val) {
|
rgbaFilterWidget(subSets.textColorA!, subSets.textColorR!,
|
||||||
|
subSets.textColorG!, subSets.textColorB!, (val) {
|
||||||
if (val.$3 == "r") {
|
if (val.$3 == "r") {
|
||||||
ref.read(subtitleSettingsStateProvider.notifier).set(subSets..textColorR = val.$1.toInt(), val.$2);
|
ref
|
||||||
|
.read(subtitleSettingsStateProvider.notifier)
|
||||||
|
.set(subSets..textColorR = val.$1.toInt(), val.$2);
|
||||||
} else if (val.$3 == "g") {
|
} else if (val.$3 == "g") {
|
||||||
ref.read(subtitleSettingsStateProvider.notifier).set(subSets..textColorG = val.$1.toInt(), val.$2);
|
ref
|
||||||
|
.read(subtitleSettingsStateProvider.notifier)
|
||||||
|
.set(subSets..textColorG = val.$1.toInt(), val.$2);
|
||||||
} else if (val.$3 == "b") {
|
} else if (val.$3 == "b") {
|
||||||
ref.read(subtitleSettingsStateProvider.notifier).set(subSets..textColorB = val.$1.toInt(), val.$2);
|
ref
|
||||||
|
.read(subtitleSettingsStateProvider.notifier)
|
||||||
|
.set(subSets..textColorB = val.$1.toInt(), val.$2);
|
||||||
} else {
|
} else {
|
||||||
ref.read(subtitleSettingsStateProvider.notifier).set(subSets..textColorA = val.$1.toInt(), val.$2);
|
ref
|
||||||
|
.read(subtitleSettingsStateProvider.notifier)
|
||||||
|
.set(subSets..textColorA = val.$1.toInt(), val.$2);
|
||||||
}
|
}
|
||||||
setState(() {});
|
setState(() {});
|
||||||
}, context),
|
}, context),
|
||||||
] else if (selector == "border") ...[
|
] else if (selector == "border") ...[
|
||||||
rgbaFilterWidget(subSets.borderColorA!, subSets.borderColorR!, subSets.borderColorG!, subSets.borderColorB!,
|
rgbaFilterWidget(subSets.borderColorA!, subSets.borderColorR!,
|
||||||
(val) {
|
subSets.borderColorG!, subSets.borderColorB!, (val) {
|
||||||
if (val.$3 == "r") {
|
if (val.$3 == "r") {
|
||||||
ref.read(subtitleSettingsStateProvider.notifier).set(subSets..borderColorR = val.$1.toInt(), val.$2);
|
ref
|
||||||
|
.read(subtitleSettingsStateProvider.notifier)
|
||||||
|
.set(subSets..borderColorR = val.$1.toInt(), val.$2);
|
||||||
} else if (val.$3 == "g") {
|
} else if (val.$3 == "g") {
|
||||||
ref.read(subtitleSettingsStateProvider.notifier).set(subSets..borderColorG = val.$1.toInt(), val.$2);
|
ref
|
||||||
|
.read(subtitleSettingsStateProvider.notifier)
|
||||||
|
.set(subSets..borderColorG = val.$1.toInt(), val.$2);
|
||||||
} else if (val.$3 == "b") {
|
} else if (val.$3 == "b") {
|
||||||
ref.read(subtitleSettingsStateProvider.notifier).set(subSets..borderColorB = val.$1.toInt(), val.$2);
|
ref
|
||||||
|
.read(subtitleSettingsStateProvider.notifier)
|
||||||
|
.set(subSets..borderColorB = val.$1.toInt(), val.$2);
|
||||||
} else {
|
} else {
|
||||||
ref.read(subtitleSettingsStateProvider.notifier).set(subSets..borderColorA = val.$1.toInt(), val.$2);
|
ref
|
||||||
|
.read(subtitleSettingsStateProvider.notifier)
|
||||||
|
.set(subSets..borderColorA = val.$1.toInt(), val.$2);
|
||||||
}
|
}
|
||||||
setState(() {});
|
setState(() {});
|
||||||
}, context),
|
}, context),
|
||||||
] else ...[
|
] else ...[
|
||||||
rgbaFilterWidget(subSets.backgroundColorA!, subSets.backgroundColorR!, subSets.backgroundColorG!,
|
rgbaFilterWidget(
|
||||||
|
subSets.backgroundColorA!,
|
||||||
|
subSets.backgroundColorR!,
|
||||||
|
subSets.backgroundColorG!,
|
||||||
subSets.backgroundColorB!, (val) {
|
subSets.backgroundColorB!, (val) {
|
||||||
if (val.$3 == "r") {
|
if (val.$3 == "r") {
|
||||||
ref
|
ref
|
||||||
|
|
@ -279,7 +324,8 @@ Widget iconButton(IconData icon, void Function()? onPressed,
|
||||||
width: size,
|
width: size,
|
||||||
child: IconButton(
|
child: IconButton(
|
||||||
iconSize: size * 0.9,
|
iconSize: size * 0.9,
|
||||||
style: ButtonStyle(backgroundColor: WidgetStatePropertyAll(backgroundColor)),
|
style: ButtonStyle(
|
||||||
|
backgroundColor: WidgetStatePropertyAll(backgroundColor)),
|
||||||
padding: const EdgeInsets.all(1),
|
padding: const EdgeInsets.all(1),
|
||||||
onPressed: onPressed,
|
onPressed: onPressed,
|
||||||
icon: Icon(icon, color: iconColors)),
|
icon: Icon(icon, color: iconColors)),
|
||||||
|
|
|
||||||
|
|
@ -77,10 +77,12 @@ class _CustomSubtitleViewState extends ConsumerState<CustomSubtitleView> {
|
||||||
return LayoutBuilder(
|
return LayoutBuilder(
|
||||||
builder: (context, constraints) {
|
builder: (context, constraints) {
|
||||||
final nr = (constraints.maxWidth * constraints.maxHeight);
|
final nr = (constraints.maxWidth * constraints.maxHeight);
|
||||||
const dr = kTextScaleFactorReferenceWidth * kTextScaleFactorReferenceHeight;
|
const dr =
|
||||||
|
kTextScaleFactorReferenceWidth * kTextScaleFactorReferenceHeight;
|
||||||
final textScaleFactor = sqrt((nr / dr).clamp(0.0, 1.0));
|
final textScaleFactor = sqrt((nr / dr).clamp(0.0, 1.0));
|
||||||
|
|
||||||
final textScaler = widget.configuration.textScaler ?? TextScaler.linear(textScaleFactor);
|
final textScaler = widget.configuration.textScaler ??
|
||||||
|
TextScaler.linear(textScaleFactor);
|
||||||
return Material(
|
return Material(
|
||||||
color: Colors.transparent,
|
color: Colors.transparent,
|
||||||
child: AnimatedContainer(
|
child: AnimatedContainer(
|
||||||
|
|
@ -105,19 +107,35 @@ class _CustomSubtitleViewState extends ConsumerState<CustomSubtitleView> {
|
||||||
|
|
||||||
TextStyle subtileTextStyle(WidgetRef ref) {
|
TextStyle subtileTextStyle(WidgetRef ref) {
|
||||||
final subSets = ref.watch(subtitleSettingsStateProvider);
|
final subSets = ref.watch(subtitleSettingsStateProvider);
|
||||||
final borderColor =
|
final borderColor = Color.fromARGB(subSets.borderColorA!,
|
||||||
Color.fromARGB(subSets.borderColorA!, subSets.borderColorR!, subSets.borderColorG!, subSets.borderColorB!);
|
subSets.borderColorR!, subSets.borderColorG!, subSets.borderColorB!);
|
||||||
return TextStyle(
|
return TextStyle(
|
||||||
fontSize: subSets.fontSize!.toDouble(),
|
fontSize: subSets.fontSize!.toDouble(),
|
||||||
fontWeight: subSets.useBold! ? FontWeight.bold : null,
|
fontWeight: subSets.useBold! ? FontWeight.bold : null,
|
||||||
fontStyle: subSets.useItalic! ? FontStyle.italic : null,
|
fontStyle: subSets.useItalic! ? FontStyle.italic : null,
|
||||||
color: Color.fromARGB(subSets.textColorA!, subSets.textColorR!, subSets.textColorG!, subSets.textColorB!),
|
color: Color.fromARGB(subSets.textColorA!, subSets.textColorR!,
|
||||||
|
subSets.textColorG!, subSets.textColorB!),
|
||||||
shadows: [
|
shadows: [
|
||||||
Shadow(offset: const Offset(-1.5, -1.5), color: borderColor, blurRadius: 1.4),
|
Shadow(
|
||||||
Shadow(offset: const Offset(1.5, -1.5), color: borderColor, blurRadius: 1.4),
|
offset: const Offset(-1.5, -1.5),
|
||||||
Shadow(offset: const Offset(1.5, 1.5), color: borderColor, blurRadius: 1.4),
|
color: borderColor,
|
||||||
Shadow(offset: const Offset(-1.5, 1.5), color: borderColor, blurRadius: 1.4)
|
blurRadius: 1.4),
|
||||||
|
Shadow(
|
||||||
|
offset: const Offset(1.5, -1.5),
|
||||||
|
color: borderColor,
|
||||||
|
blurRadius: 1.4),
|
||||||
|
Shadow(
|
||||||
|
offset: const Offset(1.5, 1.5),
|
||||||
|
color: borderColor,
|
||||||
|
blurRadius: 1.4),
|
||||||
|
Shadow(
|
||||||
|
offset: const Offset(-1.5, 1.5),
|
||||||
|
color: borderColor,
|
||||||
|
blurRadius: 1.4)
|
||||||
],
|
],
|
||||||
backgroundColor: Color.fromARGB(
|
backgroundColor: Color.fromARGB(
|
||||||
subSets.backgroundColorA!, subSets.backgroundColorR!, subSets.backgroundColorG!, subSets.backgroundColorB!));
|
subSets.backgroundColorA!,
|
||||||
|
subSets.backgroundColorR!,
|
||||||
|
subSets.backgroundColorG!,
|
||||||
|
subSets.backgroundColorB!));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,8 @@ class BrowseScreen extends ConsumerStatefulWidget {
|
||||||
ConsumerState<BrowseScreen> createState() => _BrowseScreenState();
|
ConsumerState<BrowseScreen> createState() => _BrowseScreenState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _BrowseScreenState extends ConsumerState<BrowseScreen> with TickerProviderStateMixin {
|
class _BrowseScreenState extends ConsumerState<BrowseScreen>
|
||||||
|
with TickerProviderStateMixin {
|
||||||
late TabController _tabBarController;
|
late TabController _tabBarController;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
@ -74,26 +75,33 @@ class _BrowseScreenState extends ConsumerState<BrowseScreen> with TickerProvider
|
||||||
)
|
)
|
||||||
: Row(
|
: Row(
|
||||||
children: [
|
children: [
|
||||||
if (_tabBarController.index == 2 || _tabBarController.index == 3)
|
if (_tabBarController.index == 2 ||
|
||||||
|
_tabBarController.index == 3)
|
||||||
IconButton(
|
IconButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
context.push('/createExtension');
|
context.push('/createExtension');
|
||||||
},
|
},
|
||||||
icon: Icon(Icons.add_outlined, color: Theme.of(context).hintColor)),
|
icon: Icon(Icons.add_outlined,
|
||||||
|
color: Theme.of(context).hintColor)),
|
||||||
_tabBarController.index != 4
|
_tabBarController.index != 4
|
||||||
? IconButton(
|
? IconButton(
|
||||||
splashRadius: 20,
|
splashRadius: 20,
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
if (_tabBarController.index != 1 && _tabBarController.index != 0) {
|
if (_tabBarController.index != 1 &&
|
||||||
|
_tabBarController.index != 0) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_isSearch = true;
|
_isSearch = true;
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
context.push('/globalSearch', extra: _tabBarController.index == 0 ? true : false);
|
context.push('/globalSearch',
|
||||||
|
extra: _tabBarController.index == 0
|
||||||
|
? true
|
||||||
|
: false);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
icon: Icon(
|
icon: Icon(
|
||||||
_tabBarController.index == 0 || _tabBarController.index == 1
|
_tabBarController.index == 0 ||
|
||||||
|
_tabBarController.index == 1
|
||||||
? Icons.travel_explore_rounded
|
? Icons.travel_explore_rounded
|
||||||
: Icons.search_rounded,
|
: Icons.search_rounded,
|
||||||
color: Theme.of(context).hintColor))
|
color: Theme.of(context).hintColor))
|
||||||
|
|
@ -118,7 +126,8 @@ class _BrowseScreenState extends ConsumerState<BrowseScreen> with TickerProvider
|
||||||
icon: Icon(
|
icon: Icon(
|
||||||
_tabBarController.index == 0 || _tabBarController.index == 1
|
_tabBarController.index == 0 || _tabBarController.index == 1
|
||||||
? Icons.filter_list_sharp
|
? Icons.filter_list_sharp
|
||||||
: _tabBarController.index == 2 || _tabBarController.index == 3
|
: _tabBarController.index == 2 ||
|
||||||
|
_tabBarController.index == 3
|
||||||
? Icons.translate_rounded
|
? Icons.translate_rounded
|
||||||
: Icons.help_outline_outlined,
|
: Icons.help_outline_outlined,
|
||||||
color: Theme.of(context).hintColor)),
|
color: Theme.of(context).hintColor)),
|
||||||
|
|
@ -132,7 +141,11 @@ class _BrowseScreenState extends ConsumerState<BrowseScreen> with TickerProvider
|
||||||
Tab(text: l10n.anime_sources),
|
Tab(text: l10n.anime_sources),
|
||||||
Tab(
|
Tab(
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [Text(l10n.manga_extensions), const SizedBox(width: 8), _extensionUpdateNumbers(ref, true)],
|
children: [
|
||||||
|
Text(l10n.manga_extensions),
|
||||||
|
const SizedBox(width: 8),
|
||||||
|
_extensionUpdateNumbers(ref, true)
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Tab(
|
Tab(
|
||||||
|
|
@ -187,18 +200,23 @@ Widget _extensionUpdateNumbers(WidgetRef ref, bool isManga) {
|
||||||
.watch(fireImmediately: true),
|
.watch(fireImmediately: true),
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
if (snapshot.hasData && snapshot.data!.isNotEmpty) {
|
if (snapshot.hasData && snapshot.data!.isNotEmpty) {
|
||||||
final entries =
|
final entries = snapshot.data!
|
||||||
snapshot.data!.where((element) => compareVersions(element.version!, element.versionLast!) < 0).toList();
|
.where((element) =>
|
||||||
|
compareVersions(element.version!, element.versionLast!) < 0)
|
||||||
|
.toList();
|
||||||
return entries.isEmpty
|
return entries.isEmpty
|
||||||
? Container()
|
? Container()
|
||||||
: Container(
|
: Container(
|
||||||
decoration:
|
decoration: BoxDecoration(
|
||||||
BoxDecoration(borderRadius: BorderRadius.circular(20), color: Theme.of(context).focusColor),
|
borderRadius: BorderRadius.circular(20),
|
||||||
|
color: Theme.of(context).focusColor),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(5),
|
padding: const EdgeInsets.all(5),
|
||||||
child: Text(
|
child: Text(
|
||||||
entries.length.toString(),
|
entries.length.toString(),
|
||||||
style: TextStyle(fontSize: 12, color: Theme.of(context).textTheme.bodySmall!.color),
|
style: TextStyle(
|
||||||
|
fontSize: 12,
|
||||||
|
color: Theme.of(context).textTheme.bodySmall!.color),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,8 @@ Mode getSourceMode(Source? source) {
|
||||||
|
|
||||||
class _CodeEditorState extends ConsumerState<CodeEditor> {
|
class _CodeEditorState extends ConsumerState<CodeEditor> {
|
||||||
dynamic result;
|
dynamic result;
|
||||||
late final source = widget.sourceId == null ? null : isar.sources.getSync(widget.sourceId!);
|
late final source =
|
||||||
|
widget.sourceId == null ? null : isar.sources.getSync(widget.sourceId!);
|
||||||
late final controller = CodeController(
|
late final controller = CodeController(
|
||||||
text: source?.sourceCode ?? "",
|
text: source?.sourceCode ?? "",
|
||||||
language: getSourceMode(source),
|
language: getSourceMode(source),
|
||||||
|
|
@ -59,7 +60,8 @@ class _CodeEditorState extends ConsumerState<CodeEditor> {
|
||||||
bool _isLoading = false;
|
bool _isLoading = false;
|
||||||
String _errorText = "";
|
String _errorText = "";
|
||||||
bool _error = false;
|
bool _error = false;
|
||||||
final _logsNotifier = ValueNotifier<List<(LoggerLevel, String, DateTime)>>([]);
|
final _logsNotifier =
|
||||||
|
ValueNotifier<List<(LoggerLevel, String, DateTime)>>([]);
|
||||||
late final _logStreamController = Logger.logStreamController;
|
late final _logStreamController = Logger.logStreamController;
|
||||||
final _scrollController = ScrollController();
|
final _scrollController = ScrollController();
|
||||||
@override
|
@override
|
||||||
|
|
@ -96,13 +98,15 @@ class _CodeEditorState extends ConsumerState<CodeEditor> {
|
||||||
),
|
),
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
style: ElevatedButton.styleFrom(backgroundColor: context.primaryColor),
|
style: ElevatedButton.styleFrom(
|
||||||
|
backgroundColor: context.primaryColor),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.pop(context, 'filter');
|
Navigator.pop(context, 'filter');
|
||||||
},
|
},
|
||||||
child: Text(
|
child: Text(
|
||||||
context.l10n.filter,
|
context.l10n.filter,
|
||||||
style: TextStyle(color: Theme.of(context).scaffoldBackgroundColor),
|
style: TextStyle(
|
||||||
|
color: Theme.of(context).scaffoldBackgroundColor),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
@ -156,7 +160,8 @@ class _CodeEditorState extends ConsumerState<CodeEditor> {
|
||||||
gutterStyle: const GutterStyle(
|
gutterStyle: const GutterStyle(
|
||||||
textStyle: TextStyle(
|
textStyle: TextStyle(
|
||||||
color: Colors.grey,
|
color: Colors.grey,
|
||||||
height: 1.5, // Issue #307 fix, found in package: flutter-code-editor issue #270
|
height:
|
||||||
|
1.5, // Issue #307 fix, found in package: flutter-code-editor issue #270
|
||||||
),
|
),
|
||||||
showLineNumbers: true,
|
showLineNumbers: true,
|
||||||
),
|
),
|
||||||
|
|
@ -165,7 +170,8 @@ class _CodeEditorState extends ConsumerState<CodeEditor> {
|
||||||
source?.sourceCode = a;
|
source?.sourceCode = a;
|
||||||
});
|
});
|
||||||
if (source != null && mounted) {
|
if (source != null && mounted) {
|
||||||
isar.writeTxnSync(() => isar.sources.putSync(source!));
|
isar.writeTxnSync(
|
||||||
|
() => isar.sources.putSync(source!));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|
@ -182,11 +188,13 @@ class _CodeEditorState extends ConsumerState<CodeEditor> {
|
||||||
icon: const Icon(Icons.keyboard_arrow_down),
|
icon: const Icon(Icons.keyboard_arrow_down),
|
||||||
isExpanded: true,
|
isExpanded: true,
|
||||||
value: _serviceIndex,
|
value: _serviceIndex,
|
||||||
hint: Text(_getServices(context)[_serviceIndex].$1, style: const TextStyle(fontSize: 13)),
|
hint: Text(_getServices(context)[_serviceIndex].$1,
|
||||||
|
style: const TextStyle(fontSize: 13)),
|
||||||
items: _getServices(context)
|
items: _getServices(context)
|
||||||
.map((e) => DropdownMenuItem(
|
.map((e) => DropdownMenuItem(
|
||||||
value: e.$2,
|
value: e.$2,
|
||||||
child: Text(e.$1, style: const TextStyle(fontSize: 13)),
|
child: Text(e.$1,
|
||||||
|
style: const TextStyle(fontSize: 13)),
|
||||||
))
|
))
|
||||||
.toList(),
|
.toList(),
|
||||||
onChanged: (v) {
|
onChanged: (v) {
|
||||||
|
|
@ -196,7 +204,9 @@ class _CodeEditorState extends ConsumerState<CodeEditor> {
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (_serviceIndex == 0 || _serviceIndex == 1 || _serviceIndex == 2)
|
if (_serviceIndex == 0 ||
|
||||||
|
_serviceIndex == 1 ||
|
||||||
|
_serviceIndex == 2)
|
||||||
_textEditing("Page", context, "ex: 1", (v) {
|
_textEditing("Page", context, "ex: 1", (v) {
|
||||||
_page = int.tryParse(v) ?? 1;
|
_page = int.tryParse(v) ?? 1;
|
||||||
}),
|
}),
|
||||||
|
|
@ -204,8 +214,11 @@ class _CodeEditorState extends ConsumerState<CodeEditor> {
|
||||||
_textEditing("Query", context, "ex: one piece", (v) {
|
_textEditing("Query", context, "ex: one piece", (v) {
|
||||||
_query = v;
|
_query = v;
|
||||||
}),
|
}),
|
||||||
if (_serviceIndex == 3 || _serviceIndex == 4 || _serviceIndex == 5)
|
if (_serviceIndex == 3 ||
|
||||||
_textEditing("Url", context, "ex: url of the entry", (v) {
|
_serviceIndex == 4 ||
|
||||||
|
_serviceIndex == 5)
|
||||||
|
_textEditing("Url", context, "ex: url of the entry",
|
||||||
|
(v) {
|
||||||
_url = v;
|
_url = v;
|
||||||
}),
|
}),
|
||||||
Padding(
|
Padding(
|
||||||
|
|
@ -219,7 +232,8 @@ class _CodeEditorState extends ConsumerState<CodeEditor> {
|
||||||
source?.sourceCode = controller.text;
|
source?.sourceCode = controller.text;
|
||||||
});
|
});
|
||||||
if (source != null && mounted) {
|
if (source != null && mounted) {
|
||||||
isar.writeTxnSync(() => isar.sources.putSync(source!));
|
isar.writeTxnSync(
|
||||||
|
() => isar.sources.putSync(source!));
|
||||||
}
|
}
|
||||||
setState(() {
|
setState(() {
|
||||||
result = null;
|
result = null;
|
||||||
|
|
@ -228,36 +242,52 @@ class _CodeEditorState extends ConsumerState<CodeEditor> {
|
||||||
_errorText = "";
|
_errorText = "";
|
||||||
});
|
});
|
||||||
if (source != null) {
|
if (source != null) {
|
||||||
final service = getExtensionService(source!);
|
final service =
|
||||||
|
getExtensionService(source!);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (_serviceIndex == 0) {
|
if (_serviceIndex == 0) {
|
||||||
final getManga =
|
final getManga = await ref.watch(
|
||||||
await ref.watch(getPopularProvider(source: source!, page: _page).future);
|
getPopularProvider(
|
||||||
|
source: source!,
|
||||||
|
page: _page)
|
||||||
|
.future);
|
||||||
result = getManga!.toJson();
|
result = getManga!.toJson();
|
||||||
} else if (_serviceIndex == 1) {
|
} else if (_serviceIndex == 1) {
|
||||||
final getManga = await ref
|
final getManga = await ref.watch(
|
||||||
.watch(getLatestUpdatesProvider(source: source!, page: _page).future);
|
getLatestUpdatesProvider(
|
||||||
|
source: source!,
|
||||||
|
page: _page)
|
||||||
|
.future);
|
||||||
result = getManga!.toJson();
|
result = getManga!.toJson();
|
||||||
} else if (_serviceIndex == 2) {
|
} else if (_serviceIndex == 2) {
|
||||||
final getManga = await ref.watch(searchProvider(
|
final getManga = await ref.watch(
|
||||||
source: source!, query: _query, page: _page, filterList: filterList)
|
searchProvider(
|
||||||
.future);
|
source: source!,
|
||||||
|
query: _query,
|
||||||
|
page: _page,
|
||||||
|
filterList: filterList)
|
||||||
|
.future);
|
||||||
result = getManga!.toJson();
|
result = getManga!.toJson();
|
||||||
} else if (_serviceIndex == 3) {
|
} else if (_serviceIndex == 3) {
|
||||||
final getManga =
|
final getManga = await ref.watch(
|
||||||
await ref.watch(getDetailProvider(source: source!, url: _url).future);
|
getDetailProvider(
|
||||||
|
source: source!,
|
||||||
|
url: _url)
|
||||||
|
.future);
|
||||||
result = getManga.toJson();
|
result = getManga.toJson();
|
||||||
} else if (_serviceIndex == 4) {
|
} else if (_serviceIndex == 4) {
|
||||||
result = {
|
result = {
|
||||||
"pages": (await service.getPageList(_url))
|
"pages": (await service
|
||||||
|
.getPageList(_url))
|
||||||
.map((e) => e.toJson())
|
.map((e) => e.toJson())
|
||||||
.toList(),
|
.toList(),
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
result = (await service.getVideoList(_url))
|
result =
|
||||||
.map((e) => e.toJson())
|
(await service.getVideoList(_url))
|
||||||
.toList();
|
.map((e) => e.toJson())
|
||||||
|
.toList();
|
||||||
}
|
}
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
setState(() {
|
setState(() {
|
||||||
|
|
@ -298,7 +328,8 @@ class _CodeEditorState extends ConsumerState<CodeEditor> {
|
||||||
if (filters.isEmpty) {
|
if (filters.isEmpty) {
|
||||||
filters = filterList;
|
filters = filterList;
|
||||||
}
|
}
|
||||||
final res = await filterDialog(context);
|
final res =
|
||||||
|
await filterDialog(context);
|
||||||
if (res == 'filter' && mounted) {
|
if (res == 'filter' && mounted) {
|
||||||
setState(() {
|
setState(() {
|
||||||
result = null;
|
result = null;
|
||||||
|
|
@ -306,9 +337,13 @@ class _CodeEditorState extends ConsumerState<CodeEditor> {
|
||||||
_error = false;
|
_error = false;
|
||||||
_errorText = "";
|
_errorText = "";
|
||||||
});
|
});
|
||||||
final getManga = await ref.watch(searchProvider(
|
final getManga = await ref.watch(
|
||||||
source: source!, query: _query, page: _page, filterList: filters)
|
searchProvider(
|
||||||
.future);
|
source: source!,
|
||||||
|
query: _query,
|
||||||
|
page: _page,
|
||||||
|
filterList: filters)
|
||||||
|
.future);
|
||||||
result = getManga!.toJson();
|
result = getManga!.toJson();
|
||||||
setState(() {
|
setState(() {
|
||||||
_isLoading = false;
|
_isLoading = false;
|
||||||
|
|
@ -331,22 +366,26 @@ class _CodeEditorState extends ConsumerState<CodeEditor> {
|
||||||
child: _error
|
child: _error
|
||||||
? SingleChildScrollView(
|
? SingleChildScrollView(
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment:
|
||||||
|
MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Text(_errorText),
|
Text(_errorText),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
: _isLoading
|
: _isLoading
|
||||||
? const Center(child: CircularProgressIndicator())
|
? const Center(
|
||||||
|
child: CircularProgressIndicator())
|
||||||
: result != null
|
: result != null
|
||||||
? JsonConfig(
|
? JsonConfig(
|
||||||
data: JsonConfigData(
|
data: JsonConfigData(
|
||||||
gap: 100,
|
gap: 100,
|
||||||
style: const JsonStyleScheme(
|
style: const JsonStyleScheme(
|
||||||
quotation: JsonQuotation.same('"'),
|
quotation:
|
||||||
|
JsonQuotation.same('"'),
|
||||||
openAtStart: false,
|
openAtStart: false,
|
||||||
arrow: Icon(Icons.arrow_forward),
|
arrow:
|
||||||
|
Icon(Icons.arrow_forward),
|
||||||
depth: 4,
|
depth: 4,
|
||||||
),
|
),
|
||||||
color: const JsonColorScheme(),
|
color: const JsonColorScheme(),
|
||||||
|
|
@ -379,7 +418,10 @@ class _CodeEditorState extends ConsumerState<CodeEditor> {
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
final value = logs[index];
|
final value = logs[index];
|
||||||
return SelectableText(value.$2,
|
return SelectableText(value.$2,
|
||||||
style: TextStyle(color: value.$1 == LoggerLevel.info ? Colors.yellow : Colors.blueAccent));
|
style: TextStyle(
|
||||||
|
color: value.$1 == LoggerLevel.info
|
||||||
|
? Colors.yellow
|
||||||
|
: Colors.blueAccent));
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -390,7 +432,8 @@ class _CodeEditorState extends ConsumerState<CodeEditor> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _textEditing(String label, BuildContext context, String hintText, void Function(String)? onChanged) {
|
Widget _textEditing(String label, BuildContext context, String hintText,
|
||||||
|
void Function(String)? onChanged) {
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.all(4),
|
padding: const EdgeInsets.all(4),
|
||||||
child: TextFormField(
|
child: TextFormField(
|
||||||
|
|
@ -402,9 +445,12 @@ Widget _textEditing(String label, BuildContext context, String hintText, void Fu
|
||||||
isDense: true,
|
isDense: true,
|
||||||
filled: true,
|
filled: true,
|
||||||
fillColor: Colors.transparent,
|
fillColor: Colors.transparent,
|
||||||
enabledBorder: OutlineInputBorder(borderSide: BorderSide(color: context.dynamicThemeColor)),
|
enabledBorder: OutlineInputBorder(
|
||||||
focusedBorder: OutlineInputBorder(borderSide: BorderSide(color: context.dynamicThemeColor)),
|
borderSide: BorderSide(color: context.dynamicThemeColor)),
|
||||||
border: OutlineInputBorder(borderSide: BorderSide(color: context.dynamicThemeColor))),
|
focusedBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(color: context.dynamicThemeColor)),
|
||||||
|
border: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(color: context.dynamicThemeColor))),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,14 +26,17 @@ class ExtensionDetail extends ConsumerStatefulWidget {
|
||||||
class _ExtensionDetailState extends ConsumerState<ExtensionDetail> {
|
class _ExtensionDetailState extends ConsumerState<ExtensionDetail> {
|
||||||
late Source source = widget.source;
|
late Source source = widget.source;
|
||||||
late List<SourcePreference> sourcePreference =
|
late List<SourcePreference> sourcePreference =
|
||||||
getSourcePreference(source: source).map((e) => getSourcePreferenceEntry(e.key!, source.id!)).toList();
|
getSourcePreference(source: source)
|
||||||
|
.map((e) => getSourcePreferenceEntry(e.key!, source.id!))
|
||||||
|
.toList();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final l10n = l10nLocalizations(context)!;
|
final l10n = l10nLocalizations(context)!;
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text(l10n.extension_detail), leading: BackButton(onPressed: () => Navigator.pop(context, source))),
|
title: Text(l10n.extension_detail),
|
||||||
|
leading: BackButton(onPressed: () => Navigator.pop(context, source))),
|
||||||
body: SingleChildScrollView(
|
body: SingleChildScrollView(
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
|
|
@ -41,7 +44,9 @@ class _ExtensionDetailState extends ConsumerState<ExtensionDetail> {
|
||||||
padding: const EdgeInsets.only(top: 20),
|
padding: const EdgeInsets.only(top: 20),
|
||||||
child: Container(
|
child: Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Theme.of(context).secondaryHeaderColor.withValues(alpha: 0.5),
|
color: Theme.of(context)
|
||||||
|
.secondaryHeaderColor
|
||||||
|
.withValues(alpha: 0.5),
|
||||||
borderRadius: BorderRadius.circular(10)),
|
borderRadius: BorderRadius.circular(10)),
|
||||||
child: widget.source.iconUrl!.isEmpty
|
child: widget.source.iconUrl!.isEmpty
|
||||||
? const Icon(Icons.source_outlined, size: 140)
|
? const Icon(Icons.source_outlined, size: 140)
|
||||||
|
|
@ -65,7 +70,8 @@ class _ExtensionDetailState extends ConsumerState<ExtensionDetail> {
|
||||||
padding: const EdgeInsets.all(12),
|
padding: const EdgeInsets.all(12),
|
||||||
child: Text(
|
child: Text(
|
||||||
widget.source.name!,
|
widget.source.name!,
|
||||||
style: const TextStyle(fontSize: 23, fontWeight: FontWeight.bold),
|
style:
|
||||||
|
const TextStyle(fontSize: 23, fontWeight: FontWeight.bold),
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -73,7 +79,8 @@ class _ExtensionDetailState extends ConsumerState<ExtensionDetail> {
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8.0),
|
||||||
child: Container(
|
child: Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: context.primaryColor.withValues(alpha: 0.2), borderRadius: BorderRadius.circular(10)),
|
color: context.primaryColor.withValues(alpha: 0.2),
|
||||||
|
borderRadius: BorderRadius.circular(10)),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(20),
|
padding: const EdgeInsets.all(20),
|
||||||
child: Row(
|
child: Row(
|
||||||
|
|
@ -83,7 +90,8 @@ class _ExtensionDetailState extends ConsumerState<ExtensionDetail> {
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
widget.source.version!,
|
widget.source.version!,
|
||||||
style: const TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
|
style: const TextStyle(
|
||||||
|
fontSize: 16, fontWeight: FontWeight.bold),
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
l10n.version,
|
l10n.version,
|
||||||
|
|
@ -95,7 +103,8 @@ class _ExtensionDetailState extends ConsumerState<ExtensionDetail> {
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
completeLanguageName(widget.source.lang!),
|
completeLanguageName(widget.source.lang!),
|
||||||
style: const TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
|
style: const TextStyle(
|
||||||
|
fontSize: 16, fontWeight: FontWeight.bold),
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
l10n.language,
|
l10n.language,
|
||||||
|
|
@ -116,16 +125,19 @@ class _ExtensionDetailState extends ConsumerState<ExtensionDetail> {
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
padding: const EdgeInsets.all(0),
|
padding: const EdgeInsets.all(0),
|
||||||
backgroundColor: Colors.transparent,
|
backgroundColor: Colors.transparent,
|
||||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(5)),
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(5)),
|
||||||
elevation: 0,
|
elevation: 0,
|
||||||
shadowColor: Colors.transparent),
|
shadowColor: Colors.transparent),
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
final res = await context.push('/codeEditor', extra: source.id);
|
final res =
|
||||||
|
await context.push('/codeEditor', extra: source.id);
|
||||||
if (res != null && mounted) {
|
if (res != null && mounted) {
|
||||||
setState(() {
|
setState(() {
|
||||||
source = res as Source;
|
source = res as Source;
|
||||||
sourcePreference = getSourcePreference(source: source)
|
sourcePreference = getSourcePreference(source: source)
|
||||||
.map((e) => getSourcePreferenceEntry(e.key!, source.id!))
|
.map((e) =>
|
||||||
|
getSourcePreferenceEntry(e.key!, source.id!))
|
||||||
.toList();
|
.toList();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -137,7 +149,8 @@ class _ExtensionDetailState extends ConsumerState<ExtensionDetail> {
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 10),
|
padding: const EdgeInsets.symmetric(horizontal: 10),
|
||||||
child: Text(
|
child: Text(
|
||||||
l10n.edit_code,
|
l10n.edit_code,
|
||||||
style: const TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
|
style: const TextStyle(
|
||||||
|
fontSize: 20, fontWeight: FontWeight.bold),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const Icon(Icons.code)
|
const Icon(Icons.code)
|
||||||
|
|
@ -153,7 +166,8 @@ class _ExtensionDetailState extends ConsumerState<ExtensionDetail> {
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
padding: const EdgeInsets.all(0),
|
padding: const EdgeInsets.all(0),
|
||||||
backgroundColor: Colors.transparent,
|
backgroundColor: Colors.transparent,
|
||||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(5)),
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(5)),
|
||||||
elevation: 0,
|
elevation: 0,
|
||||||
shadowColor: Colors.transparent),
|
shadowColor: Colors.transparent),
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
|
|
@ -164,7 +178,8 @@ class _ExtensionDetailState extends ConsumerState<ExtensionDetail> {
|
||||||
padding: EdgeInsets.symmetric(horizontal: 10),
|
padding: EdgeInsets.symmetric(horizontal: 10),
|
||||||
child: Text(
|
child: Text(
|
||||||
"Delete all cookies",
|
"Delete all cookies",
|
||||||
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
|
style: TextStyle(
|
||||||
|
fontSize: 20, fontWeight: FontWeight.bold),
|
||||||
),
|
),
|
||||||
)),
|
)),
|
||||||
),
|
),
|
||||||
|
|
@ -176,9 +191,11 @@ class _ExtensionDetailState extends ConsumerState<ExtensionDetail> {
|
||||||
child: ElevatedButton(
|
child: ElevatedButton(
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
padding: const EdgeInsets.all(0),
|
padding: const EdgeInsets.all(0),
|
||||||
side: BorderSide(color: context.primaryColor, width: 0.3),
|
side:
|
||||||
|
BorderSide(color: context.primaryColor, width: 0.3),
|
||||||
backgroundColor: Colors.transparent,
|
backgroundColor: Colors.transparent,
|
||||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(5)),
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(5)),
|
||||||
elevation: 0,
|
elevation: 0,
|
||||||
shadowColor: Colors.transparent),
|
shadowColor: Colors.transparent),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
|
|
@ -189,7 +206,8 @@ class _ExtensionDetailState extends ConsumerState<ExtensionDetail> {
|
||||||
title: Text(
|
title: Text(
|
||||||
widget.source.name!,
|
widget.source.name!,
|
||||||
),
|
),
|
||||||
content: Text(l10n.uninstall_extension(widget.source.name!)),
|
content: Text(l10n
|
||||||
|
.uninstall_extension(widget.source.name!)),
|
||||||
actions: [
|
actions: [
|
||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.end,
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
|
|
@ -204,13 +222,15 @@ class _ExtensionDetailState extends ConsumerState<ExtensionDetail> {
|
||||||
),
|
),
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
final sourcePrefsIds = isar.sourcePreferences
|
final sourcePrefsIds = isar
|
||||||
|
.sourcePreferences
|
||||||
.filter()
|
.filter()
|
||||||
.sourceIdEqualTo(source.id!)
|
.sourceIdEqualTo(source.id!)
|
||||||
.findAllSync()
|
.findAllSync()
|
||||||
.map((e) => e.id!)
|
.map((e) => e.id!)
|
||||||
.toList();
|
.toList();
|
||||||
final sourcePrefsStringIds = isar.sourcePreferenceStringValues
|
final sourcePrefsStringIds = isar
|
||||||
|
.sourcePreferenceStringValues
|
||||||
.filter()
|
.filter()
|
||||||
.sourceIdEqualTo(source.id!)
|
.sourceIdEqualTo(source.id!)
|
||||||
.findAllSync()
|
.findAllSync()
|
||||||
|
|
@ -218,15 +238,19 @@ class _ExtensionDetailState extends ConsumerState<ExtensionDetail> {
|
||||||
.toList();
|
.toList();
|
||||||
isar.writeTxnSync(() {
|
isar.writeTxnSync(() {
|
||||||
if (source.isObsolete ?? false) {
|
if (source.isObsolete ?? false) {
|
||||||
isar.sources.deleteSync(widget.source.id!);
|
isar.sources.deleteSync(
|
||||||
|
widget.source.id!);
|
||||||
} else {
|
} else {
|
||||||
isar.sources.putSync(widget.source
|
isar.sources.putSync(widget.source
|
||||||
..sourceCode = ""
|
..sourceCode = ""
|
||||||
..isAdded = false
|
..isAdded = false
|
||||||
..isPinned = false);
|
..isPinned = false);
|
||||||
}
|
}
|
||||||
isar.sourcePreferences.deleteAllSync(sourcePrefsIds);
|
isar.sourcePreferences
|
||||||
isar.sourcePreferenceStringValues.deleteAllSync(sourcePrefsStringIds);
|
.deleteAllSync(sourcePrefsIds);
|
||||||
|
isar.sourcePreferenceStringValues
|
||||||
|
.deleteAllSync(
|
||||||
|
sourcePrefsStringIds);
|
||||||
});
|
});
|
||||||
|
|
||||||
Navigator.pop(ctx);
|
Navigator.pop(ctx);
|
||||||
|
|
@ -241,11 +265,13 @@ class _ExtensionDetailState extends ConsumerState<ExtensionDetail> {
|
||||||
},
|
},
|
||||||
child: Text(
|
child: Text(
|
||||||
l10n.uninstall,
|
l10n.uninstall,
|
||||||
style: const TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
|
style: const TextStyle(
|
||||||
|
fontSize: 20, fontWeight: FontWeight.bold),
|
||||||
)),
|
)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SourcePreferenceWidget(sourcePreference: sourcePreference, source: source)
|
SourcePreferenceWidget(
|
||||||
|
sourcePreference: sourcePreference, source: source)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,12 @@ class ExtensionsLang extends ConsumerWidget {
|
||||||
} else if (value == 1) {
|
} else if (value == 1) {
|
||||||
enable = false;
|
enable = false;
|
||||||
}
|
}
|
||||||
final sources = isar.sources.filter().idIsNotNull().and().isMangaEqualTo(isManga).findAllSync();
|
final sources = isar.sources
|
||||||
|
.filter()
|
||||||
|
.idIsNotNull()
|
||||||
|
.and()
|
||||||
|
.isMangaEqualTo(isManga)
|
||||||
|
.findAllSync();
|
||||||
for (var source in sources) {
|
for (var source in sources) {
|
||||||
isar.sources.putSync(source..isActive = enable);
|
isar.sources.putSync(source..isActive = enable);
|
||||||
}
|
}
|
||||||
|
|
@ -48,7 +53,12 @@ class ExtensionsLang extends ConsumerWidget {
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
body: StreamBuilder(
|
body: StreamBuilder(
|
||||||
stream: isar.sources.filter().idIsNotNull().and().isMangaEqualTo(isManga).watch(fireImmediately: true),
|
stream: isar.sources
|
||||||
|
.filter()
|
||||||
|
.idIsNotNull()
|
||||||
|
.and()
|
||||||
|
.isMangaEqualTo(isManga)
|
||||||
|
.watch(fireImmediately: true),
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
List<Source>? entries = snapshot.hasData ? snapshot.data : [];
|
List<Source>? entries = snapshot.hasData ? snapshot.data : [];
|
||||||
final languages = entries!.map((e) => e.lang!).toSet().toList();
|
final languages = entries!.map((e) => e.lang!).toSet().toList();
|
||||||
|
|
@ -70,7 +80,9 @@ class ExtensionsLang extends ConsumerWidget {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
value: entries
|
value: entries
|
||||||
.where((element) => element.lang!.toLowerCase() == lang.toLowerCase() && element.isActive!)
|
.where((element) =>
|
||||||
|
element.lang!.toLowerCase() == lang.toLowerCase() &&
|
||||||
|
element.isActive!)
|
||||||
.isNotEmpty,
|
.isNotEmpty,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,8 @@ import 'package:mangayomi/modules/browse/extension/widgets/extension_list_tile_w
|
||||||
class ExtensionScreen extends ConsumerStatefulWidget {
|
class ExtensionScreen extends ConsumerStatefulWidget {
|
||||||
final bool isManga;
|
final bool isManga;
|
||||||
final String query;
|
final String query;
|
||||||
const ExtensionScreen({required this.query, required this.isManga, super.key});
|
const ExtensionScreen(
|
||||||
|
{required this.query, required this.isManga, super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
ConsumerState<ExtensionScreen> createState() => _ExtensionScreenState();
|
ConsumerState<ExtensionScreen> createState() => _ExtensionScreenState();
|
||||||
|
|
@ -24,7 +25,8 @@ class _ExtensionScreenState extends ConsumerState<ExtensionScreen> {
|
||||||
final controller = ScrollController();
|
final controller = ScrollController();
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final streamExtensions = ref.watch(getExtensionsStreamProvider(widget.isManga));
|
final streamExtensions =
|
||||||
|
ref.watch(getExtensionsStreamProvider(widget.isManga));
|
||||||
if (widget.isManga) {
|
if (widget.isManga) {
|
||||||
ref.watch(fetchMangaSourcesListProvider(id: null, reFresh: false));
|
ref.watch(fetchMangaSourcesListProvider(id: null, reFresh: false));
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -33,15 +35,21 @@ class _ExtensionScreenState extends ConsumerState<ExtensionScreen> {
|
||||||
final l10n = l10nLocalizations(context)!;
|
final l10n = l10nLocalizations(context)!;
|
||||||
return RefreshIndicator(
|
return RefreshIndicator(
|
||||||
onRefresh: () => widget.isManga
|
onRefresh: () => widget.isManga
|
||||||
? ref.refresh(fetchMangaSourcesListProvider(id: null, reFresh: true).future)
|
? ref.refresh(
|
||||||
: ref.refresh(fetchAnimeSourcesListProvider(id: null, reFresh: true).future),
|
fetchMangaSourcesListProvider(id: null, reFresh: true).future)
|
||||||
|
: ref.refresh(
|
||||||
|
fetchAnimeSourcesListProvider(id: null, reFresh: true).future),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.only(top: 10),
|
padding: const EdgeInsets.only(top: 10),
|
||||||
child: streamExtensions.when(
|
child: streamExtensions.when(
|
||||||
data: (data) {
|
data: (data) {
|
||||||
data = widget.query.isEmpty
|
data = widget.query.isEmpty
|
||||||
? data
|
? data
|
||||||
: data.where((element) => element.name!.toLowerCase().contains(widget.query.toLowerCase())).toList();
|
: data
|
||||||
|
.where((element) => element.name!
|
||||||
|
.toLowerCase()
|
||||||
|
.contains(widget.query.toLowerCase()))
|
||||||
|
.toList();
|
||||||
|
|
||||||
final notInstalledEntries = data
|
final notInstalledEntries = data
|
||||||
.where((element) => element.version == element.versionLast!)
|
.where((element) => element.version == element.versionLast!)
|
||||||
|
|
@ -51,8 +59,10 @@ class _ExtensionScreenState extends ConsumerState<ExtensionScreen> {
|
||||||
.where((element) => element.version == element.versionLast!)
|
.where((element) => element.version == element.versionLast!)
|
||||||
.where((element) => element.isAdded!)
|
.where((element) => element.isAdded!)
|
||||||
.toList();
|
.toList();
|
||||||
final updateEntries =
|
final updateEntries = data
|
||||||
data.where((element) => compareVersions(element.version!, element.versionLast!) < 0).toList();
|
.where((element) =>
|
||||||
|
compareVersions(element.version!, element.versionLast!) < 0)
|
||||||
|
.toList();
|
||||||
return Scrollbar(
|
return Scrollbar(
|
||||||
interactive: true,
|
interactive: true,
|
||||||
controller: controller,
|
controller: controller,
|
||||||
|
|
@ -71,16 +81,21 @@ class _ExtensionScreenState extends ConsumerState<ExtensionScreen> {
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
l10n.update_pending,
|
l10n.update_pending,
|
||||||
style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 13),
|
style: const TextStyle(
|
||||||
|
fontWeight: FontWeight.bold, fontSize: 13),
|
||||||
),
|
),
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
for (var source in updateEntries) {
|
for (var source in updateEntries) {
|
||||||
source.isManga!
|
source.isManga!
|
||||||
? await ref
|
? await ref.watch(
|
||||||
.watch(fetchMangaSourcesListProvider(id: source.id, reFresh: true).future)
|
fetchMangaSourcesListProvider(
|
||||||
: await ref
|
id: source.id, reFresh: true)
|
||||||
.watch(fetchAnimeSourcesListProvider(id: source.id, reFresh: true).future);
|
.future)
|
||||||
|
: await ref.watch(
|
||||||
|
fetchAnimeSourcesListProvider(
|
||||||
|
id: source.id, reFresh: true)
|
||||||
|
.future);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: Text(l10n.update_all))
|
child: Text(l10n.update_all))
|
||||||
|
|
@ -92,8 +107,10 @@ class _ExtensionScreenState extends ConsumerState<ExtensionScreen> {
|
||||||
source: element,
|
source: element,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
groupComparator: (group1, group2) => group1.compareTo(group2),
|
groupComparator: (group1, group2) =>
|
||||||
itemComparator: (item1, item2) => item1.name!.compareTo(item2.name!),
|
group1.compareTo(group2),
|
||||||
|
itemComparator: (item1, item2) =>
|
||||||
|
item1.name!.compareTo(item2.name!),
|
||||||
order: GroupedListOrder.ASC,
|
order: GroupedListOrder.ASC,
|
||||||
),
|
),
|
||||||
SliverGroupedListView<Source, String>(
|
SliverGroupedListView<Source, String>(
|
||||||
|
|
@ -103,26 +120,31 @@ class _ExtensionScreenState extends ConsumerState<ExtensionScreen> {
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 12),
|
padding: const EdgeInsets.symmetric(horizontal: 12),
|
||||||
child: Text(
|
child: Text(
|
||||||
l10n.installed,
|
l10n.installed,
|
||||||
style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 13),
|
style: const TextStyle(
|
||||||
|
fontWeight: FontWeight.bold, fontSize: 13),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
itemBuilder: (context, Source element) {
|
itemBuilder: (context, Source element) {
|
||||||
return ExtensionListTileWidget(source: element);
|
return ExtensionListTileWidget(source: element);
|
||||||
},
|
},
|
||||||
groupComparator: (group1, group2) => group1.compareTo(group2),
|
groupComparator: (group1, group2) =>
|
||||||
itemComparator: (item1, item2) => item1.name!.compareTo(item2.name!),
|
group1.compareTo(group2),
|
||||||
|
itemComparator: (item1, item2) =>
|
||||||
|
item1.name!.compareTo(item2.name!),
|
||||||
order: GroupedListOrder.ASC,
|
order: GroupedListOrder.ASC,
|
||||||
),
|
),
|
||||||
SliverGroupedListView<Source, String>(
|
SliverGroupedListView<Source, String>(
|
||||||
elements: notInstalledEntries,
|
elements: notInstalledEntries,
|
||||||
groupBy: (element) => completeLanguageName(element.lang!.toLowerCase()),
|
groupBy: (element) =>
|
||||||
|
completeLanguageName(element.lang!.toLowerCase()),
|
||||||
groupSeparatorBuilder: (String groupByValue) => Padding(
|
groupSeparatorBuilder: (String groupByValue) => Padding(
|
||||||
padding: const EdgeInsets.only(left: 12),
|
padding: const EdgeInsets.only(left: 12),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
groupByValue,
|
groupByValue,
|
||||||
style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 13),
|
style: const TextStyle(
|
||||||
|
fontWeight: FontWeight.bold, fontSize: 13),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
@ -132,8 +154,10 @@ class _ExtensionScreenState extends ConsumerState<ExtensionScreen> {
|
||||||
source: element,
|
source: element,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
groupComparator: (group1, group2) => group1.compareTo(group2),
|
groupComparator: (group1, group2) =>
|
||||||
itemComparator: (item1, item2) => item1.name!.compareTo(item2.name!),
|
group1.compareTo(group2),
|
||||||
|
itemComparator: (item1, item2) =>
|
||||||
|
item1.name!.compareTo(item2.name!),
|
||||||
order: GroupedListOrder.ASC,
|
order: GroupedListOrder.ASC,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
@ -144,9 +168,11 @@ class _ExtensionScreenState extends ConsumerState<ExtensionScreen> {
|
||||||
child: ElevatedButton(
|
child: ElevatedButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
if (widget.isManga) {
|
if (widget.isManga) {
|
||||||
ref.invalidate(fetchMangaSourcesListProvider(id: null, reFresh: true));
|
ref.invalidate(
|
||||||
|
fetchMangaSourcesListProvider(id: null, reFresh: true));
|
||||||
} else {
|
} else {
|
||||||
ref.invalidate(fetchAnimeSourcesListProvider(id: null, reFresh: true));
|
ref.invalidate(
|
||||||
|
fetchAnimeSourcesListProvider(id: null, reFresh: true));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: Text(context.l10n.refresh)),
|
child: Text(context.l10n.refresh)),
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,11 @@ import 'package:mangayomi/models/source.dart';
|
||||||
import 'package:mangayomi/services/get_source_preference.dart';
|
import 'package:mangayomi/services/get_source_preference.dart';
|
||||||
|
|
||||||
void setPreferenceSetting(SourcePreference sourcePreference, Source source) {
|
void setPreferenceSetting(SourcePreference sourcePreference, Source source) {
|
||||||
final sourcePref =
|
final sourcePref = isar.sourcePreferences
|
||||||
isar.sourcePreferences.filter().sourceIdEqualTo(source.id).keyEqualTo(sourcePreference.key).findFirstSync();
|
.filter()
|
||||||
|
.sourceIdEqualTo(source.id)
|
||||||
|
.keyEqualTo(sourcePreference.key)
|
||||||
|
.findFirstSync();
|
||||||
isar.writeTxnSync(() {
|
isar.writeTxnSync(() {
|
||||||
if (sourcePref != null) {
|
if (sourcePref != null) {
|
||||||
isar.sourcePreferences.putSync(sourcePreference);
|
isar.sourcePreferences.putSync(sourcePreference);
|
||||||
|
|
@ -33,21 +36,30 @@ getPreferenceValue(int sourceId, String key) {
|
||||||
}
|
}
|
||||||
|
|
||||||
SourcePreference getSourcePreferenceEntry(String key, int sourceId) {
|
SourcePreference getSourcePreferenceEntry(String key, int sourceId) {
|
||||||
SourcePreference? sourcePreference =
|
SourcePreference? sourcePreference = isar.sourcePreferences
|
||||||
isar.sourcePreferences.filter().sourceIdEqualTo(sourceId).keyEqualTo(key).findFirstSync();
|
.filter()
|
||||||
|
.sourceIdEqualTo(sourceId)
|
||||||
|
.keyEqualTo(key)
|
||||||
|
.findFirstSync();
|
||||||
if (sourcePreference == null) {
|
if (sourcePreference == null) {
|
||||||
final source = isar.sources.getSync(sourceId)!;
|
final source = isar.sources.getSync(sourceId)!;
|
||||||
sourcePreference = getSourcePreference(source: source)
|
sourcePreference = getSourcePreference(source: source).firstWhere(
|
||||||
.firstWhere((element) => element.key == key, orElse: () => throw "Error when getting source preference");
|
(element) => element.key == key,
|
||||||
|
orElse: () => throw "Error when getting source preference");
|
||||||
setPreferenceSetting(sourcePreference, source);
|
setPreferenceSetting(sourcePreference, source);
|
||||||
}
|
}
|
||||||
|
|
||||||
return sourcePreference;
|
return sourcePreference;
|
||||||
}
|
}
|
||||||
|
|
||||||
String getSourcePreferenceStringValue(int sourceId, String key, String defaultValue) {
|
String getSourcePreferenceStringValue(
|
||||||
SourcePreferenceStringValue? sourcePreferenceStringValue =
|
int sourceId, String key, String defaultValue) {
|
||||||
isar.sourcePreferenceStringValues.filter().sourceIdEqualTo(sourceId).keyEqualTo(key).findFirstSync();
|
SourcePreferenceStringValue? sourcePreferenceStringValue = isar
|
||||||
|
.sourcePreferenceStringValues
|
||||||
|
.filter()
|
||||||
|
.sourceIdEqualTo(sourceId)
|
||||||
|
.keyEqualTo(key)
|
||||||
|
.findFirstSync();
|
||||||
if (sourcePreferenceStringValue == null) {
|
if (sourcePreferenceStringValue == null) {
|
||||||
setSourcePreferenceStringValue(sourceId, key, defaultValue);
|
setSourcePreferenceStringValue(sourceId, key, defaultValue);
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
|
|
@ -57,8 +69,11 @@ String getSourcePreferenceStringValue(int sourceId, String key, String defaultVa
|
||||||
}
|
}
|
||||||
|
|
||||||
void setSourcePreferenceStringValue(int sourceId, String key, String value) {
|
void setSourcePreferenceStringValue(int sourceId, String key, String value) {
|
||||||
final sourcePref =
|
final sourcePref = isar.sourcePreferenceStringValues
|
||||||
isar.sourcePreferenceStringValues.filter().sourceIdEqualTo(sourceId).keyEqualTo(key).findFirstSync();
|
.filter()
|
||||||
|
.sourceIdEqualTo(sourceId)
|
||||||
|
.keyEqualTo(key)
|
||||||
|
.findFirstSync();
|
||||||
isar.writeTxnSync(() {
|
isar.writeTxnSync(() {
|
||||||
if (sourcePref != null) {
|
if (sourcePref != null) {
|
||||||
isar.sourcePreferenceStringValues.putSync(sourcePref..value = value);
|
isar.sourcePreferenceStringValues.putSync(sourcePref..value = value);
|
||||||
|
|
|
||||||
|
|
@ -46,11 +46,13 @@ class _CreateExtensionState extends State<CreateExtension> {
|
||||||
icon: const Icon(Icons.keyboard_arrow_down),
|
icon: const Icon(Icons.keyboard_arrow_down),
|
||||||
isExpanded: true,
|
isExpanded: true,
|
||||||
value: _languageIndex,
|
value: _languageIndex,
|
||||||
hint: Text(_languages[_languageIndex], style: const TextStyle(fontSize: 13)),
|
hint: Text(_languages[_languageIndex],
|
||||||
|
style: const TextStyle(fontSize: 13)),
|
||||||
items: _languages
|
items: _languages
|
||||||
.map((e) => DropdownMenuItem(
|
.map((e) => DropdownMenuItem(
|
||||||
value: _languages.indexOf(e),
|
value: _languages.indexOf(e),
|
||||||
child: Text(e, style: const TextStyle(fontSize: 13)),
|
child: Text(e,
|
||||||
|
style: const TextStyle(fontSize: 13)),
|
||||||
))
|
))
|
||||||
.toList(),
|
.toList(),
|
||||||
onChanged: (v) {
|
onChanged: (v) {
|
||||||
|
|
@ -58,7 +60,8 @@ class _CreateExtensionState extends State<CreateExtension> {
|
||||||
if (v == 0) {
|
if (v == 0) {
|
||||||
_sourceCodeLanguage = SourceCodeLanguage.dart;
|
_sourceCodeLanguage = SourceCodeLanguage.dart;
|
||||||
} else {
|
} else {
|
||||||
_sourceCodeLanguage = SourceCodeLanguage.javascript;
|
_sourceCodeLanguage =
|
||||||
|
SourceCodeLanguage.javascript;
|
||||||
}
|
}
|
||||||
_languageIndex = v!;
|
_languageIndex = v!;
|
||||||
});
|
});
|
||||||
|
|
@ -78,12 +81,15 @@ class _CreateExtensionState extends State<CreateExtension> {
|
||||||
_lang = v;
|
_lang = v;
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
_textEditing("BaseUrl", context, "ex: https://example.com", (v) {
|
_textEditing("BaseUrl", context, "ex: https://example.com",
|
||||||
|
(v) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_baseUrl = v;
|
_baseUrl = v;
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
_textEditing("ApiUrl (optional)", context, "ex: https://api.example.com", (v) {
|
_textEditing(
|
||||||
|
"ApiUrl (optional)", context, "ex: https://api.example.com",
|
||||||
|
(v) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_apiUrl = v;
|
_apiUrl = v;
|
||||||
});
|
});
|
||||||
|
|
@ -104,11 +110,13 @@ class _CreateExtensionState extends State<CreateExtension> {
|
||||||
icon: const Icon(Icons.keyboard_arrow_down),
|
icon: const Icon(Icons.keyboard_arrow_down),
|
||||||
isExpanded: true,
|
isExpanded: true,
|
||||||
value: _sourceTypeIndex,
|
value: _sourceTypeIndex,
|
||||||
hint: Text(_sourceTypes[_sourceTypeIndex], style: const TextStyle(fontSize: 13)),
|
hint: Text(_sourceTypes[_sourceTypeIndex],
|
||||||
|
style: const TextStyle(fontSize: 13)),
|
||||||
items: _sourceTypes
|
items: _sourceTypes
|
||||||
.map((e) => DropdownMenuItem(
|
.map((e) => DropdownMenuItem(
|
||||||
value: _sourceTypes.indexOf(e),
|
value: _sourceTypes.indexOf(e),
|
||||||
child: Text(e, style: const TextStyle(fontSize: 13)),
|
child: Text(e,
|
||||||
|
style: const TextStyle(fontSize: 13)),
|
||||||
))
|
))
|
||||||
.toList(),
|
.toList(),
|
||||||
onChanged: (v) {
|
onChanged: (v) {
|
||||||
|
|
@ -132,11 +140,15 @@ class _CreateExtensionState extends State<CreateExtension> {
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8.0),
|
||||||
child: ElevatedButton(
|
child: ElevatedButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
if (_name.isNotEmpty && _lang.isNotEmpty && _baseUrl.isNotEmpty && _iconUrl.isNotEmpty) {
|
if (_name.isNotEmpty &&
|
||||||
|
_lang.isNotEmpty &&
|
||||||
|
_baseUrl.isNotEmpty &&
|
||||||
|
_iconUrl.isNotEmpty) {
|
||||||
try {
|
try {
|
||||||
final id = _sourceCodeLanguage == SourceCodeLanguage.dart
|
final id =
|
||||||
? 'mangayomi-$_lang.$_name'.hashCode
|
_sourceCodeLanguage == SourceCodeLanguage.dart
|
||||||
: 'mangayomi-js-$_lang.$_name'.hashCode;
|
? 'mangayomi-$_lang.$_name'.hashCode
|
||||||
|
: 'mangayomi-js-$_lang.$_name'.hashCode;
|
||||||
final checkIfExist = isar.sources.getSync(id);
|
final checkIfExist = isar.sources.getSync(id);
|
||||||
if (checkIfExist == null) {
|
if (checkIfExist == null) {
|
||||||
Source source = Source(
|
Source source = Source(
|
||||||
|
|
@ -155,9 +167,12 @@ class _CreateExtensionState extends State<CreateExtension> {
|
||||||
..sourceCodeLanguage = _sourceCodeLanguage;
|
..sourceCodeLanguage = _sourceCodeLanguage;
|
||||||
source = source
|
source = source
|
||||||
..isLocal = true
|
..isLocal = true
|
||||||
..sourceCode =
|
..sourceCode = _sourceCodeLanguage ==
|
||||||
_sourceCodeLanguage == SourceCodeLanguage.dart ? _dartTemplate : _jsSample(source);
|
SourceCodeLanguage.dart
|
||||||
isar.writeTxnSync(() => isar.sources.putSync(source));
|
? _dartTemplate
|
||||||
|
: _jsSample(source);
|
||||||
|
isar.writeTxnSync(
|
||||||
|
() => isar.sources.putSync(source));
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
botToast("Source created successfully");
|
botToast("Source created successfully");
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -177,7 +192,8 @@ class _CreateExtensionState extends State<CreateExtension> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _textEditing(String label, BuildContext context, String hintText, void Function(String)? onChanged) {
|
Widget _textEditing(String label, BuildContext context, String hintText,
|
||||||
|
void Function(String)? onChanged) {
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 17, vertical: 5),
|
padding: const EdgeInsets.symmetric(horizontal: 17, vertical: 5),
|
||||||
child: TextFormField(
|
child: TextFormField(
|
||||||
|
|
@ -189,9 +205,12 @@ Widget _textEditing(String label, BuildContext context, String hintText, void Fu
|
||||||
isDense: true,
|
isDense: true,
|
||||||
filled: true,
|
filled: true,
|
||||||
fillColor: Colors.transparent,
|
fillColor: Colors.transparent,
|
||||||
enabledBorder: OutlineInputBorder(borderSide: BorderSide(color: context.secondaryColor)),
|
enabledBorder: OutlineInputBorder(
|
||||||
focusedBorder: OutlineInputBorder(borderSide: BorderSide(color: context.secondaryColor)),
|
borderSide: BorderSide(color: context.secondaryColor)),
|
||||||
border: OutlineInputBorder(borderSide: BorderSide(color: context.secondaryColor))),
|
focusedBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(color: context.secondaryColor)),
|
||||||
|
border: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(color: context.secondaryColor))),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,11 @@ class ExtensionLangListTileWidget extends StatelessWidget {
|
||||||
final String lang;
|
final String lang;
|
||||||
final bool value;
|
final bool value;
|
||||||
final Function(bool) onChanged;
|
final Function(bool) onChanged;
|
||||||
const ExtensionLangListTileWidget({super.key, required this.lang, required this.value, required this.onChanged});
|
const ExtensionLangListTileWidget(
|
||||||
|
{super.key,
|
||||||
|
required this.lang,
|
||||||
|
required this.value,
|
||||||
|
required this.onChanged});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
|
|
||||||
|
|
@ -14,22 +14,28 @@ import 'package:mangayomi/utils/language.dart';
|
||||||
class ExtensionListTileWidget extends ConsumerStatefulWidget {
|
class ExtensionListTileWidget extends ConsumerStatefulWidget {
|
||||||
final Source source;
|
final Source source;
|
||||||
final bool isTestSource;
|
final bool isTestSource;
|
||||||
const ExtensionListTileWidget({super.key, required this.source, this.isTestSource = false});
|
const ExtensionListTileWidget(
|
||||||
|
{super.key, required this.source, this.isTestSource = false});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
ConsumerState<ExtensionListTileWidget> createState() => _ExtensionListTileWidgetState();
|
ConsumerState<ExtensionListTileWidget> createState() =>
|
||||||
|
_ExtensionListTileWidgetState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _ExtensionListTileWidgetState extends ConsumerState<ExtensionListTileWidget> {
|
class _ExtensionListTileWidgetState
|
||||||
|
extends ConsumerState<ExtensionListTileWidget> {
|
||||||
bool _isLoading = false;
|
bool _isLoading = false;
|
||||||
@override
|
@override
|
||||||
Widget build(
|
Widget build(
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
) {
|
) {
|
||||||
final l10n = l10nLocalizations(context)!;
|
final l10n = l10nLocalizations(context)!;
|
||||||
final updateAivalable =
|
final updateAivalable = widget.isTestSource
|
||||||
widget.isTestSource ? false : compareVersions(widget.source.version!, widget.source.versionLast!) < 0;
|
? false
|
||||||
final sourceNotEmpty = widget.source.sourceCode != null && widget.source.sourceCode!.isNotEmpty;
|
: compareVersions(widget.source.version!, widget.source.versionLast!) <
|
||||||
|
0;
|
||||||
|
final sourceNotEmpty = widget.source.sourceCode != null &&
|
||||||
|
widget.source.sourceCode!.isNotEmpty;
|
||||||
|
|
||||||
return ListTile(
|
return ListTile(
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
|
|
@ -43,8 +49,12 @@ class _ExtensionListTileWidgetState extends ConsumerState<ExtensionListTileWidge
|
||||||
_isLoading = true;
|
_isLoading = true;
|
||||||
});
|
});
|
||||||
widget.source.isManga!
|
widget.source.isManga!
|
||||||
? await ref.watch(fetchMangaSourcesListProvider(id: widget.source.id, reFresh: true).future)
|
? await ref.watch(fetchMangaSourcesListProvider(
|
||||||
: await ref.watch(fetchAnimeSourcesListProvider(id: widget.source.id, reFresh: true).future);
|
id: widget.source.id, reFresh: true)
|
||||||
|
.future)
|
||||||
|
: await ref.watch(fetchAnimeSourcesListProvider(
|
||||||
|
id: widget.source.id, reFresh: true)
|
||||||
|
.future);
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_isLoading = false;
|
_isLoading = false;
|
||||||
|
|
@ -56,7 +66,8 @@ class _ExtensionListTileWidgetState extends ConsumerState<ExtensionListTileWidge
|
||||||
height: 37,
|
height: 37,
|
||||||
width: 37,
|
width: 37,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Theme.of(context).secondaryHeaderColor.withValues(alpha: 0.5),
|
color:
|
||||||
|
Theme.of(context).secondaryHeaderColor.withValues(alpha: 0.5),
|
||||||
borderRadius: BorderRadius.circular(5)),
|
borderRadius: BorderRadius.circular(5)),
|
||||||
child: widget.source.iconUrl!.isEmpty
|
child: widget.source.iconUrl!.isEmpty
|
||||||
? const Icon(Icons.extension_rounded)
|
? const Icon(Icons.extension_rounded)
|
||||||
|
|
@ -79,14 +90,20 @@ class _ExtensionListTileWidgetState extends ConsumerState<ExtensionListTileWidge
|
||||||
crossAxisAlignment: CrossAxisAlignment.end,
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
children: [
|
children: [
|
||||||
Text(completeLanguageName(widget.source.lang!.toLowerCase()),
|
Text(completeLanguageName(widget.source.lang!.toLowerCase()),
|
||||||
style: const TextStyle(fontWeight: FontWeight.w300, fontSize: 12)),
|
style:
|
||||||
|
const TextStyle(fontWeight: FontWeight.w300, fontSize: 12)),
|
||||||
const SizedBox(width: 4),
|
const SizedBox(width: 4),
|
||||||
Text(widget.source.version!, style: const TextStyle(fontWeight: FontWeight.w300, fontSize: 12)),
|
Text(widget.source.version!,
|
||||||
|
style:
|
||||||
|
const TextStyle(fontWeight: FontWeight.w300, fontSize: 12)),
|
||||||
if (widget.source.isObsolete ?? false)
|
if (widget.source.isObsolete ?? false)
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 4),
|
padding: const EdgeInsets.symmetric(horizontal: 4),
|
||||||
child: Text("OBSOLETE",
|
child: Text("OBSOLETE",
|
||||||
style: TextStyle(color: context.primaryColor, fontWeight: FontWeight.bold, fontSize: 12)),
|
style: TextStyle(
|
||||||
|
color: context.primaryColor,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
fontSize: 12)),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
@ -100,8 +117,12 @@ class _ExtensionListTileWidgetState extends ConsumerState<ExtensionListTileWidge
|
||||||
_isLoading = true;
|
_isLoading = true;
|
||||||
});
|
});
|
||||||
widget.source.isManga!
|
widget.source.isManga!
|
||||||
? await ref.watch(fetchMangaSourcesListProvider(id: widget.source.id, reFresh: true).future)
|
? await ref.watch(fetchMangaSourcesListProvider(
|
||||||
: await ref.watch(fetchAnimeSourcesListProvider(id: widget.source.id, reFresh: true).future);
|
id: widget.source.id, reFresh: true)
|
||||||
|
.future)
|
||||||
|
: await ref.watch(fetchAnimeSourcesListProvider(
|
||||||
|
id: widget.source.id, reFresh: true)
|
||||||
|
.future);
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_isLoading = false;
|
_isLoading = false;
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,8 @@ import 'package:mangayomi/utils/extensions/build_context_extensions.dart';
|
||||||
class SourcePreferenceWidget extends StatefulWidget {
|
class SourcePreferenceWidget extends StatefulWidget {
|
||||||
final List<SourcePreference> sourcePreference;
|
final List<SourcePreference> sourcePreference;
|
||||||
final Source source;
|
final Source source;
|
||||||
const SourcePreferenceWidget({super.key, required this.sourcePreference, required this.source});
|
const SourcePreferenceWidget(
|
||||||
|
{super.key, required this.sourcePreference, required this.source});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<SourcePreferenceWidget> createState() => _SourcePreferenceWidgetState();
|
State<SourcePreferenceWidget> createState() => _SourcePreferenceWidgetState();
|
||||||
|
|
@ -29,7 +30,9 @@ class _SourcePreferenceWidgetState extends State<SourcePreferenceWidget> {
|
||||||
final pref = preference.editTextPreference!;
|
final pref = preference.editTextPreference!;
|
||||||
w = ListTile(
|
w = ListTile(
|
||||||
title: Text(pref.title!),
|
title: Text(pref.title!),
|
||||||
subtitle: Text(pref.summary!, style: TextStyle(fontSize: 11, color: context.secondaryColor)),
|
subtitle: Text(pref.summary!,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 11, color: context.secondaryColor)),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
showDialog(
|
showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
|
|
@ -49,7 +52,9 @@ class _SourcePreferenceWidgetState extends State<SourcePreferenceWidget> {
|
||||||
final pref = preference.checkBoxPreference!;
|
final pref = preference.checkBoxPreference!;
|
||||||
w = CheckboxListTile(
|
w = CheckboxListTile(
|
||||||
title: Text(pref.title!),
|
title: Text(pref.title!),
|
||||||
subtitle: Text(pref.summary!, style: TextStyle(fontSize: 11, color: context.secondaryColor)),
|
subtitle: Text(pref.summary!,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 11, color: context.secondaryColor)),
|
||||||
value: pref.value,
|
value: pref.value,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
setState(() {
|
setState(() {
|
||||||
|
|
@ -63,7 +68,9 @@ class _SourcePreferenceWidgetState extends State<SourcePreferenceWidget> {
|
||||||
final pref = preference.switchPreferenceCompat!;
|
final pref = preference.switchPreferenceCompat!;
|
||||||
w = SwitchListTile(
|
w = SwitchListTile(
|
||||||
title: Text(pref.title!),
|
title: Text(pref.title!),
|
||||||
subtitle: Text(pref.summary!, style: TextStyle(fontSize: 11, color: context.secondaryColor)),
|
subtitle: Text(pref.summary!,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 11, color: context.secondaryColor)),
|
||||||
value: pref.value!,
|
value: pref.value!,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
setState(() {
|
setState(() {
|
||||||
|
|
@ -78,7 +85,8 @@ class _SourcePreferenceWidgetState extends State<SourcePreferenceWidget> {
|
||||||
w = ListTile(
|
w = ListTile(
|
||||||
title: Text(pref.title!),
|
title: Text(pref.title!),
|
||||||
subtitle: Text(pref.entries![pref.valueIndex!],
|
subtitle: Text(pref.entries![pref.valueIndex!],
|
||||||
style: TextStyle(fontSize: 11, color: context.secondaryColor)),
|
style: TextStyle(
|
||||||
|
fontSize: 11, color: context.secondaryColor)),
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
final res = await showDialog(
|
final res = await showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
|
|
@ -114,7 +122,8 @@ class _SourcePreferenceWidgetState extends State<SourcePreferenceWidget> {
|
||||||
},
|
},
|
||||||
child: Text(
|
child: Text(
|
||||||
context.l10n.cancel,
|
context.l10n.cancel,
|
||||||
style: TextStyle(color: context.primaryColor),
|
style: TextStyle(
|
||||||
|
color: context.primaryColor),
|
||||||
)),
|
)),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
@ -132,7 +141,9 @@ class _SourcePreferenceWidgetState extends State<SourcePreferenceWidget> {
|
||||||
final pref = preference.multiSelectListPreference!;
|
final pref = preference.multiSelectListPreference!;
|
||||||
w = ListTile(
|
w = ListTile(
|
||||||
title: Text(pref.title!),
|
title: Text(pref.title!),
|
||||||
subtitle: Text(pref.summary!, style: TextStyle(fontSize: 11, color: context.secondaryColor)),
|
subtitle: Text(pref.summary!,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 11, color: context.secondaryColor)),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
List<String> indexList = [];
|
List<String> indexList = [];
|
||||||
indexList.addAll(pref.values!);
|
indexList.addAll(pref.values!);
|
||||||
|
|
@ -151,20 +162,27 @@ class _SourcePreferenceWidgetState extends State<SourcePreferenceWidget> {
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
return ListTileChapterFilter(
|
return ListTileChapterFilter(
|
||||||
label: pref.entries![index],
|
label: pref.entries![index],
|
||||||
type: indexList.contains(pref.entryValues![index]) ? 1 : 0,
|
type: indexList.contains(
|
||||||
|
pref.entryValues![index])
|
||||||
|
? 1
|
||||||
|
: 0,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
if (indexList.contains(pref.entryValues![index])) {
|
if (indexList.contains(
|
||||||
|
pref.entryValues![index])) {
|
||||||
setState(() {
|
setState(() {
|
||||||
indexList.remove(pref.entryValues![index]);
|
indexList.remove(pref
|
||||||
|
.entryValues![index]);
|
||||||
pref.values = indexList;
|
pref.values = indexList;
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
setState(() {
|
setState(() {
|
||||||
indexList.add(pref.entryValues![index]);
|
indexList.add(pref
|
||||||
|
.entryValues![index]);
|
||||||
pref.values = indexList;
|
pref.values = indexList;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
setPreferenceSetting(preference, widget.source);
|
setPreferenceSetting(
|
||||||
|
preference, widget.source);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
)),
|
)),
|
||||||
|
|
@ -178,7 +196,8 @@ class _SourcePreferenceWidgetState extends State<SourcePreferenceWidget> {
|
||||||
},
|
},
|
||||||
child: Text(
|
child: Text(
|
||||||
context.l10n.cancel,
|
context.l10n.cancel,
|
||||||
style: TextStyle(color: context.primaryColor),
|
style: TextStyle(
|
||||||
|
color: context.primaryColor),
|
||||||
)),
|
)),
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
|
|
@ -186,7 +205,8 @@ class _SourcePreferenceWidgetState extends State<SourcePreferenceWidget> {
|
||||||
},
|
},
|
||||||
child: Text(
|
child: Text(
|
||||||
context.l10n.ok,
|
context.l10n.ok,
|
||||||
style: TextStyle(color: context.primaryColor),
|
style: TextStyle(
|
||||||
|
color: context.primaryColor),
|
||||||
)),
|
)),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
@ -211,7 +231,11 @@ class EditTextDialogWidget extends StatefulWidget {
|
||||||
final String dialogMessage;
|
final String dialogMessage;
|
||||||
final Function(String) onChanged;
|
final Function(String) onChanged;
|
||||||
const EditTextDialogWidget(
|
const EditTextDialogWidget(
|
||||||
{super.key, required this.text, required this.onChanged, required this.dialogTitle, required this.dialogMessage});
|
{super.key,
|
||||||
|
required this.text,
|
||||||
|
required this.onChanged,
|
||||||
|
required this.dialogTitle,
|
||||||
|
required this.dialogMessage});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<EditTextDialogWidget> createState() => _EditTextDialogWidgetState();
|
State<EditTextDialogWidget> createState() => _EditTextDialogWidgetState();
|
||||||
|
|
@ -224,7 +248,10 @@ class _EditTextDialogWidgetState extends State<EditTextDialogWidget> {
|
||||||
return AlertDialog(
|
return AlertDialog(
|
||||||
title: Column(
|
title: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [Text(widget.dialogTitle), Text(widget.dialogMessage, style: const TextStyle(fontSize: 13))],
|
children: [
|
||||||
|
Text(widget.dialogTitle),
|
||||||
|
Text(widget.dialogMessage, style: const TextStyle(fontSize: 13))
|
||||||
|
],
|
||||||
),
|
),
|
||||||
content: Padding(
|
content: Padding(
|
||||||
padding: const EdgeInsets.only(top: 20),
|
padding: const EdgeInsets.only(top: 20),
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,12 @@ class _GlobalSearchScreenState extends ConsumerState<GlobalSearchScreen> {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
List<Source> sourceList = ref.watch(onlyIncludePinnedSourceStateProvider)
|
List<Source> sourceList = ref.watch(onlyIncludePinnedSourceStateProvider)
|
||||||
? isar.sources.filter().isPinnedEqualTo(true).and().isMangaEqualTo(widget.isManga).findAllSync()
|
? isar.sources
|
||||||
|
.filter()
|
||||||
|
.isPinnedEqualTo(true)
|
||||||
|
.and()
|
||||||
|
.isMangaEqualTo(widget.isManga)
|
||||||
|
.findAllSync()
|
||||||
: isar.sources
|
: isar.sources
|
||||||
.filter()
|
.filter()
|
||||||
.idIsNotNull()
|
.idIsNotNull()
|
||||||
|
|
@ -123,7 +128,8 @@ class _SourceSearchScreenState extends State<SourceSearchScreen> {
|
||||||
_init() async {
|
_init() async {
|
||||||
try {
|
try {
|
||||||
_errorMessage = "";
|
_errorMessage = "";
|
||||||
pages = await search(source: widget.source, page: 1, query: widget.query, filterList: []);
|
pages = await search(
|
||||||
|
source: widget.source, page: 1, query: widget.query, filterList: []);
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_isLoading = false;
|
_isLoading = false;
|
||||||
|
|
@ -214,7 +220,8 @@ class MangaGlobalImageCard extends ConsumerStatefulWidget {
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
ConsumerState<MangaGlobalImageCard> createState() => _MangaGlobalImageCardState();
|
ConsumerState<MangaGlobalImageCard> createState() =>
|
||||||
|
_MangaGlobalImageCardState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _MangaGlobalImageCardState extends ConsumerState<MangaGlobalImageCard>
|
class _MangaGlobalImageCardState extends ConsumerState<MangaGlobalImageCard>
|
||||||
|
|
@ -251,16 +258,20 @@ class _MangaGlobalImageCardState extends ConsumerState<MangaGlobalImageCard>
|
||||||
child: Column(children: [
|
child: Column(children: [
|
||||||
Builder(
|
Builder(
|
||||||
builder: (context) {
|
builder: (context) {
|
||||||
if (hasData && snapshot.data!.first.customCoverImage != null) {
|
if (hasData &&
|
||||||
return Image.memory(snapshot.data!.first.customCoverImage as Uint8List);
|
snapshot.data!.first.customCoverImage != null) {
|
||||||
|
return Image.memory(snapshot
|
||||||
|
.data!.first.customCoverImage as Uint8List);
|
||||||
}
|
}
|
||||||
return ClipRRect(
|
return ClipRRect(
|
||||||
borderRadius: BorderRadius.circular(5),
|
borderRadius: BorderRadius.circular(5),
|
||||||
child: cachedNetworkImage(
|
child: cachedNetworkImage(
|
||||||
headers: ref
|
headers: ref.watch(headersProvider(
|
||||||
.watch(headersProvider(source: widget.source.name!, lang: widget.source.lang!)),
|
source: widget.source.name!,
|
||||||
|
lang: widget.source.lang!)),
|
||||||
imageUrl: toImgUrl(hasData
|
imageUrl: toImgUrl(hasData
|
||||||
? snapshot.data!.first.customCoverFromTracker ??
|
? snapshot.data!.first
|
||||||
|
.customCoverFromTracker ??
|
||||||
snapshot.data!.first.imageUrl ??
|
snapshot.data!.first.imageUrl ??
|
||||||
""
|
""
|
||||||
: getMangaDetail.imageUrl ?? ""),
|
: getMangaDetail.imageUrl ?? ""),
|
||||||
|
|
@ -281,7 +292,9 @@ class _MangaGlobalImageCardState extends ConsumerState<MangaGlobalImageCard>
|
||||||
Container(
|
Container(
|
||||||
width: 110,
|
width: 110,
|
||||||
height: 150,
|
height: 150,
|
||||||
color: hasData && snapshot.data!.first.favorite! ? Colors.black.withValues(alpha: 0.7) : null,
|
color: hasData && snapshot.data!.first.favorite!
|
||||||
|
? Colors.black.withValues(alpha: 0.7)
|
||||||
|
: null,
|
||||||
),
|
),
|
||||||
if (hasData && snapshot.data!.first.favorite!)
|
if (hasData && snapshot.data!.first.favorite!)
|
||||||
Positioned(
|
Positioned(
|
||||||
|
|
@ -289,7 +302,8 @@ class _MangaGlobalImageCardState extends ConsumerState<MangaGlobalImageCard>
|
||||||
left: 0,
|
left: 0,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(4),
|
padding: const EdgeInsets.all(4),
|
||||||
child: Icon(Icons.collections_bookmark, color: context.primaryColor),
|
child: Icon(Icons.collections_bookmark,
|
||||||
|
color: context.primaryColor),
|
||||||
))
|
))
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,8 @@ class SourcesFilterScreen extends ConsumerWidget {
|
||||||
SliverGroupedListView<Source, String>(
|
SliverGroupedListView<Source, String>(
|
||||||
elements: entries,
|
elements: entries,
|
||||||
groupBy: (element) => element.lang!,
|
groupBy: (element) => element.lang!,
|
||||||
groupSeparatorBuilder: (String groupByValue) => SwitchListTile(
|
groupSeparatorBuilder: (String groupByValue) =>
|
||||||
|
SwitchListTile(
|
||||||
value: entries
|
value: entries
|
||||||
.where((element) =>
|
.where((element) =>
|
||||||
element.lang!.toLowerCase() == groupByValue &&
|
element.lang!.toLowerCase() == groupByValue &&
|
||||||
|
|
@ -49,19 +50,24 @@ class SourcesFilterScreen extends ConsumerWidget {
|
||||||
isar.writeTxnSync(() {
|
isar.writeTxnSync(() {
|
||||||
for (var source in entries) {
|
for (var source in entries) {
|
||||||
if (source.lang!.toLowerCase() == groupByValue) {
|
if (source.lang!.toLowerCase() == groupByValue) {
|
||||||
isar.sources.putSync(source..isActive = val == true);
|
isar.sources
|
||||||
|
.putSync(source..isActive = val == true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
title: Text(
|
title: Text(
|
||||||
completeLanguageName(groupByValue),
|
completeLanguageName(groupByValue),
|
||||||
style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 13),
|
style: const TextStyle(
|
||||||
|
fontWeight: FontWeight.bold, fontSize: 13),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
itemBuilder: (context, Source element) {
|
itemBuilder: (context, Source element) {
|
||||||
if (entries
|
if (entries
|
||||||
.where((s) => s.lang!.toLowerCase() == element.lang && s.isActive! && s.isManga == isManga)
|
.where((s) =>
|
||||||
|
s.lang!.toLowerCase() == element.lang &&
|
||||||
|
s.isActive! &&
|
||||||
|
s.isManga == isManga)
|
||||||
.isEmpty) {
|
.isEmpty) {
|
||||||
return Container();
|
return Container();
|
||||||
}
|
}
|
||||||
|
|
@ -70,7 +76,9 @@ class SourcesFilterScreen extends ConsumerWidget {
|
||||||
height: 37,
|
height: 37,
|
||||||
width: 37,
|
width: 37,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Theme.of(context).secondaryHeaderColor.withValues(alpha: 0.5),
|
color: Theme.of(context)
|
||||||
|
.secondaryHeaderColor
|
||||||
|
.withValues(alpha: 0.5),
|
||||||
borderRadius: BorderRadius.circular(5)),
|
borderRadius: BorderRadius.circular(5)),
|
||||||
child: element.iconUrl!.isEmpty
|
child: element.iconUrl!.isEmpty
|
||||||
? const Icon(Icons.source_outlined)
|
? const Icon(Icons.source_outlined)
|
||||||
|
|
@ -97,8 +105,10 @@ class SourcesFilterScreen extends ConsumerWidget {
|
||||||
title: Text(element.name!),
|
title: Text(element.name!),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
groupComparator: (group1, group2) => group1.compareTo(group2),
|
groupComparator: (group1, group2) =>
|
||||||
itemComparator: (item1, item2) => item1.name!.compareTo(item2.name!),
|
group1.compareTo(group2),
|
||||||
|
itemComparator: (item1, item2) =>
|
||||||
|
item1.name!.compareTo(item2.name!),
|
||||||
order: GroupedListOrder.ASC,
|
order: GroupedListOrder.ASC,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,8 @@ import 'package:mangayomi/utils/language.dart';
|
||||||
class SourcesScreen extends ConsumerStatefulWidget {
|
class SourcesScreen extends ConsumerStatefulWidget {
|
||||||
final Function(int) tabIndex;
|
final Function(int) tabIndex;
|
||||||
final bool isManga;
|
final bool isManga;
|
||||||
const SourcesScreen({required this.tabIndex, required this.isManga, super.key});
|
const SourcesScreen(
|
||||||
|
{required this.tabIndex, required this.isManga, super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
ConsumerState<SourcesScreen> createState() => _SourcesScreenState();
|
ConsumerState<SourcesScreen> createState() => _SourcesScreenState();
|
||||||
|
|
@ -50,16 +51,20 @@ class _SourcesScreenState extends ConsumerState<SourcesScreen> {
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8.0),
|
||||||
child: ElevatedButton.icon(
|
child: ElevatedButton.icon(
|
||||||
onPressed: () => widget.tabIndex(widget.isManga ? 2 : 3),
|
onPressed: () =>
|
||||||
|
widget.tabIndex(widget.isManga ? 2 : 3),
|
||||||
icon: const Icon(Icons.extension_rounded),
|
icon: const Icon(Icons.extension_rounded),
|
||||||
label: Text(context.l10n.show_extensions)),
|
label: Text(context.l10n.show_extensions)),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
final lastUsedEntries = sources.where((element) => element.lastUsed!).toList();
|
final lastUsedEntries =
|
||||||
final isPinnedEntries = sources.where((element) => element.isPinned!).toList();
|
sources.where((element) => element.lastUsed!).toList();
|
||||||
final allEntriesWithoutIspinned = sources.where((element) => !element.isPinned!).toList();
|
final isPinnedEntries =
|
||||||
|
sources.where((element) => element.isPinned!).toList();
|
||||||
|
final allEntriesWithoutIspinned =
|
||||||
|
sources.where((element) => !element.isPinned!).toList();
|
||||||
return Scrollbar(
|
return Scrollbar(
|
||||||
interactive: true,
|
interactive: true,
|
||||||
controller: controller,
|
controller: controller,
|
||||||
|
|
@ -77,7 +82,8 @@ class _SourcesScreenState extends ConsumerState<SourcesScreen> {
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
l10n.last_used,
|
l10n.last_used,
|
||||||
style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 13),
|
style: const TextStyle(
|
||||||
|
fontWeight: FontWeight.bold, fontSize: 13),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
@ -88,8 +94,10 @@ class _SourcesScreenState extends ConsumerState<SourcesScreen> {
|
||||||
isManga: widget.isManga,
|
isManga: widget.isManga,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
groupComparator: (group1, group2) => group1.compareTo(group2),
|
groupComparator: (group1, group2) =>
|
||||||
itemComparator: (item1, item2) => item1.name!.compareTo(item2.name!),
|
group1.compareTo(group2),
|
||||||
|
itemComparator: (item1, item2) =>
|
||||||
|
item1.name!.compareTo(item2.name!),
|
||||||
order: GroupedListOrder.ASC,
|
order: GroupedListOrder.ASC,
|
||||||
),
|
),
|
||||||
SliverGroupedListView<Source, String>(
|
SliverGroupedListView<Source, String>(
|
||||||
|
|
@ -101,7 +109,8 @@ class _SourcesScreenState extends ConsumerState<SourcesScreen> {
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
l10n.pinned,
|
l10n.pinned,
|
||||||
style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 13),
|
style: const TextStyle(
|
||||||
|
fontWeight: FontWeight.bold, fontSize: 13),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
@ -112,20 +121,24 @@ class _SourcesScreenState extends ConsumerState<SourcesScreen> {
|
||||||
isManga: widget.isManga,
|
isManga: widget.isManga,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
groupComparator: (group1, group2) => group1.compareTo(group2),
|
groupComparator: (group1, group2) =>
|
||||||
itemComparator: (item1, item2) => item1.name!.compareTo(item2.name!),
|
group1.compareTo(group2),
|
||||||
|
itemComparator: (item1, item2) =>
|
||||||
|
item1.name!.compareTo(item2.name!),
|
||||||
order: GroupedListOrder.ASC,
|
order: GroupedListOrder.ASC,
|
||||||
),
|
),
|
||||||
SliverGroupedListView<Source, String>(
|
SliverGroupedListView<Source, String>(
|
||||||
elements: allEntriesWithoutIspinned,
|
elements: allEntriesWithoutIspinned,
|
||||||
groupBy: (element) => completeLanguageName(element.lang!.toLowerCase()),
|
groupBy: (element) =>
|
||||||
|
completeLanguageName(element.lang!.toLowerCase()),
|
||||||
groupSeparatorBuilder: (String groupByValue) => Padding(
|
groupSeparatorBuilder: (String groupByValue) => Padding(
|
||||||
padding: const EdgeInsets.only(left: 12),
|
padding: const EdgeInsets.only(left: 12),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
groupByValue,
|
groupByValue,
|
||||||
style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 13),
|
style: const TextStyle(
|
||||||
|
fontWeight: FontWeight.bold, fontSize: 13),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
@ -136,8 +149,10 @@ class _SourcesScreenState extends ConsumerState<SourcesScreen> {
|
||||||
isManga: widget.isManga,
|
isManga: widget.isManga,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
groupComparator: (group1, group2) => group1.compareTo(group2),
|
groupComparator: (group1, group2) =>
|
||||||
itemComparator: (item1, item2) => item1.name!.compareTo(item2.name!),
|
group1.compareTo(group2),
|
||||||
|
itemComparator: (item1, item2) =>
|
||||||
|
item1.name!.compareTo(item2.name!),
|
||||||
order: GroupedListOrder.ASC,
|
order: GroupedListOrder.ASC,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -12,16 +12,23 @@ import 'package:mangayomi/utils/language.dart';
|
||||||
class SourceListTile extends StatelessWidget {
|
class SourceListTile extends StatelessWidget {
|
||||||
final bool isManga;
|
final bool isManga;
|
||||||
final Source source;
|
final Source source;
|
||||||
const SourceListTile({super.key, required this.source, required this.isManga});
|
const SourceListTile(
|
||||||
|
{super.key, required this.source, required this.isManga});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return ListTile(
|
return ListTile(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
final sources = isar.sources.filter().idIsNotNull().and().isMangaEqualTo(isManga).findAllSync();
|
final sources = isar.sources
|
||||||
|
.filter()
|
||||||
|
.idIsNotNull()
|
||||||
|
.and()
|
||||||
|
.isMangaEqualTo(isManga)
|
||||||
|
.findAllSync();
|
||||||
isar.writeTxnSync(() {
|
isar.writeTxnSync(() {
|
||||||
for (var src in sources) {
|
for (var src in sources) {
|
||||||
isar.sources.putSync(src..lastUsed = src.id == source.id ? true : false);
|
isar.sources
|
||||||
|
.putSync(src..lastUsed = src.id == source.id ? true : false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -31,7 +38,8 @@ class SourceListTile extends StatelessWidget {
|
||||||
height: 37,
|
height: 37,
|
||||||
width: 37,
|
width: 37,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Theme.of(context).secondaryHeaderColor.withValues(alpha: 0.5),
|
color:
|
||||||
|
Theme.of(context).secondaryHeaderColor.withValues(alpha: 0.5),
|
||||||
borderRadius: BorderRadius.circular(5)),
|
borderRadius: BorderRadius.circular(5)),
|
||||||
child: source.iconUrl!.isEmpty
|
child: source.iconUrl!.isEmpty
|
||||||
? const Icon(Icons.extension_rounded)
|
? const Icon(Icons.extension_rounded)
|
||||||
|
|
@ -68,8 +76,10 @@ class SourceListTile extends StatelessWidget {
|
||||||
// final supportsLatest = ref.watch(supportsLatestProvider(source: source));
|
// final supportsLatest = ref.watch(supportsLatestProvider(source: source));
|
||||||
// if (supportsLatest) {
|
// if (supportsLatest) {
|
||||||
return TextButton(
|
return TextButton(
|
||||||
style: const ButtonStyle(padding: WidgetStatePropertyAll(EdgeInsets.all(10))),
|
style: const ButtonStyle(
|
||||||
onPressed: () => context.push('/mangaHome', extra: (source, true)),
|
padding: WidgetStatePropertyAll(EdgeInsets.all(10))),
|
||||||
|
onPressed: () =>
|
||||||
|
context.push('/mangaHome', extra: (source, true)),
|
||||||
child: Text(context.l10n.latest));
|
child: Text(context.l10n.latest));
|
||||||
// }
|
// }
|
||||||
// return const SizedBox.shrink();
|
// return const SizedBox.shrink();
|
||||||
|
|
@ -79,7 +89,8 @@ class SourceListTile extends StatelessWidget {
|
||||||
IconButton(
|
IconButton(
|
||||||
padding: const EdgeInsets.all(0),
|
padding: const EdgeInsets.all(0),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
isar.writeTxnSync(() => isar.sources.putSync(source..isPinned = !source.isPinned!));
|
isar.writeTxnSync(() => isar.sources
|
||||||
|
.putSync(source..isPinned = !source.isPinned!));
|
||||||
},
|
},
|
||||||
icon: Icon(
|
icon: Icon(
|
||||||
Icons.push_pin_outlined,
|
Icons.push_pin_outlined,
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,8 @@ class HistoryScreen extends ConsumerStatefulWidget {
|
||||||
ConsumerState<HistoryScreen> createState() => _HistoryScreenState();
|
ConsumerState<HistoryScreen> createState() => _HistoryScreenState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _HistoryScreenState extends ConsumerState<HistoryScreen> with TickerProviderStateMixin {
|
class _HistoryScreenState extends ConsumerState<HistoryScreen>
|
||||||
|
with TickerProviderStateMixin {
|
||||||
late TabController _tabBarController;
|
late TabController _tabBarController;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
@ -88,7 +89,8 @@ class _HistoryScreenState extends ConsumerState<HistoryScreen> with TickerProvid
|
||||||
_isSearch = true;
|
_isSearch = true;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
icon: Icon(Icons.search, color: Theme.of(context).hintColor)),
|
icon:
|
||||||
|
Icon(Icons.search, color: Theme.of(context).hintColor)),
|
||||||
IconButton(
|
IconButton(
|
||||||
splashRadius: 20,
|
splashRadius: 20,
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
|
|
@ -117,8 +119,10 @@ class _HistoryScreenState extends ConsumerState<HistoryScreen> with TickerProvid
|
||||||
List<History> histories = isar.historys
|
List<History> histories = isar.historys
|
||||||
.filter()
|
.filter()
|
||||||
.idIsNotNull()
|
.idIsNotNull()
|
||||||
.chapter(
|
.chapter((q) => q.manga((q) =>
|
||||||
(q) => q.manga((q) => q.isMangaEqualTo(_tabBarController.index == 0)))
|
q.isMangaEqualTo(
|
||||||
|
_tabBarController.index ==
|
||||||
|
0)))
|
||||||
.findAllSync()
|
.findAllSync()
|
||||||
.toList();
|
.toList();
|
||||||
isar.writeTxnSync(() {
|
isar.writeTxnSync(() {
|
||||||
|
|
@ -137,7 +141,8 @@ class _HistoryScreenState extends ConsumerState<HistoryScreen> with TickerProvid
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
icon: Icon(Icons.delete_sweep_outlined, color: Theme.of(context).hintColor)),
|
icon: Icon(Icons.delete_sweep_outlined,
|
||||||
|
color: Theme.of(context).hintColor)),
|
||||||
],
|
],
|
||||||
bottom: TabBar(
|
bottom: TabBar(
|
||||||
indicatorSize: TabBarIndicatorSize.tab,
|
indicatorSize: TabBarIndicatorSize.tab,
|
||||||
|
|
@ -179,13 +184,16 @@ class _HistoryTabState extends ConsumerState<HistoryTab> {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final l10n = l10nLocalizations(context)!;
|
final l10n = l10nLocalizations(context)!;
|
||||||
final history = ref.watch(getAllHistoryStreamProvider(isManga: widget.isManga));
|
final history =
|
||||||
|
ref.watch(getAllHistoryStreamProvider(isManga: widget.isManga));
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
body: history.when(
|
body: history.when(
|
||||||
data: (data) {
|
data: (data) {
|
||||||
final entries = data
|
final entries = data
|
||||||
.where((element) => widget.query.isNotEmpty
|
.where((element) => widget.query.isNotEmpty
|
||||||
? element.chapter.value!.manga.value!.name!.toLowerCase().contains(widget.query.toLowerCase())
|
? element.chapter.value!.manga.value!.name!
|
||||||
|
.toLowerCase()
|
||||||
|
.contains(widget.query.toLowerCase())
|
||||||
: true)
|
: true)
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
|
|
@ -195,7 +203,10 @@ class _HistoryTabState extends ConsumerState<HistoryTab> {
|
||||||
SliverGroupedListView<History, String>(
|
SliverGroupedListView<History, String>(
|
||||||
elements: entries,
|
elements: entries,
|
||||||
groupBy: (element) => dateFormat(element.date!,
|
groupBy: (element) => dateFormat(element.date!,
|
||||||
context: context, ref: ref, forHistoryValue: true, useRelativeTimesTamps: false),
|
context: context,
|
||||||
|
ref: ref,
|
||||||
|
forHistoryValue: true,
|
||||||
|
useRelativeTimesTamps: false),
|
||||||
groupSeparatorBuilder: (String groupByValue) => Padding(
|
groupSeparatorBuilder: (String groupByValue) => Padding(
|
||||||
padding: const EdgeInsets.only(bottom: 8, left: 12),
|
padding: const EdgeInsets.only(bottom: 8, left: 12),
|
||||||
child: Row(
|
child: Row(
|
||||||
|
|
@ -216,7 +227,8 @@ class _HistoryTabState extends ConsumerState<HistoryTab> {
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
padding: const EdgeInsets.all(0),
|
padding: const EdgeInsets.all(0),
|
||||||
backgroundColor: Colors.transparent,
|
backgroundColor: Colors.transparent,
|
||||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(0)),
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(0)),
|
||||||
elevation: 0,
|
elevation: 0,
|
||||||
shadowColor: Colors.transparent),
|
shadowColor: Colors.transparent),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
|
|
@ -235,18 +247,26 @@ class _HistoryTabState extends ConsumerState<HistoryTab> {
|
||||||
child: ElevatedButton(
|
child: ElevatedButton(
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
padding: const EdgeInsets.all(0),
|
padding: const EdgeInsets.all(0),
|
||||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(7)),
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(7)),
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
context.push('/manga-reader/detail', extra: manga.id);
|
context.push('/manga-reader/detail',
|
||||||
|
extra: manga.id);
|
||||||
},
|
},
|
||||||
child: ClipRRect(
|
child: ClipRRect(
|
||||||
borderRadius: BorderRadius.circular(7),
|
borderRadius: BorderRadius.circular(7),
|
||||||
child: manga.customCoverImage != null
|
child: manga.customCoverImage != null
|
||||||
? Image.memory(manga.customCoverImage as Uint8List)
|
? Image.memory(
|
||||||
|
manga.customCoverImage as Uint8List)
|
||||||
: cachedNetworkImage(
|
: cachedNetworkImage(
|
||||||
headers: ref.watch(headersProvider(source: manga.source!, lang: manga.lang!)),
|
headers: ref.watch(headersProvider(
|
||||||
imageUrl: toImgUrl(manga.customCoverFromTracker ?? manga.imageUrl ?? ""),
|
source: manga.source!,
|
||||||
|
lang: manga.lang!)),
|
||||||
|
imageUrl: toImgUrl(
|
||||||
|
manga.customCoverFromTracker ??
|
||||||
|
manga.imageUrl ??
|
||||||
|
""),
|
||||||
width: 60,
|
width: 60,
|
||||||
height: 90,
|
height: 90,
|
||||||
fit: BoxFit.cover),
|
fit: BoxFit.cover),
|
||||||
|
|
@ -262,33 +282,46 @@ class _HistoryTabState extends ConsumerState<HistoryTab> {
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8.0),
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment:
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
MainAxisAlignment.center,
|
||||||
|
crossAxisAlignment:
|
||||||
|
CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
manga.name!,
|
manga.name!,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
color: Theme.of(context).textTheme.bodyLarge!.color,
|
color: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.bodyLarge!
|
||||||
|
.color,
|
||||||
fontWeight: FontWeight.bold),
|
fontWeight: FontWeight.bold),
|
||||||
textAlign: TextAlign.start,
|
textAlign: TextAlign.start,
|
||||||
),
|
),
|
||||||
Wrap(
|
Wrap(
|
||||||
crossAxisAlignment: WrapCrossAlignment.end,
|
crossAxisAlignment:
|
||||||
|
WrapCrossAlignment.end,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
chapter.name!,
|
chapter.name!,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 11,
|
fontSize: 11,
|
||||||
color: Theme.of(context).textTheme.bodyLarge!.color,
|
color: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.bodyLarge!
|
||||||
|
.color,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
" - ${dateFormatHour(element.date!, context)}",
|
" - ${dateFormatHour(element.date!, context)}",
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 11,
|
fontSize: 11,
|
||||||
color: Theme.of(context).textTheme.bodyLarge!.color,
|
color: Theme.of(context)
|
||||||
fontWeight: FontWeight.w400),
|
.textTheme
|
||||||
|
.bodyLarge!
|
||||||
|
.color,
|
||||||
|
fontWeight:
|
||||||
|
FontWeight.w400),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
@ -306,43 +339,73 @@ class _HistoryTabState extends ConsumerState<HistoryTab> {
|
||||||
title: Text(
|
title: Text(
|
||||||
l10n.remove,
|
l10n.remove,
|
||||||
),
|
),
|
||||||
content: Text(l10n.remove_history_msg),
|
content: Text(
|
||||||
|
l10n.remove_history_msg),
|
||||||
actions: [
|
actions: [
|
||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.end,
|
mainAxisAlignment:
|
||||||
|
MainAxisAlignment.end,
|
||||||
children: [
|
children: [
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.pop(context);
|
Navigator.pop(
|
||||||
|
context);
|
||||||
},
|
},
|
||||||
child: Text(l10n.cancel)),
|
child: Text(
|
||||||
|
l10n.cancel)),
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
width: 15,
|
width: 15,
|
||||||
),
|
),
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
await manga.chapters.load();
|
await manga.chapters
|
||||||
final chapters = manga.chapters;
|
.load();
|
||||||
await isar.writeTxn(() async {
|
final chapters =
|
||||||
await isar.historys.delete(element.id!);
|
manga.chapters;
|
||||||
for (var chapter in chapters) {
|
await isar.writeTxn(
|
||||||
|
() async {
|
||||||
|
await isar
|
||||||
|
.historys
|
||||||
|
.delete(
|
||||||
|
element
|
||||||
|
.id!);
|
||||||
|
for (var chapter
|
||||||
|
in chapters) {
|
||||||
await ref
|
await ref
|
||||||
.read(changedItemsManagerProvider(managerId: 1)
|
.read(changedItemsManagerProvider(
|
||||||
|
managerId:
|
||||||
|
1)
|
||||||
.notifier)
|
.notifier)
|
||||||
.addUpdatedChapterAsync(chapter, true, false);
|
.addUpdatedChapterAsync(
|
||||||
await isar.chapters.delete(chapter.id!);
|
chapter,
|
||||||
|
true,
|
||||||
|
false);
|
||||||
|
await isar
|
||||||
|
.chapters
|
||||||
|
.delete(
|
||||||
|
chapter
|
||||||
|
.id!);
|
||||||
}
|
}
|
||||||
await ref
|
await ref
|
||||||
.read(changedItemsManagerProvider(managerId: 1)
|
.read(changedItemsManagerProvider(
|
||||||
|
managerId:
|
||||||
|
1)
|
||||||
.notifier)
|
.notifier)
|
||||||
.addDeletedMangaAsync(manga, false);
|
.addDeletedMangaAsync(
|
||||||
await isar.mangas.delete(manga.id!);
|
manga,
|
||||||
|
false);
|
||||||
|
await isar.mangas
|
||||||
|
.delete(manga
|
||||||
|
.id!);
|
||||||
});
|
});
|
||||||
if (context.mounted) {
|
if (context
|
||||||
Navigator.pop(context);
|
.mounted) {
|
||||||
|
Navigator.pop(
|
||||||
|
context);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: Text(l10n.remove)),
|
child: Text(
|
||||||
|
l10n.remove)),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
|
|
@ -352,7 +415,10 @@ class _HistoryTabState extends ConsumerState<HistoryTab> {
|
||||||
icon: Icon(
|
icon: Icon(
|
||||||
Icons.delete_outline,
|
Icons.delete_outline,
|
||||||
size: 25,
|
size: 25,
|
||||||
color: Theme.of(context).textTheme.bodyLarge!.color,
|
color: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.bodyLarge!
|
||||||
|
.color,
|
||||||
)),
|
)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
@ -363,7 +429,8 @@ class _HistoryTabState extends ConsumerState<HistoryTab> {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
itemComparator: (item1, item2) => item1.date!.compareTo(item2.date!),
|
itemComparator: (item1, item2) =>
|
||||||
|
item1.date!.compareTo(item2.date!),
|
||||||
order: GroupedListOrder.DESC,
|
order: GroupedListOrder.DESC,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,8 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
part 'isar_providers.g.dart';
|
part 'isar_providers.g.dart';
|
||||||
|
|
||||||
@riverpod
|
@riverpod
|
||||||
Stream<List<History>> getAllHistoryStream(Ref ref, {required bool isManga}) async* {
|
Stream<List<History>> getAllHistoryStream(Ref ref,
|
||||||
|
{required bool isManga}) async* {
|
||||||
yield* isar.historys
|
yield* isar.historys
|
||||||
.filter()
|
.filter()
|
||||||
.idIsNotNull()
|
.idIsNotNull()
|
||||||
|
|
@ -19,7 +20,8 @@ Stream<List<History>> getAllHistoryStream(Ref ref, {required bool isManga}) asyn
|
||||||
}
|
}
|
||||||
|
|
||||||
@riverpod
|
@riverpod
|
||||||
Stream<List<Update>> getAllUpdateStream(Ref ref, {required bool isManga}) async* {
|
Stream<List<Update>> getAllUpdateStream(Ref ref,
|
||||||
|
{required bool isManga}) async* {
|
||||||
yield* isar.updates
|
yield* isar.updates
|
||||||
.filter()
|
.filter()
|
||||||
.idIsNotNull()
|
.idIsNotNull()
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:isar/isar.dart';
|
import 'package:isar/isar.dart';
|
||||||
import 'package:mangayomi/eval/dart/model/m_bridge.dart';
|
import 'package:mangayomi/eval/model/m_bridge.dart';
|
||||||
import 'package:mangayomi/main.dart';
|
import 'package:mangayomi/main.dart';
|
||||||
import 'package:mangayomi/models/category.dart';
|
import 'package:mangayomi/models/category.dart';
|
||||||
import 'package:mangayomi/models/chapter.dart';
|
import 'package:mangayomi/models/chapter.dart';
|
||||||
|
|
@ -1115,7 +1115,9 @@ class _LibraryScreenState extends ConsumerState<LibraryScreen>
|
||||||
type: fromLibList.isNotEmpty ? 1 : 0,
|
type: fromLibList.isNotEmpty ? 1 : 0,
|
||||||
),
|
),
|
||||||
ListTileChapterFilter(
|
ListTileChapterFilter(
|
||||||
label: widget.isManga ? l10n.downloaded_chapters : l10n.downloaded_episodes,
|
label: widget.isManga
|
||||||
|
? l10n.downloaded_chapters
|
||||||
|
: l10n.downloaded_episodes,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
setState(() {
|
setState(() {
|
||||||
if (downloadedChapsList == mangaIdsList) {
|
if (downloadedChapsList == mangaIdsList) {
|
||||||
|
|
@ -1516,7 +1518,9 @@ class _LibraryScreenState extends ConsumerState<LibraryScreen>
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
ListTileChapterFilter(
|
ListTileChapterFilter(
|
||||||
label: widget.isManga ? l10n.downloaded_chapters : l10n.downloaded_episodes,
|
label: widget.isManga
|
||||||
|
? l10n.downloaded_chapters
|
||||||
|
: l10n.downloaded_episodes,
|
||||||
type: downloadedChapter ? 1 : 0,
|
type: downloadedChapter ? 1 : 0,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
ref
|
ref
|
||||||
|
|
@ -1549,7 +1553,9 @@ class _LibraryScreenState extends ConsumerState<LibraryScreen>
|
||||||
.set(!localSource);
|
.set(!localSource);
|
||||||
}),
|
}),
|
||||||
ListTileChapterFilter(
|
ListTileChapterFilter(
|
||||||
label: widget.isManga ? l10n.show_continue_reading_buttons : l10n.show_continue_watching_buttons,
|
label: widget.isManga
|
||||||
|
? l10n.show_continue_reading_buttons
|
||||||
|
: l10n.show_continue_watching_buttons,
|
||||||
type: continueReaderBtn ? 1 : 0,
|
type: continueReaderBtn ? 1 : 0,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
ref
|
ref
|
||||||
|
|
@ -1648,7 +1654,8 @@ class _LibraryScreenState extends ConsumerState<LibraryScreen>
|
||||||
color: Theme.of(context).scaffoldBackgroundColor,
|
color: Theme.of(context).scaffoldBackgroundColor,
|
||||||
child: AppBar(
|
child: AppBar(
|
||||||
title: Text(mangaIdsList.length.toString()),
|
title: Text(mangaIdsList.length.toString()),
|
||||||
backgroundColor: context.primaryColor.withValues(alpha: 0.2),
|
backgroundColor:
|
||||||
|
context.primaryColor.withValues(alpha: 0.2),
|
||||||
leading: IconButton(
|
leading: IconButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
ref.read(mangasListStateProvider.notifier).clear();
|
ref.read(mangasListStateProvider.notifier).clear();
|
||||||
|
|
|
||||||
|
|
@ -8,17 +8,23 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
part 'add_torrent.g.dart';
|
part 'add_torrent.g.dart';
|
||||||
|
|
||||||
@riverpod
|
@riverpod
|
||||||
Future addTorrentFromUrlOrFromFile(Ref ref, Manga? mManga, {required bool init, String? url}) async {
|
Future addTorrentFromUrlOrFromFile(Ref ref, Manga? mManga,
|
||||||
|
{required bool init, String? url}) async {
|
||||||
FilePickerResult? result;
|
FilePickerResult? result;
|
||||||
if (url == null) {
|
if (url == null) {
|
||||||
result =
|
result = await FilePicker.platform.pickFiles(
|
||||||
await FilePicker.platform.pickFiles(allowMultiple: true, type: FileType.custom, allowedExtensions: ['torrent']);
|
allowMultiple: true,
|
||||||
|
type: FileType.custom,
|
||||||
|
allowedExtensions: ['torrent']);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result != null || url != null) {
|
if (result != null || url != null) {
|
||||||
String torrentName = "";
|
String torrentName = "";
|
||||||
if (url != null) {
|
if (url != null) {
|
||||||
torrentName = (await MTorrentServer().getTorrentPlaylist(url, null)).$1.first.quality;
|
torrentName = (await MTorrentServer().getTorrentPlaylist(url, null))
|
||||||
|
.$1
|
||||||
|
.first
|
||||||
|
.quality;
|
||||||
}
|
}
|
||||||
final dateNow = DateTime.now().millisecondsSinceEpoch;
|
final dateNow = DateTime.now().millisecondsSinceEpoch;
|
||||||
final manga = mManga ??
|
final manga = mManga ??
|
||||||
|
|
@ -43,7 +49,8 @@ Future addTorrentFromUrlOrFromFile(Ref ref, Manga? mManga, {required bool init,
|
||||||
manga.customCoverImage = null;
|
manga.customCoverImage = null;
|
||||||
isar.writeTxnSync(() {
|
isar.writeTxnSync(() {
|
||||||
isar.mangas.putSync(manga);
|
isar.mangas.putSync(manga);
|
||||||
final chapters = Chapter(name: torrentName, url: url, mangaId: manga.id)..manga.value = manga;
|
final chapters = Chapter(name: torrentName, url: url, mangaId: manga.id)
|
||||||
|
..manga.value = manga;
|
||||||
isar.chapters.putSync(chapters);
|
isar.chapters.putSync(chapters);
|
||||||
chapters.manga.saveSync();
|
chapters.manga.saveSync();
|
||||||
});
|
});
|
||||||
|
|
@ -57,7 +64,9 @@ Future addTorrentFromUrlOrFromFile(Ref ref, Manga? mManga, {required bool init,
|
||||||
|
|
||||||
isar.writeTxnSync(() {
|
isar.writeTxnSync(() {
|
||||||
isar.mangas.putSync(manga);
|
isar.mangas.putSync(manga);
|
||||||
final chapters = Chapter(name: name, archivePath: file.path, mangaId: manga.id)..manga.value = manga;
|
final chapters =
|
||||||
|
Chapter(name: name, archivePath: file.path, mangaId: manga.id)
|
||||||
|
..manga.value = manga;
|
||||||
isar.chapters.putSync(chapters);
|
isar.chapters.putSync(chapters);
|
||||||
chapters.manga.saveSync();
|
chapters.manga.saveSync();
|
||||||
});
|
});
|
||||||
|
|
@ -68,10 +77,6 @@ Future addTorrentFromUrlOrFromFile(Ref ref, Manga? mManga, {required bool init,
|
||||||
}
|
}
|
||||||
|
|
||||||
String _getName(String path) {
|
String _getName(String path) {
|
||||||
return path
|
return path.split('/').last.split("\\").last.replaceAll(
|
||||||
.split('/')
|
RegExp(r'\.(mp4|mov|avi|flv|wmv|mpeg|mkv|cbz|zip|cbt|tar|torrent)'), '');
|
||||||
.last
|
|
||||||
.split("\\")
|
|
||||||
.last
|
|
||||||
.replaceAll(RegExp(r'\.(mp4|mov|avi|flv|wmv|mpeg|mkv|cbz|zip|cbt|tar|torrent)'), '');
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,8 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
part 'isar_providers.g.dart';
|
part 'isar_providers.g.dart';
|
||||||
|
|
||||||
@riverpod
|
@riverpod
|
||||||
Stream<List<Manga>> getAllMangaStream(Ref ref, {required int? categoryId, required bool? isManga}) async* {
|
Stream<List<Manga>> getAllMangaStream(Ref ref,
|
||||||
|
{required int? categoryId, required bool? isManga}) async* {
|
||||||
yield* categoryId == null
|
yield* categoryId == null
|
||||||
? isar.mangas
|
? isar.mangas
|
||||||
.filter()
|
.filter()
|
||||||
|
|
@ -28,7 +29,8 @@ Stream<List<Manga>> getAllMangaStream(Ref ref, {required int? categoryId, requir
|
||||||
}
|
}
|
||||||
|
|
||||||
@riverpod
|
@riverpod
|
||||||
Stream<List<Manga>> getAllMangaWithoutCategoriesStream(Ref ref, {required bool? isManga}) async* {
|
Stream<List<Manga>> getAllMangaWithoutCategoriesStream(Ref ref,
|
||||||
|
{required bool? isManga}) async* {
|
||||||
yield* isar.mangas
|
yield* isar.mangas
|
||||||
.filter()
|
.filter()
|
||||||
.idIsNotNull()
|
.idIsNotNull()
|
||||||
|
|
@ -47,5 +49,10 @@ Stream<List<Manga>> getAllMangaWithoutCategoriesStream(Ref ref, {required bool?
|
||||||
|
|
||||||
@riverpod
|
@riverpod
|
||||||
Stream<List<Settings>> getSettingsStream(Ref ref) async* {
|
Stream<List<Settings>> getSettingsStream(Ref ref) async* {
|
||||||
yield* isar.settings.filter().idIsNotNull().and().idEqualTo(227).watch(fireImmediately: true);
|
yield* isar.settings
|
||||||
|
.filter()
|
||||||
|
.idIsNotNull()
|
||||||
|
.and()
|
||||||
|
.idEqualTo(227)
|
||||||
|
.watch(fireImmediately: true);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,8 @@ class LibraryDisplayTypeState extends _$LibraryDisplayTypeState {
|
||||||
return isManga ? settings.displayType : settings.animeDisplayType;
|
return isManga ? settings.displayType : settings.animeDisplayType;
|
||||||
}
|
}
|
||||||
|
|
||||||
String getLibraryDisplayTypeName(DisplayType displayType, BuildContext context) {
|
String getLibraryDisplayTypeName(
|
||||||
|
DisplayType displayType, BuildContext context) {
|
||||||
final l10n = context.l10n;
|
final l10n = context.l10n;
|
||||||
return switch (displayType) {
|
return switch (displayType) {
|
||||||
DisplayType.compactGrid => l10n.compact_grid,
|
DisplayType.compactGrid => l10n.compact_grid,
|
||||||
|
|
@ -74,13 +75,18 @@ class LibraryGridSizeState extends _$LibraryGridSizeState {
|
||||||
@riverpod
|
@riverpod
|
||||||
class MangaFilterDownloadedState extends _$MangaFilterDownloadedState {
|
class MangaFilterDownloadedState extends _$MangaFilterDownloadedState {
|
||||||
@override
|
@override
|
||||||
int build({required List<Manga> mangaList, required bool isManga, required Settings settings}) {
|
int build(
|
||||||
|
{required List<Manga> mangaList,
|
||||||
|
required bool isManga,
|
||||||
|
required Settings settings}) {
|
||||||
state = getType();
|
state = getType();
|
||||||
return getType();
|
return getType();
|
||||||
}
|
}
|
||||||
|
|
||||||
int getType() {
|
int getType() {
|
||||||
return isManga ? settings.libraryFilterMangasDownloadType! : settings.libraryFilterAnimeDownloadType ?? 0;
|
return isManga
|
||||||
|
? settings.libraryFilterMangasDownloadType!
|
||||||
|
: settings.libraryFilterAnimeDownloadType ?? 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setType(int type) {
|
void setType(int type) {
|
||||||
|
|
@ -110,13 +116,18 @@ class MangaFilterDownloadedState extends _$MangaFilterDownloadedState {
|
||||||
@riverpod
|
@riverpod
|
||||||
class MangaFilterUnreadState extends _$MangaFilterUnreadState {
|
class MangaFilterUnreadState extends _$MangaFilterUnreadState {
|
||||||
@override
|
@override
|
||||||
int build({required List<Manga> mangaList, required bool isManga, required Settings settings}) {
|
int build(
|
||||||
|
{required List<Manga> mangaList,
|
||||||
|
required bool isManga,
|
||||||
|
required Settings settings}) {
|
||||||
state = getType();
|
state = getType();
|
||||||
return getType();
|
return getType();
|
||||||
}
|
}
|
||||||
|
|
||||||
int getType() {
|
int getType() {
|
||||||
return isManga ? settings.libraryFilterMangasUnreadType! : settings.libraryFilterAnimeUnreadType ?? 0;
|
return isManga
|
||||||
|
? settings.libraryFilterMangasUnreadType!
|
||||||
|
: settings.libraryFilterAnimeUnreadType ?? 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setType(int type) {
|
void setType(int type) {
|
||||||
|
|
@ -195,13 +206,18 @@ class MangaFilterUnreadState extends _$MangaFilterUnreadState {
|
||||||
@riverpod
|
@riverpod
|
||||||
class MangaFilterStartedState extends _$MangaFilterStartedState {
|
class MangaFilterStartedState extends _$MangaFilterStartedState {
|
||||||
@override
|
@override
|
||||||
int build({required List<Manga> mangaList, required bool isManga, required Settings settings}) {
|
int build(
|
||||||
|
{required List<Manga> mangaList,
|
||||||
|
required bool isManga,
|
||||||
|
required Settings settings}) {
|
||||||
state = getType();
|
state = getType();
|
||||||
return getType();
|
return getType();
|
||||||
}
|
}
|
||||||
|
|
||||||
int getType() {
|
int getType() {
|
||||||
return isManga ? settings.libraryFilterMangasStartedType! : settings.libraryFilterAnimeStartedType ?? 0;
|
return isManga
|
||||||
|
? settings.libraryFilterMangasStartedType!
|
||||||
|
: settings.libraryFilterAnimeStartedType ?? 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setType(int type) {
|
void setType(int type) {
|
||||||
|
|
@ -280,13 +296,18 @@ class MangaFilterStartedState extends _$MangaFilterStartedState {
|
||||||
@riverpod
|
@riverpod
|
||||||
class MangaFilterBookmarkedState extends _$MangaFilterBookmarkedState {
|
class MangaFilterBookmarkedState extends _$MangaFilterBookmarkedState {
|
||||||
@override
|
@override
|
||||||
int build({required List<Manga> mangaList, required bool isManga, required Settings settings}) {
|
int build(
|
||||||
|
{required List<Manga> mangaList,
|
||||||
|
required bool isManga,
|
||||||
|
required Settings settings}) {
|
||||||
state = getType();
|
state = getType();
|
||||||
return getType();
|
return getType();
|
||||||
}
|
}
|
||||||
|
|
||||||
int getType() {
|
int getType() {
|
||||||
return isManga ? settings.libraryFilterMangasBookMarkedType! : settings.libraryFilterAnimeBookMarkedType ?? 0;
|
return isManga
|
||||||
|
? settings.libraryFilterMangasBookMarkedType!
|
||||||
|
: settings.libraryFilterAnimeBookMarkedType ?? 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setType(int type) {
|
void setType(int type) {
|
||||||
|
|
@ -365,16 +386,22 @@ class MangaFilterBookmarkedState extends _$MangaFilterBookmarkedState {
|
||||||
@riverpod
|
@riverpod
|
||||||
class MangasFilterResultState extends _$MangasFilterResultState {
|
class MangasFilterResultState extends _$MangasFilterResultState {
|
||||||
@override
|
@override
|
||||||
bool build({required List<Manga> mangaList, required bool isManga, required Settings settings}) {
|
bool build(
|
||||||
final downloadFilterType =
|
{required List<Manga> mangaList,
|
||||||
ref.watch(mangaFilterDownloadedStateProvider(mangaList: mangaList, isManga: isManga, settings: settings));
|
required bool isManga,
|
||||||
final unreadFilterType =
|
required Settings settings}) {
|
||||||
ref.watch(mangaFilterUnreadStateProvider(mangaList: mangaList, isManga: isManga, settings: settings));
|
final downloadFilterType = ref.watch(mangaFilterDownloadedStateProvider(
|
||||||
final startedFilterType =
|
mangaList: mangaList, isManga: isManga, settings: settings));
|
||||||
ref.watch(mangaFilterStartedStateProvider(mangaList: mangaList, isManga: isManga, settings: settings));
|
final unreadFilterType = ref.watch(mangaFilterUnreadStateProvider(
|
||||||
final bookmarkedFilterType =
|
mangaList: mangaList, isManga: isManga, settings: settings));
|
||||||
ref.watch(mangaFilterBookmarkedStateProvider(mangaList: mangaList, isManga: isManga, settings: settings));
|
final startedFilterType = ref.watch(mangaFilterStartedStateProvider(
|
||||||
return downloadFilterType == 0 && unreadFilterType == 0 && startedFilterType == 0 && bookmarkedFilterType == 0;
|
mangaList: mangaList, isManga: isManga, settings: settings));
|
||||||
|
final bookmarkedFilterType = ref.watch(mangaFilterBookmarkedStateProvider(
|
||||||
|
mangaList: mangaList, isManga: isManga, settings: settings));
|
||||||
|
return downloadFilterType == 0 &&
|
||||||
|
unreadFilterType == 0 &&
|
||||||
|
startedFilterType == 0 &&
|
||||||
|
bookmarkedFilterType == 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -382,7 +409,9 @@ class MangasFilterResultState extends _$MangasFilterResultState {
|
||||||
class LibraryShowCategoryTabsState extends _$LibraryShowCategoryTabsState {
|
class LibraryShowCategoryTabsState extends _$LibraryShowCategoryTabsState {
|
||||||
@override
|
@override
|
||||||
bool build({required bool isManga, required Settings settings}) {
|
bool build({required bool isManga, required Settings settings}) {
|
||||||
return isManga ? settings.libraryShowCategoryTabs! : settings.animeLibraryShowCategoryTabs ?? false;
|
return isManga
|
||||||
|
? settings.libraryShowCategoryTabs!
|
||||||
|
: settings.animeLibraryShowCategoryTabs ?? false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set(bool value) {
|
void set(bool value) {
|
||||||
|
|
@ -403,7 +432,9 @@ class LibraryShowCategoryTabsState extends _$LibraryShowCategoryTabsState {
|
||||||
class LibraryDownloadedChaptersState extends _$LibraryDownloadedChaptersState {
|
class LibraryDownloadedChaptersState extends _$LibraryDownloadedChaptersState {
|
||||||
@override
|
@override
|
||||||
bool build({required bool isManga, required Settings settings}) {
|
bool build({required bool isManga, required Settings settings}) {
|
||||||
return isManga ? settings.libraryDownloadedChapters! : settings.animeLibraryDownloadedChapters ?? false;
|
return isManga
|
||||||
|
? settings.libraryDownloadedChapters!
|
||||||
|
: settings.animeLibraryDownloadedChapters ?? false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set(bool value) {
|
void set(bool value) {
|
||||||
|
|
@ -424,7 +455,9 @@ class LibraryDownloadedChaptersState extends _$LibraryDownloadedChaptersState {
|
||||||
class LibraryLanguageState extends _$LibraryLanguageState {
|
class LibraryLanguageState extends _$LibraryLanguageState {
|
||||||
@override
|
@override
|
||||||
bool build({required bool isManga, required Settings settings}) {
|
bool build({required bool isManga, required Settings settings}) {
|
||||||
return isManga ? settings.libraryShowLanguage! : settings.animeLibraryShowLanguage ?? false;
|
return isManga
|
||||||
|
? settings.libraryShowLanguage!
|
||||||
|
: settings.animeLibraryShowLanguage ?? false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set(bool value) {
|
void set(bool value) {
|
||||||
|
|
@ -445,7 +478,9 @@ class LibraryLanguageState extends _$LibraryLanguageState {
|
||||||
class LibraryLocalSourceState extends _$LibraryLocalSourceState {
|
class LibraryLocalSourceState extends _$LibraryLocalSourceState {
|
||||||
@override
|
@override
|
||||||
bool build({required bool isManga, required Settings settings}) {
|
bool build({required bool isManga, required Settings settings}) {
|
||||||
return isManga ? settings.libraryLocalSource ?? false : settings.animeLibraryLocalSource ?? false;
|
return isManga
|
||||||
|
? settings.libraryLocalSource ?? false
|
||||||
|
: settings.animeLibraryLocalSource ?? false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set(bool value) {
|
void set(bool value) {
|
||||||
|
|
@ -466,7 +501,9 @@ class LibraryLocalSourceState extends _$LibraryLocalSourceState {
|
||||||
class LibraryShowNumbersOfItemsState extends _$LibraryShowNumbersOfItemsState {
|
class LibraryShowNumbersOfItemsState extends _$LibraryShowNumbersOfItemsState {
|
||||||
@override
|
@override
|
||||||
bool build({required bool isManga, required Settings settings}) {
|
bool build({required bool isManga, required Settings settings}) {
|
||||||
return isManga ? settings.libraryShowNumbersOfItems! : settings.animeLibraryShowNumbersOfItems ?? false;
|
return isManga
|
||||||
|
? settings.libraryShowNumbersOfItems!
|
||||||
|
: settings.animeLibraryShowNumbersOfItems ?? false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set(bool value) {
|
void set(bool value) {
|
||||||
|
|
@ -484,7 +521,8 @@ class LibraryShowNumbersOfItemsState extends _$LibraryShowNumbersOfItemsState {
|
||||||
}
|
}
|
||||||
|
|
||||||
@riverpod
|
@riverpod
|
||||||
class LibraryShowContinueReadingButtonState extends _$LibraryShowContinueReadingButtonState {
|
class LibraryShowContinueReadingButtonState
|
||||||
|
extends _$LibraryShowContinueReadingButtonState {
|
||||||
@override
|
@override
|
||||||
bool build({required bool isManga, required Settings settings}) {
|
bool build({required bool isManga, required Settings settings}) {
|
||||||
return isManga
|
return isManga
|
||||||
|
|
@ -510,7 +548,9 @@ class LibraryShowContinueReadingButtonState extends _$LibraryShowContinueReading
|
||||||
class SortLibraryMangaState extends _$SortLibraryMangaState {
|
class SortLibraryMangaState extends _$SortLibraryMangaState {
|
||||||
@override
|
@override
|
||||||
SortLibraryManga build({required bool isManga, required Settings settings}) {
|
SortLibraryManga build({required bool isManga, required Settings settings}) {
|
||||||
return isManga ? settings.sortLibraryManga ?? SortLibraryManga() : settings.sortLibraryAnime ?? SortLibraryManga();
|
return isManga
|
||||||
|
? settings.sortLibraryManga ?? SortLibraryManga()
|
||||||
|
: settings.sortLibraryAnime ?? SortLibraryManga();
|
||||||
}
|
}
|
||||||
|
|
||||||
void update(bool reverse, int index) {
|
void update(bool reverse, int index) {
|
||||||
|
|
@ -611,7 +651,9 @@ class MangasSetIsReadState extends _$MangasSetIsReadState {
|
||||||
for (var chapter in chapters) {
|
for (var chapter in chapters) {
|
||||||
chapter.isRead = true;
|
chapter.isRead = true;
|
||||||
chapter.lastPageRead = "1";
|
chapter.lastPageRead = "1";
|
||||||
ref.read(changedItemsManagerProvider(managerId: 1).notifier).addUpdatedChapter(chapter, false, false);
|
ref
|
||||||
|
.read(changedItemsManagerProvider(managerId: 1).notifier)
|
||||||
|
.addUpdatedChapter(chapter, false, false);
|
||||||
isar.chapters.putSync(chapter..manga.value = manga);
|
isar.chapters.putSync(chapter..manga.value = manga);
|
||||||
chapter.manga.saveSync();
|
chapter.manga.saveSync();
|
||||||
}
|
}
|
||||||
|
|
@ -636,7 +678,9 @@ class MangasSetUnReadState extends _$MangasSetUnReadState {
|
||||||
isar.writeTxnSync(() {
|
isar.writeTxnSync(() {
|
||||||
for (var chapter in chapters) {
|
for (var chapter in chapters) {
|
||||||
chapter.isRead = false;
|
chapter.isRead = false;
|
||||||
ref.read(changedItemsManagerProvider(managerId: 1).notifier).addUpdatedChapter(chapter, false, false);
|
ref
|
||||||
|
.read(changedItemsManagerProvider(managerId: 1).notifier)
|
||||||
|
.addUpdatedChapter(chapter, false, false);
|
||||||
isar.chapters.putSync(chapter..manga.value = manga);
|
isar.chapters.putSync(chapter..manga.value = manga);
|
||||||
chapter.manga.saveSync();
|
chapter.manga.saveSync();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,11 +10,14 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
part 'local_archive.g.dart';
|
part 'local_archive.g.dart';
|
||||||
|
|
||||||
@riverpod
|
@riverpod
|
||||||
Future importArchivesFromFile(Ref ref, Manga? mManga, {required bool isManga, required bool init}) async {
|
Future importArchivesFromFile(Ref ref, Manga? mManga,
|
||||||
|
{required bool isManga, required bool init}) async {
|
||||||
FilePickerResult? result = await FilePicker.platform.pickFiles(
|
FilePickerResult? result = await FilePicker.platform.pickFiles(
|
||||||
allowMultiple: true,
|
allowMultiple: true,
|
||||||
type: FileType.custom,
|
type: FileType.custom,
|
||||||
allowedExtensions: isManga ? ['cbz', 'zip'] : ['mp4', 'mov', 'avi', 'flv', 'wmv', 'mpeg', 'mkv']);
|
allowedExtensions: isManga
|
||||||
|
? ['cbz', 'zip']
|
||||||
|
: ['mp4', 'mov', 'avi', 'flv', 'wmv', 'mpeg', 'mkv']);
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
final dateNow = DateTime.now().millisecondsSinceEpoch;
|
final dateNow = DateTime.now().millisecondsSinceEpoch;
|
||||||
final manga = mManga ??
|
final manga = mManga ??
|
||||||
|
|
@ -36,8 +39,9 @@ Future importArchivesFromFile(Ref ref, Manga? mManga, {required bool isManga, re
|
||||||
artist: '',
|
artist: '',
|
||||||
);
|
);
|
||||||
for (var file in result.files.reversed.toList()) {
|
for (var file in result.files.reversed.toList()) {
|
||||||
(String, LocalExtensionType, Uint8List, String)? data =
|
(String, LocalExtensionType, Uint8List, String)? data = isManga
|
||||||
isManga ? await ref.watch(getArchivesDataFromFileProvider(file.path!).future) : null;
|
? await ref.watch(getArchivesDataFromFileProvider(file.path!).future)
|
||||||
|
: null;
|
||||||
String name = _getName(file.path!);
|
String name = _getName(file.path!);
|
||||||
|
|
||||||
if (init) {
|
if (init) {
|
||||||
|
|
@ -46,9 +50,11 @@ Future importArchivesFromFile(Ref ref, Manga? mManga, {required bool isManga, re
|
||||||
|
|
||||||
isar.writeTxnSync(() {
|
isar.writeTxnSync(() {
|
||||||
isar.mangas.putSync(manga);
|
isar.mangas.putSync(manga);
|
||||||
final chapters =
|
final chapters = Chapter(
|
||||||
Chapter(name: isManga ? data!.$1 : name, archivePath: isManga ? data!.$4 : file.path, mangaId: manga.id)
|
name: isManga ? data!.$1 : name,
|
||||||
..manga.value = manga;
|
archivePath: isManga ? data!.$4 : file.path,
|
||||||
|
mangaId: manga.id)
|
||||||
|
..manga.value = manga;
|
||||||
isar.chapters.putSync(chapters);
|
isar.chapters.putSync(chapters);
|
||||||
chapters.manga.saveSync();
|
chapters.manga.saveSync();
|
||||||
});
|
});
|
||||||
|
|
@ -58,10 +64,6 @@ Future importArchivesFromFile(Ref ref, Manga? mManga, {required bool isManga, re
|
||||||
}
|
}
|
||||||
|
|
||||||
String _getName(String path) {
|
String _getName(String path) {
|
||||||
return path
|
return path.split('/').last.split("\\").last.replaceAll(
|
||||||
.split('/')
|
RegExp(r'\.(mp4|mov|avi|flv|wmv|mpeg|mkv|cbz|zip|cbt|tar)'), '');
|
||||||
.last
|
|
||||||
.split("\\")
|
|
||||||
.last
|
|
||||||
.replaceAll(RegExp(r'\.(mp4|mov|avi|flv|wmv|mpeg|mkv|cbz|zip|cbt|tar)'), '');
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,8 @@ class _LibraryGridViewWidgetState extends State<LibraryGridViewWidget> {
|
||||||
final isLongPressed = ref.watch(isLongPressedMangaStateProvider);
|
final isLongPressed = ref.watch(isLongPressedMangaStateProvider);
|
||||||
final isManga = widget.isManga;
|
final isManga = widget.isManga;
|
||||||
|
|
||||||
final gridSize = ref.watch(libraryGridSizeStateProvider(isManga: isManga));
|
final gridSize =
|
||||||
|
ref.watch(libraryGridSizeStateProvider(isManga: isManga));
|
||||||
return GridViewWidget(
|
return GridViewWidget(
|
||||||
gridSize: gridSize,
|
gridSize: gridSize,
|
||||||
childAspectRatio: widget.isComfortableGrid ? 0.642 : 0.69,
|
childAspectRatio: widget.isComfortableGrid ? 0.642 : 0.69,
|
||||||
|
|
@ -74,12 +75,16 @@ class _LibraryGridViewWidgetState extends State<LibraryGridViewWidget> {
|
||||||
),
|
),
|
||||||
isComfortableGrid: widget.isComfortableGrid,
|
isComfortableGrid: widget.isComfortableGrid,
|
||||||
image: entry.customCoverImage != null
|
image: entry.customCoverImage != null
|
||||||
? MemoryImage(entry.customCoverImage as Uint8List) as ImageProvider
|
? MemoryImage(entry.customCoverImage as Uint8List)
|
||||||
|
as ImageProvider
|
||||||
: CustomExtendedNetworkImageProvider(
|
: CustomExtendedNetworkImageProvider(
|
||||||
toImgUrl(entry.customCoverFromTracker ?? entry.imageUrl ?? ""),
|
toImgUrl(entry.customCoverFromTracker ??
|
||||||
|
entry.imageUrl ??
|
||||||
|
""),
|
||||||
headers: entry.isLocalArchive!
|
headers: entry.isLocalArchive!
|
||||||
? null
|
? null
|
||||||
: ref.watch(headersProvider(source: entry.source!, lang: entry.lang!)),
|
: ref.watch(headersProvider(
|
||||||
|
source: entry.source!, lang: entry.lang!)),
|
||||||
),
|
),
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
if (isLongPressed) {
|
if (isLongPressed) {
|
||||||
|
|
@ -91,15 +96,19 @@ class _LibraryGridViewWidgetState extends State<LibraryGridViewWidget> {
|
||||||
lang: entry.lang!,
|
lang: entry.lang!,
|
||||||
mangaM: entry,
|
mangaM: entry,
|
||||||
source: entry.source!);
|
source: entry.source!);
|
||||||
ref.invalidate(getAllMangaWithoutCategoriesStreamProvider(isManga: widget.isManga));
|
ref.invalidate(getAllMangaWithoutCategoriesStreamProvider(
|
||||||
ref.invalidate(getAllMangaStreamProvider(categoryId: null, isManga: widget.isManga));
|
isManga: widget.isManga));
|
||||||
|
ref.invalidate(getAllMangaStreamProvider(
|
||||||
|
categoryId: null, isManga: widget.isManga));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onLongPress: () {
|
onLongPress: () {
|
||||||
if (!isLongPressed) {
|
if (!isLongPressed) {
|
||||||
ref.read(mangasListStateProvider.notifier).update(entry);
|
ref.read(mangasListStateProvider.notifier).update(entry);
|
||||||
|
|
||||||
ref.read(isLongPressedMangaStateProvider.notifier).update(!isLongPressed);
|
ref
|
||||||
|
.read(isLongPressedMangaStateProvider.notifier)
|
||||||
|
.update(!isLongPressed);
|
||||||
} else {
|
} else {
|
||||||
ref.read(mangasListStateProvider.notifier).update(entry);
|
ref.read(mangasListStateProvider.notifier).update(entry);
|
||||||
}
|
}
|
||||||
|
|
@ -108,7 +117,9 @@ class _LibraryGridViewWidgetState extends State<LibraryGridViewWidget> {
|
||||||
if (!isLongPressed) {
|
if (!isLongPressed) {
|
||||||
ref.read(mangasListStateProvider.notifier).update(entry);
|
ref.read(mangasListStateProvider.notifier).update(entry);
|
||||||
|
|
||||||
ref.read(isLongPressedMangaStateProvider.notifier).update(!isLongPressed);
|
ref
|
||||||
|
.read(isLongPressedMangaStateProvider.notifier)
|
||||||
|
.update(!isLongPressed);
|
||||||
} else {
|
} else {
|
||||||
ref.read(mangasListStateProvider.notifier).update(entry);
|
ref.read(mangasListStateProvider.notifier).update(entry);
|
||||||
}
|
}
|
||||||
|
|
@ -132,14 +143,18 @@ class _LibraryGridViewWidgetState extends State<LibraryGridViewWidget> {
|
||||||
Container(
|
Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: const BorderRadius.only(
|
borderRadius: const BorderRadius.only(
|
||||||
topLeft: Radius.circular(3), bottomLeft: Radius.circular(3)),
|
topLeft: Radius.circular(3),
|
||||||
|
bottomLeft: Radius.circular(3)),
|
||||||
color: Theme.of(context).hintColor,
|
color: Theme.of(context).hintColor,
|
||||||
),
|
),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.only(left: 3, right: 3),
|
padding: const EdgeInsets.only(
|
||||||
|
left: 3, right: 3),
|
||||||
child: Text(
|
child: Text(
|
||||||
"Local",
|
"Local",
|
||||||
style: TextStyle(color: context.dynamicBlackWhiteColor),
|
style: TextStyle(
|
||||||
|
color: context
|
||||||
|
.dynamicBlackWhiteColor),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -150,14 +165,20 @@ class _LibraryGridViewWidgetState extends State<LibraryGridViewWidget> {
|
||||||
List nbrDown = [];
|
List nbrDown = [];
|
||||||
if (widget.downloadedChapter) {
|
if (widget.downloadedChapter) {
|
||||||
isar.txnSync(() {
|
isar.txnSync(() {
|
||||||
for (var i = 0; i < entry.chapters.length; i++) {
|
for (var i = 0;
|
||||||
|
i < entry.chapters.length;
|
||||||
|
i++) {
|
||||||
final entries = isar.downloads
|
final entries = isar.downloads
|
||||||
.filter()
|
.filter()
|
||||||
.idIsNotNull()
|
.idIsNotNull()
|
||||||
.chapterIdEqualTo(entry.chapters.toList()[i].id)
|
.chapterIdEqualTo(entry
|
||||||
|
.chapters
|
||||||
|
.toList()[i]
|
||||||
|
.id)
|
||||||
.findAllSync();
|
.findAllSync();
|
||||||
|
|
||||||
if (entries.isNotEmpty && entries.first.isDownload!) {
|
if (entries.isNotEmpty &&
|
||||||
|
entries.first.isDownload!) {
|
||||||
nbrDown.add(1);
|
nbrDown.add(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -166,25 +187,42 @@ class _LibraryGridViewWidgetState extends State<LibraryGridViewWidget> {
|
||||||
|
|
||||||
return Row(
|
return Row(
|
||||||
children: [
|
children: [
|
||||||
if (nbrDown.isNotEmpty && widget.downloadedChapter)
|
if (nbrDown.isNotEmpty &&
|
||||||
|
widget.downloadedChapter)
|
||||||
Container(
|
Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: const BorderRadius.only(
|
borderRadius:
|
||||||
topLeft: Radius.circular(3), bottomLeft: Radius.circular(3)),
|
const BorderRadius.only(
|
||||||
color: Theme.of(context).secondaryHeaderColor,
|
topLeft:
|
||||||
|
Radius.circular(
|
||||||
|
3),
|
||||||
|
bottomLeft:
|
||||||
|
Radius.circular(
|
||||||
|
3)),
|
||||||
|
color: Theme.of(context)
|
||||||
|
.secondaryHeaderColor,
|
||||||
),
|
),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.only(left: 3, right: 3),
|
padding:
|
||||||
|
const EdgeInsets.only(
|
||||||
|
left: 3, right: 3),
|
||||||
child: Text(
|
child: Text(
|
||||||
nbrDown.length.toString(),
|
nbrDown.length.toString(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(left: 3),
|
padding: const EdgeInsets.only(
|
||||||
|
left: 3),
|
||||||
child: Text(
|
child: Text(
|
||||||
entry.chapters.where((element) => !element.isRead!).length.toString(),
|
entry.chapters
|
||||||
style: TextStyle(color: context.dynamicBlackWhiteColor),
|
.where((element) =>
|
||||||
|
!element.isRead!)
|
||||||
|
.length
|
||||||
|
.toString(),
|
||||||
|
style: TextStyle(
|
||||||
|
color: context
|
||||||
|
.dynamicBlackWhiteColor),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
@ -207,14 +245,17 @@ class _LibraryGridViewWidgetState extends State<LibraryGridViewWidget> {
|
||||||
child: Container(
|
child: Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: const BorderRadius.only(
|
borderRadius: const BorderRadius.only(
|
||||||
topLeft: Radius.circular(3), bottomLeft: Radius.circular(3)),
|
topLeft: Radius.circular(3),
|
||||||
|
bottomLeft: Radius.circular(3)),
|
||||||
color: Theme.of(context).hintColor,
|
color: Theme.of(context).hintColor,
|
||||||
),
|
),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.only(left: 3, right: 3),
|
padding: const EdgeInsets.only(
|
||||||
|
left: 3, right: 3),
|
||||||
child: Text(
|
child: Text(
|
||||||
entry.lang!.toUpperCase(),
|
entry.lang!.toUpperCase(),
|
||||||
style: const TextStyle(color: Colors.white),
|
style:
|
||||||
|
const TextStyle(color: Colors.white),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -222,7 +263,8 @@ class _LibraryGridViewWidgetState extends State<LibraryGridViewWidget> {
|
||||||
)),
|
)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
if (!widget.isComfortableGrid && !widget.isCoverOnlyGrid) BottomTextWidget(text: entry.name!),
|
if (!widget.isComfortableGrid && !widget.isCoverOnlyGrid)
|
||||||
|
BottomTextWidget(text: entry.name!),
|
||||||
if (widget.continueReaderBtn)
|
if (widget.continueReaderBtn)
|
||||||
Positioned(
|
Positioned(
|
||||||
bottom: 0,
|
bottom: 0,
|
||||||
|
|
@ -236,22 +278,31 @@ class _LibraryGridViewWidgetState extends State<LibraryGridViewWidget> {
|
||||||
.filter()
|
.filter()
|
||||||
.idIsNotNull()
|
.idIsNotNull()
|
||||||
.and()
|
.and()
|
||||||
.chapter((q) => q.manga((q) => q.isMangaEqualTo(entry.isManga!)))
|
.chapter((q) => q.manga((q) =>
|
||||||
|
q.isMangaEqualTo(entry.isManga!)))
|
||||||
.watch(fireImmediately: true),
|
.watch(fireImmediately: true),
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
if (snapshot.hasData && snapshot.data!.isNotEmpty) {
|
if (snapshot.hasData &&
|
||||||
final incognitoMode = ref.watch(incognitoModeStateProvider);
|
snapshot.data!.isNotEmpty) {
|
||||||
final entries =
|
final incognitoMode =
|
||||||
snapshot.data!.where((element) => element.mangaId == entry.id).toList();
|
ref.watch(incognitoModeStateProvider);
|
||||||
if (entries.isNotEmpty && !incognitoMode) {
|
final entries = snapshot.data!
|
||||||
|
.where((element) =>
|
||||||
|
element.mangaId == entry.id)
|
||||||
|
.toList();
|
||||||
|
if (entries.isNotEmpty &&
|
||||||
|
!incognitoMode) {
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
entries.first.chapter.value!.pushToReaderView(context);
|
entries.first.chapter.value!
|
||||||
|
.pushToReaderView(context);
|
||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.circular(5),
|
borderRadius:
|
||||||
color: context.primaryColor.withValues(alpha: 0.9),
|
BorderRadius.circular(5),
|
||||||
|
color: context.primaryColor
|
||||||
|
.withValues(alpha: 0.9),
|
||||||
),
|
),
|
||||||
child: const Padding(
|
child: const Padding(
|
||||||
padding: EdgeInsets.all(7),
|
padding: EdgeInsets.all(7),
|
||||||
|
|
@ -265,12 +316,19 @@ class _LibraryGridViewWidgetState extends State<LibraryGridViewWidget> {
|
||||||
}
|
}
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
entry.chapters.toList().reversed.toList().last.pushToReaderView(context);
|
entry.chapters
|
||||||
|
.toList()
|
||||||
|
.reversed
|
||||||
|
.toList()
|
||||||
|
.last
|
||||||
|
.pushToReaderView(context);
|
||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.circular(5),
|
borderRadius:
|
||||||
color: context.primaryColor.withValues(alpha: 0.9),
|
BorderRadius.circular(5),
|
||||||
|
color: context.primaryColor
|
||||||
|
.withValues(alpha: 0.9),
|
||||||
),
|
),
|
||||||
child: const Padding(
|
child: const Padding(
|
||||||
padding: EdgeInsets.all(7),
|
padding: EdgeInsets.all(7),
|
||||||
|
|
@ -284,12 +342,19 @@ class _LibraryGridViewWidgetState extends State<LibraryGridViewWidget> {
|
||||||
}
|
}
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
entry.chapters.toList().reversed.toList().last.pushToReaderView(context);
|
entry.chapters
|
||||||
|
.toList()
|
||||||
|
.reversed
|
||||||
|
.toList()
|
||||||
|
.last
|
||||||
|
.pushToReaderView(context);
|
||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.circular(5),
|
borderRadius:
|
||||||
color: context.primaryColor.withValues(alpha: 0.9),
|
BorderRadius.circular(5),
|
||||||
|
color: context.primaryColor
|
||||||
|
.withValues(alpha: 0.9),
|
||||||
),
|
),
|
||||||
child: const Padding(
|
child: const Padding(
|
||||||
padding: EdgeInsets.all(7),
|
padding: EdgeInsets.all(7),
|
||||||
|
|
|
||||||
|
|
@ -58,15 +58,19 @@ class LibraryListViewWidget extends StatelessWidget {
|
||||||
lang: entry.lang!,
|
lang: entry.lang!,
|
||||||
mangaM: entry,
|
mangaM: entry,
|
||||||
source: entry.source!);
|
source: entry.source!);
|
||||||
ref.invalidate(getAllMangaWithoutCategoriesStreamProvider(isManga: entry.isManga));
|
ref.invalidate(getAllMangaWithoutCategoriesStreamProvider(
|
||||||
ref.invalidate(getAllMangaStreamProvider(categoryId: null, isManga: entry.isManga));
|
isManga: entry.isManga));
|
||||||
|
ref.invalidate(getAllMangaStreamProvider(
|
||||||
|
categoryId: null, isManga: entry.isManga));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onLongPress: () {
|
onLongPress: () {
|
||||||
if (!isLongPressed) {
|
if (!isLongPressed) {
|
||||||
ref.read(mangasListStateProvider.notifier).update(entry);
|
ref.read(mangasListStateProvider.notifier).update(entry);
|
||||||
|
|
||||||
ref.read(isLongPressedMangaStateProvider.notifier).update(!isLongPressed);
|
ref
|
||||||
|
.read(isLongPressedMangaStateProvider.notifier)
|
||||||
|
.update(!isLongPressed);
|
||||||
} else {
|
} else {
|
||||||
ref.read(mangasListStateProvider.notifier).update(entry);
|
ref.read(mangasListStateProvider.notifier).update(entry);
|
||||||
}
|
}
|
||||||
|
|
@ -75,19 +79,24 @@ class LibraryListViewWidget extends StatelessWidget {
|
||||||
if (!isLongPressed) {
|
if (!isLongPressed) {
|
||||||
ref.read(mangasListStateProvider.notifier).update(entry);
|
ref.read(mangasListStateProvider.notifier).update(entry);
|
||||||
|
|
||||||
ref.read(isLongPressedMangaStateProvider.notifier).update(!isLongPressed);
|
ref
|
||||||
|
.read(isLongPressedMangaStateProvider.notifier)
|
||||||
|
.update(!isLongPressed);
|
||||||
} else {
|
} else {
|
||||||
ref.read(mangasListStateProvider.notifier).update(entry);
|
ref.read(mangasListStateProvider.notifier).update(entry);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
color:
|
color: mangaIdsList.contains(entry.id)
|
||||||
mangaIdsList.contains(entry.id) ? context.primaryColor.withValues(alpha: 0.4) : Colors.transparent,
|
? context.primaryColor.withValues(alpha: 0.4)
|
||||||
|
: Colors.transparent,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 3),
|
padding:
|
||||||
|
const EdgeInsets.symmetric(horizontal: 8, vertical: 3),
|
||||||
child: Container(
|
child: Container(
|
||||||
height: 45,
|
height: 45,
|
||||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(5)),
|
decoration:
|
||||||
|
BoxDecoration(borderRadius: BorderRadius.circular(5)),
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
|
|
@ -102,16 +111,21 @@ class LibraryListViewWidget extends StatelessWidget {
|
||||||
width: 40,
|
width: 40,
|
||||||
height: 45,
|
height: 45,
|
||||||
image: entry.customCoverImage != null
|
image: entry.customCoverImage != null
|
||||||
? MemoryImage(entry.customCoverImage as Uint8List) as ImageProvider
|
? MemoryImage(entry.customCoverImage
|
||||||
|
as Uint8List) as ImageProvider
|
||||||
: CustomExtendedNetworkImageProvider(
|
: CustomExtendedNetworkImageProvider(
|
||||||
toImgUrl(entry.customCoverFromTracker ?? entry.imageUrl!),
|
toImgUrl(
|
||||||
headers:
|
entry.customCoverFromTracker ??
|
||||||
ref.watch(headersProvider(source: entry.source!, lang: entry.lang!)),
|
entry.imageUrl!),
|
||||||
|
headers: ref.watch(headersProvider(
|
||||||
|
source: entry.source!,
|
||||||
|
lang: entry.lang!)),
|
||||||
),
|
),
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
child: Container(
|
child: Container(
|
||||||
color: mangaIdsList.contains(entry.id)
|
color: mangaIdsList.contains(entry.id)
|
||||||
? context.primaryColor.withValues(alpha: 0.4)
|
? context.primaryColor
|
||||||
|
.withValues(alpha: 0.4)
|
||||||
: Colors.transparent,
|
: Colors.transparent,
|
||||||
)),
|
)),
|
||||||
),
|
),
|
||||||
|
|
@ -119,7 +133,8 @@ class LibraryListViewWidget extends StatelessWidget {
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 10),
|
padding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 10),
|
||||||
child: Text(entry.name!),
|
child: Text(entry.name!),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
@ -129,8 +144,9 @@ class LibraryListViewWidget extends StatelessWidget {
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.all(5),
|
padding: const EdgeInsets.all(5),
|
||||||
child: Container(
|
child: Container(
|
||||||
decoration:
|
decoration: BoxDecoration(
|
||||||
BoxDecoration(borderRadius: BorderRadius.circular(3), color: context.primaryColor),
|
borderRadius: BorderRadius.circular(3),
|
||||||
|
color: context.primaryColor),
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
height: 22,
|
height: 22,
|
||||||
child: Row(
|
child: Row(
|
||||||
|
|
@ -139,11 +155,13 @@ class LibraryListViewWidget extends StatelessWidget {
|
||||||
Container(
|
Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: const BorderRadius.only(
|
borderRadius: const BorderRadius.only(
|
||||||
topLeft: Radius.circular(3), bottomLeft: Radius.circular(3)),
|
topLeft: Radius.circular(3),
|
||||||
|
bottomLeft: Radius.circular(3)),
|
||||||
color: Theme.of(context).hintColor,
|
color: Theme.of(context).hintColor,
|
||||||
),
|
),
|
||||||
child: const Padding(
|
child: const Padding(
|
||||||
padding: EdgeInsets.only(left: 3, right: 3),
|
padding:
|
||||||
|
EdgeInsets.only(left: 3, right: 3),
|
||||||
child: Text(
|
child: Text(
|
||||||
"Local",
|
"Local",
|
||||||
style: TextStyle(color: Colors.white),
|
style: TextStyle(color: Colors.white),
|
||||||
|
|
@ -157,14 +175,20 @@ class LibraryListViewWidget extends StatelessWidget {
|
||||||
builder: (context, ref, child) {
|
builder: (context, ref, child) {
|
||||||
List nbrDown = [];
|
List nbrDown = [];
|
||||||
isar.txnSync(() {
|
isar.txnSync(() {
|
||||||
for (var i = 0; i < entry.chapters.length; i++) {
|
for (var i = 0;
|
||||||
|
i < entry.chapters.length;
|
||||||
|
i++) {
|
||||||
final entries = isar.downloads
|
final entries = isar.downloads
|
||||||
.filter()
|
.filter()
|
||||||
.idIsNotNull()
|
.idIsNotNull()
|
||||||
.chapterIdEqualTo(entry.chapters.toList()[i].id)
|
.chapterIdEqualTo(entry
|
||||||
|
.chapters
|
||||||
|
.toList()[i]
|
||||||
|
.id)
|
||||||
.findAllSync();
|
.findAllSync();
|
||||||
|
|
||||||
if (entries.isNotEmpty && entries.first.isDownload!) {
|
if (entries.isNotEmpty &&
|
||||||
|
entries.first.isDownload!) {
|
||||||
nbrDown.add(entries.first);
|
nbrDown.add(entries.first);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -172,15 +196,22 @@ class LibraryListViewWidget extends StatelessWidget {
|
||||||
if (nbrDown.isNotEmpty) {
|
if (nbrDown.isNotEmpty) {
|
||||||
return Container(
|
return Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: const BorderRadius.only(
|
borderRadius:
|
||||||
topLeft: Radius.circular(3), bottomLeft: Radius.circular(3)),
|
const BorderRadius.only(
|
||||||
color: Theme.of(context).hintColor,
|
topLeft:
|
||||||
|
Radius.circular(3),
|
||||||
|
bottomLeft:
|
||||||
|
Radius.circular(3)),
|
||||||
|
color:
|
||||||
|
Theme.of(context).hintColor,
|
||||||
),
|
),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.only(left: 3, right: 3),
|
padding: const EdgeInsets.only(
|
||||||
|
left: 3, right: 3),
|
||||||
child: Text(
|
child: Text(
|
||||||
nbrDown.length.toString(),
|
nbrDown.length.toString(),
|
||||||
style: const TextStyle(color: Colors.white),
|
style: const TextStyle(
|
||||||
|
color: Colors.white),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
@ -194,7 +225,8 @@ class LibraryListViewWidget extends StatelessWidget {
|
||||||
padding: const EdgeInsets.only(right: 3),
|
padding: const EdgeInsets.only(right: 3),
|
||||||
child: Text(
|
child: Text(
|
||||||
entry.chapters.length.toString(),
|
entry.chapters.length.toString(),
|
||||||
style: const TextStyle(color: Colors.white),
|
style:
|
||||||
|
const TextStyle(color: Colors.white),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (language && entry.lang!.isNotEmpty)
|
if (language && entry.lang!.isNotEmpty)
|
||||||
|
|
@ -203,14 +235,17 @@ class LibraryListViewWidget extends StatelessWidget {
|
||||||
child: Container(
|
child: Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: const BorderRadius.only(
|
borderRadius: const BorderRadius.only(
|
||||||
topRight: Radius.circular(3), bottomRight: Radius.circular(3)),
|
topRight: Radius.circular(3),
|
||||||
|
bottomRight: Radius.circular(3)),
|
||||||
color: Theme.of(context).hintColor,
|
color: Theme.of(context).hintColor,
|
||||||
),
|
),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.only(left: 3, right: 3),
|
padding: const EdgeInsets.only(
|
||||||
|
left: 3, right: 3),
|
||||||
child: Text(
|
child: Text(
|
||||||
entry.lang!.toUpperCase(),
|
entry.lang!.toUpperCase(),
|
||||||
style: const TextStyle(color: Colors.white),
|
style: const TextStyle(
|
||||||
|
color: Colors.white),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -228,13 +263,18 @@ class LibraryListViewWidget extends StatelessWidget {
|
||||||
.filter()
|
.filter()
|
||||||
.idIsNotNull()
|
.idIsNotNull()
|
||||||
.and()
|
.and()
|
||||||
.chapter((q) => q.manga((q) => q.isMangaEqualTo(entry.isManga!)))
|
.chapter((q) => q.manga((q) =>
|
||||||
|
q.isMangaEqualTo(entry.isManga!)))
|
||||||
.watch(fireImmediately: true),
|
.watch(fireImmediately: true),
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
if (snapshot.hasData && snapshot.data!.isNotEmpty) {
|
if (snapshot.hasData &&
|
||||||
final incognitoMode = ref.watch(incognitoModeStateProvider);
|
snapshot.data!.isNotEmpty) {
|
||||||
final entries =
|
final incognitoMode =
|
||||||
snapshot.data!.where((element) => element.mangaId == entry.id).toList();
|
ref.watch(incognitoModeStateProvider);
|
||||||
|
final entries = snapshot.data!
|
||||||
|
.where((element) =>
|
||||||
|
element.mangaId == entry.id)
|
||||||
|
.toList();
|
||||||
if (entries.isNotEmpty && !incognitoMode) {
|
if (entries.isNotEmpty && !incognitoMode) {
|
||||||
final chap = entries.first.chapter.value!;
|
final chap = entries.first.chapter.value!;
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
|
|
@ -243,8 +283,10 @@ class LibraryListViewWidget extends StatelessWidget {
|
||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.circular(5),
|
borderRadius:
|
||||||
color: context.primaryColor.withValues(alpha: 0.9),
|
BorderRadius.circular(5),
|
||||||
|
color: context.primaryColor
|
||||||
|
.withValues(alpha: 0.9),
|
||||||
),
|
),
|
||||||
child: const Padding(
|
child: const Padding(
|
||||||
padding: EdgeInsets.all(7),
|
padding: EdgeInsets.all(7),
|
||||||
|
|
@ -258,12 +300,19 @@ class LibraryListViewWidget extends StatelessWidget {
|
||||||
}
|
}
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
entry.chapters.toList().reversed.toList().last.pushToReaderView(context);
|
entry.chapters
|
||||||
|
.toList()
|
||||||
|
.reversed
|
||||||
|
.toList()
|
||||||
|
.last
|
||||||
|
.pushToReaderView(context);
|
||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.circular(5),
|
borderRadius:
|
||||||
color: context.primaryColor.withValues(alpha: 0.9),
|
BorderRadius.circular(5),
|
||||||
|
color: context.primaryColor
|
||||||
|
.withValues(alpha: 0.9),
|
||||||
),
|
),
|
||||||
child: const Padding(
|
child: const Padding(
|
||||||
padding: EdgeInsets.all(7),
|
padding: EdgeInsets.all(7),
|
||||||
|
|
@ -277,12 +326,18 @@ class LibraryListViewWidget extends StatelessWidget {
|
||||||
}
|
}
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
entry.chapters.toList().reversed.toList().last.pushToReaderView(context);
|
entry.chapters
|
||||||
|
.toList()
|
||||||
|
.reversed
|
||||||
|
.toList()
|
||||||
|
.last
|
||||||
|
.pushToReaderView(context);
|
||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.circular(5),
|
borderRadius: BorderRadius.circular(5),
|
||||||
color: context.primaryColor.withValues(alpha: 0.9),
|
color: context.primaryColor
|
||||||
|
.withValues(alpha: 0.9),
|
||||||
),
|
),
|
||||||
child: const Padding(
|
child: const Padding(
|
||||||
padding: EdgeInsets.all(7),
|
padding: EdgeInsets.all(7),
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,9 @@ class _ListTileMangaCategoryState extends State<ListTileMangaCategory> {
|
||||||
void initState() {
|
void initState() {
|
||||||
final res = widget.mangasList.where(
|
final res = widget.mangasList.where(
|
||||||
(element) {
|
(element) {
|
||||||
return element.categories == null ? false : element.categories!.contains(widget.category.id);
|
return element.categories == null
|
||||||
|
? false
|
||||||
|
: element.categories!.contains(widget.category.id);
|
||||||
},
|
},
|
||||||
).toList();
|
).toList();
|
||||||
widget.res(res);
|
widget.res(res);
|
||||||
|
|
|
||||||
|
|
@ -35,8 +35,10 @@ class SeachFormTextField extends StatelessWidget {
|
||||||
icon: const Icon(
|
icon: const Icon(
|
||||||
Icons.arrow_back,
|
Icons.arrow_back,
|
||||||
)),
|
)),
|
||||||
suffixIcon:
|
suffixIcon: controller.text.isEmpty
|
||||||
controller.text.isEmpty ? null : IconButton(onPressed: onSuffixPressed, icon: const Icon(Icons.clear)),
|
? null
|
||||||
|
: IconButton(
|
||||||
|
onPressed: onSuffixPressed, icon: const Icon(Icons.clear)),
|
||||||
enabledBorder: const OutlineInputBorder(
|
enabledBorder: const OutlineInputBorder(
|
||||||
borderSide: BorderSide.none,
|
borderSide: BorderSide.none,
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,8 @@ class MainScreen extends ConsumerWidget {
|
||||||
final location = ref.watch(
|
final location = ref.watch(
|
||||||
routerCurrentLocationStateProvider(context),
|
routerCurrentLocationStateProvider(context),
|
||||||
);
|
);
|
||||||
bool isReadingScreen = location == '/mangareaderview' || location == '/animePlayerView';
|
bool isReadingScreen =
|
||||||
|
location == '/mangareaderview' || location == '/animePlayerView';
|
||||||
int currentIndex = switch (location) {
|
int currentIndex = switch (location) {
|
||||||
null || '/MangaLibrary' => 0,
|
null || '/MangaLibrary' => 0,
|
||||||
'/AnimeLibrary' => 1,
|
'/AnimeLibrary' => 1,
|
||||||
|
|
@ -122,7 +123,9 @@ class MainScreen extends ConsumerWidget {
|
||||||
children: [
|
children: [
|
||||||
NavigationRailTheme(
|
NavigationRailTheme(
|
||||||
data: NavigationRailThemeData(
|
data: NavigationRailThemeData(
|
||||||
indicatorShape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(30)),
|
indicatorShape: RoundedRectangleBorder(
|
||||||
|
borderRadius:
|
||||||
|
BorderRadius.circular(30)),
|
||||||
),
|
),
|
||||||
child: Builder(builder: (context) {
|
child: Builder(builder: (context) {
|
||||||
return NavigationRail(
|
return NavigationRail(
|
||||||
|
|
@ -130,46 +133,73 @@ class MainScreen extends ConsumerWidget {
|
||||||
useIndicator: true,
|
useIndicator: true,
|
||||||
destinations: [
|
destinations: [
|
||||||
NavigationRailDestination(
|
NavigationRailDestination(
|
||||||
selectedIcon: const Icon(Icons.collections_bookmark),
|
selectedIcon: const Icon(
|
||||||
icon: const Icon(Icons.collections_bookmark_outlined),
|
Icons.collections_bookmark),
|
||||||
|
icon: const Icon(Icons
|
||||||
|
.collections_bookmark_outlined),
|
||||||
label: Padding(
|
label: Padding(
|
||||||
padding: const EdgeInsets.only(top: 5), child: Text(l10n.manga))),
|
padding: const EdgeInsets.only(
|
||||||
|
top: 5),
|
||||||
|
child: Text(l10n.manga))),
|
||||||
NavigationRailDestination(
|
NavigationRailDestination(
|
||||||
selectedIcon: const Icon(Icons.video_collection),
|
selectedIcon: const Icon(
|
||||||
icon: const Icon(Icons.video_collection_outlined),
|
Icons.video_collection),
|
||||||
|
icon: const Icon(Icons
|
||||||
|
.video_collection_outlined),
|
||||||
label: Padding(
|
label: Padding(
|
||||||
padding: const EdgeInsets.only(top: 5), child: Text(l10n.anime))),
|
padding: const EdgeInsets.only(
|
||||||
|
top: 5),
|
||||||
|
child: Text(l10n.anime))),
|
||||||
NavigationRailDestination(
|
NavigationRailDestination(
|
||||||
selectedIcon: const Icon(Icons.new_releases),
|
selectedIcon:
|
||||||
icon: const Icon(Icons.new_releases_outlined),
|
const Icon(Icons.new_releases),
|
||||||
|
icon: const Icon(
|
||||||
|
Icons.new_releases_outlined),
|
||||||
label: Padding(
|
label: Padding(
|
||||||
padding: const EdgeInsets.only(top: 5),
|
padding: const EdgeInsets.only(
|
||||||
|
top: 5),
|
||||||
child: Stack(
|
child: Stack(
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
getHyphenatedUpdatesLabel(
|
getHyphenatedUpdatesLabel(
|
||||||
ref.watch(l10nLocaleStateProvider).languageCode,
|
ref
|
||||||
|
.watch(
|
||||||
|
l10nLocaleStateProvider)
|
||||||
|
.languageCode,
|
||||||
l10n.updates,
|
l10n.updates,
|
||||||
),
|
),
|
||||||
textAlign: TextAlign.center,
|
textAlign:
|
||||||
|
TextAlign.center,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
))),
|
))),
|
||||||
NavigationRailDestination(
|
NavigationRailDestination(
|
||||||
selectedIcon: const Icon(Icons.history),
|
selectedIcon:
|
||||||
icon: const Icon(Icons.history_outlined),
|
const Icon(Icons.history),
|
||||||
|
icon: const Icon(
|
||||||
|
Icons.history_outlined),
|
||||||
label: Padding(
|
label: Padding(
|
||||||
padding: const EdgeInsets.only(top: 5), child: Text(l10n.history))),
|
padding: const EdgeInsets.only(
|
||||||
|
top: 5),
|
||||||
|
child: Text(l10n.history))),
|
||||||
NavigationRailDestination(
|
NavigationRailDestination(
|
||||||
selectedIcon: const Icon(Icons.explore),
|
selectedIcon:
|
||||||
icon: const Icon(Icons.explore_outlined),
|
const Icon(Icons.explore),
|
||||||
|
icon: const Icon(
|
||||||
|
Icons.explore_outlined),
|
||||||
label: Padding(
|
label: Padding(
|
||||||
padding: const EdgeInsets.only(top: 5), child: Text(l10n.browse))),
|
padding: const EdgeInsets.only(
|
||||||
|
top: 5),
|
||||||
|
child: Text(l10n.browse))),
|
||||||
NavigationRailDestination(
|
NavigationRailDestination(
|
||||||
selectedIcon: const Icon(Icons.more_horiz),
|
selectedIcon:
|
||||||
icon: const Icon(Icons.more_horiz_outlined),
|
const Icon(Icons.more_horiz),
|
||||||
|
icon: const Icon(
|
||||||
|
Icons.more_horiz_outlined),
|
||||||
label: Padding(
|
label: Padding(
|
||||||
padding: const EdgeInsets.only(top: 5), child: Text(l10n.more))),
|
padding: const EdgeInsets.only(
|
||||||
|
top: 5),
|
||||||
|
child: Text(l10n.more))),
|
||||||
],
|
],
|
||||||
selectedIndex: currentIndex,
|
selectedIndex: currentIndex,
|
||||||
onDestinationSelected: (newIndex) {
|
onDestinationSelected: (newIndex) {
|
||||||
|
|
@ -186,8 +216,14 @@ class MainScreen extends ConsumerWidget {
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
Positioned(right: 18, top: 140, child: _updatesTotalNumbers(ref)),
|
Positioned(
|
||||||
Positioned(right: 18, top: 275, child: _extensionUpdateTotalNumbers(ref)),
|
right: 18,
|
||||||
|
top: 140,
|
||||||
|
child: _updatesTotalNumbers(ref)),
|
||||||
|
Positioned(
|
||||||
|
right: 18,
|
||||||
|
top: 275,
|
||||||
|
child: _extensionUpdateTotalNumbers(ref)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -216,27 +252,38 @@ class MainScreen extends ConsumerWidget {
|
||||||
},
|
},
|
||||||
child: NavigationBarTheme(
|
child: NavigationBarTheme(
|
||||||
data: NavigationBarThemeData(
|
data: NavigationBarThemeData(
|
||||||
indicatorShape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(30)),
|
indicatorShape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(30)),
|
||||||
),
|
),
|
||||||
child: NavigationBar(
|
child: NavigationBar(
|
||||||
animationDuration: const Duration(milliseconds: 500),
|
animationDuration:
|
||||||
|
const Duration(milliseconds: 500),
|
||||||
selectedIndex: currentIndex,
|
selectedIndex: currentIndex,
|
||||||
destinations: [
|
destinations: [
|
||||||
NavigationDestination(
|
NavigationDestination(
|
||||||
selectedIcon: const Icon(Icons.collections_bookmark),
|
selectedIcon:
|
||||||
icon: const Icon(Icons.collections_bookmark_outlined),
|
const Icon(Icons.collections_bookmark),
|
||||||
|
icon: const Icon(
|
||||||
|
Icons.collections_bookmark_outlined),
|
||||||
label: l10n.manga),
|
label: l10n.manga),
|
||||||
NavigationDestination(
|
NavigationDestination(
|
||||||
selectedIcon: const Icon(Icons.video_collection),
|
selectedIcon:
|
||||||
icon: const Icon(Icons.video_collection_outlined),
|
const Icon(Icons.video_collection),
|
||||||
|
icon: const Icon(
|
||||||
|
Icons.video_collection_outlined),
|
||||||
label: l10n.anime),
|
label: l10n.anime),
|
||||||
Stack(
|
Stack(
|
||||||
children: [
|
children: [
|
||||||
NavigationDestination(
|
NavigationDestination(
|
||||||
selectedIcon: const Icon(Icons.new_releases),
|
selectedIcon:
|
||||||
icon: const Icon(Icons.new_releases_outlined),
|
const Icon(Icons.new_releases),
|
||||||
|
icon: const Icon(
|
||||||
|
Icons.new_releases_outlined),
|
||||||
label: l10n.updates),
|
label: l10n.updates),
|
||||||
Positioned(right: 14, top: 3, child: _updatesTotalNumbers(ref)),
|
Positioned(
|
||||||
|
right: 14,
|
||||||
|
top: 3,
|
||||||
|
child: _updatesTotalNumbers(ref)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
NavigationDestination(
|
NavigationDestination(
|
||||||
|
|
@ -249,7 +296,10 @@ class MainScreen extends ConsumerWidget {
|
||||||
selectedIcon: const Icon(Icons.explore),
|
selectedIcon: const Icon(Icons.explore),
|
||||||
icon: const Icon(Icons.explore_outlined),
|
icon: const Icon(Icons.explore_outlined),
|
||||||
label: l10n.browse),
|
label: l10n.browse),
|
||||||
Positioned(right: 14, top: 3, child: _extensionUpdateTotalNumbers(ref)),
|
Positioned(
|
||||||
|
right: 14,
|
||||||
|
top: 3,
|
||||||
|
child: _extensionUpdateTotalNumbers(ref)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
NavigationDestination(
|
NavigationDestination(
|
||||||
|
|
@ -286,21 +336,32 @@ class MainScreen extends ConsumerWidget {
|
||||||
|
|
||||||
Widget _extensionUpdateTotalNumbers(WidgetRef ref) {
|
Widget _extensionUpdateTotalNumbers(WidgetRef ref) {
|
||||||
return StreamBuilder(
|
return StreamBuilder(
|
||||||
stream: isar.sources.filter().idIsNotNull().and().isActiveEqualTo(true).watch(fireImmediately: true),
|
stream: isar.sources
|
||||||
|
.filter()
|
||||||
|
.idIsNotNull()
|
||||||
|
.and()
|
||||||
|
.isActiveEqualTo(true)
|
||||||
|
.watch(fireImmediately: true),
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
if (snapshot.hasData && snapshot.data!.isNotEmpty) {
|
if (snapshot.hasData && snapshot.data!.isNotEmpty) {
|
||||||
final entries =
|
final entries = snapshot.data!
|
||||||
snapshot.data!.where((element) => compareVersions(element.version!, element.versionLast!) < 0).toList();
|
.where((element) =>
|
||||||
|
compareVersions(element.version!, element.versionLast!) < 0)
|
||||||
|
.toList();
|
||||||
return entries.isEmpty
|
return entries.isEmpty
|
||||||
? Container()
|
? Container()
|
||||||
: Container(
|
: Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.circular(10), color: const Color.fromARGB(255, 176, 46, 37)),
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
color: const Color.fromARGB(255, 176, 46, 37)),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 5, vertical: 3),
|
padding:
|
||||||
|
const EdgeInsets.symmetric(horizontal: 5, vertical: 3),
|
||||||
child: Text(
|
child: Text(
|
||||||
entries.length.toString(),
|
entries.length.toString(),
|
||||||
style: TextStyle(fontSize: 10, color: Theme.of(context).textTheme.bodySmall!.color),
|
style: TextStyle(
|
||||||
|
fontSize: 10,
|
||||||
|
color: Theme.of(context).textTheme.bodySmall!.color),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
@ -324,12 +385,16 @@ Widget _updatesTotalNumbers(WidgetRef ref) {
|
||||||
? Container()
|
? Container()
|
||||||
: Container(
|
: Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.circular(10), color: const Color.fromARGB(255, 176, 46, 37)),
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
color: const Color.fromARGB(255, 176, 46, 37)),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 5, vertical: 3),
|
padding:
|
||||||
|
const EdgeInsets.symmetric(horizontal: 5, vertical: 3),
|
||||||
child: Text(
|
child: Text(
|
||||||
entries.length.toString(),
|
entries.length.toString(),
|
||||||
style: TextStyle(fontSize: 10, color: Theme.of(context).textTheme.bodySmall!.color),
|
style: TextStyle(
|
||||||
|
fontSize: 10,
|
||||||
|
color: Theme.of(context).textTheme.bodySmall!.color),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -11,11 +11,20 @@ part 'migration.g.dart';
|
||||||
|
|
||||||
@riverpod
|
@riverpod
|
||||||
Future<void> migration(Ref ref) async {
|
Future<void> migration(Ref ref) async {
|
||||||
final chapters = isar.chapters.filter().idIsNotNull().mangaIdIsNull().findAllSync();
|
final chapters =
|
||||||
final downloads = isar.downloads.filter().idIsNotNull().mangaIdIsNull().findAllSync();
|
isar.chapters.filter().idIsNotNull().mangaIdIsNull().findAllSync();
|
||||||
final histories =
|
final downloads =
|
||||||
isar.historys.filter().idIsNotNull().chapterIdIsNull().or().idIsNotNull().isMangaIsNull().findAllSync();
|
isar.downloads.filter().idIsNotNull().mangaIdIsNull().findAllSync();
|
||||||
final tracks = isar.tracks.filter().idIsNotNull().isMangaIsNull().findAllSync();
|
final histories = isar.historys
|
||||||
|
.filter()
|
||||||
|
.idIsNotNull()
|
||||||
|
.chapterIdIsNull()
|
||||||
|
.or()
|
||||||
|
.idIsNotNull()
|
||||||
|
.isMangaIsNull()
|
||||||
|
.findAllSync();
|
||||||
|
final tracks =
|
||||||
|
isar.tracks.filter().idIsNotNull().isMangaIsNull().findAllSync();
|
||||||
|
|
||||||
isar.writeTxnSync(() {
|
isar.writeTxnSync(() {
|
||||||
//mangaId in chapter
|
//mangaId in chapter
|
||||||
|
|
|
||||||
|
|
@ -8,17 +8,20 @@ import 'package:path/path.dart' as p;
|
||||||
part 'archive_reader_providers.g.dart';
|
part 'archive_reader_providers.g.dart';
|
||||||
|
|
||||||
@riverpod
|
@riverpod
|
||||||
Future<List<(String, LocalExtensionType, Uint8List, String)>> getArchivesDataFromDirectory(Ref ref, String path) async {
|
Future<List<(String, LocalExtensionType, Uint8List, String)>>
|
||||||
|
getArchivesDataFromDirectory(Ref ref, String path) async {
|
||||||
return compute(_extractOnly, path);
|
return compute(_extractOnly, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@riverpod
|
@riverpod
|
||||||
Future<List<LocalArchive>> getArchiveDataFromDirectory(Ref ref, String path) async {
|
Future<List<LocalArchive>> getArchiveDataFromDirectory(
|
||||||
|
Ref ref, String path) async {
|
||||||
return compute(_extract, path);
|
return compute(_extract, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@riverpod
|
@riverpod
|
||||||
Future<(String, LocalExtensionType, Uint8List, String)> getArchivesDataFromFile(Ref ref, String path) async {
|
Future<(String, LocalExtensionType, Uint8List, String)> getArchivesDataFromFile(
|
||||||
|
Ref ref, String path) async {
|
||||||
return compute(_extractArchiveOnly, path);
|
return compute(_extractArchiveOnly, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -31,7 +34,8 @@ Future<List<LocalArchive>> _extract(String data) async {
|
||||||
return await _searchForArchive(Directory(data));
|
return await _searchForArchive(Directory(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<(String, LocalExtensionType, Uint8List, String)>> _extractOnly(String data) async {
|
Future<List<(String, LocalExtensionType, Uint8List, String)>> _extractOnly(
|
||||||
|
String data) async {
|
||||||
return await _searchForArchiveOnly(Directory(data));
|
return await _searchForArchiveOnly(Directory(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -53,7 +57,8 @@ Future<List<LocalArchive>> _searchForArchive(Directory dir) async {
|
||||||
return _list;
|
return _list;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<(String, LocalExtensionType, Uint8List, String)>> _searchForArchiveOnly(Directory dir) async {
|
Future<List<(String, LocalExtensionType, Uint8List, String)>>
|
||||||
|
_searchForArchiveOnly(Directory dir) async {
|
||||||
List<FileSystemEntity> entities = dir.listSync();
|
List<FileSystemEntity> entities = dir.listSync();
|
||||||
for (FileSystemEntity entity in entities) {
|
for (FileSystemEntity entity in entities) {
|
||||||
if (entity is Directory) {
|
if (entity is Directory) {
|
||||||
|
|
@ -99,7 +104,8 @@ LocalArchive _extractArchive(String path) {
|
||||||
Archive? archive;
|
Archive? archive;
|
||||||
final inputStream = InputFileStream(path);
|
final inputStream = InputFileStream(path);
|
||||||
final extensionType = localArchive.extensionType;
|
final extensionType = localArchive.extensionType;
|
||||||
if (extensionType == LocalExtensionType.cbt || extensionType == LocalExtensionType.tar) {
|
if (extensionType == LocalExtensionType.cbt ||
|
||||||
|
extensionType == LocalExtensionType.tar) {
|
||||||
archive = TarDecoder().decodeStream(inputStream);
|
archive = TarDecoder().decodeStream(inputStream);
|
||||||
} else {
|
} else {
|
||||||
archive = ZipDecoder().decodeStream(inputStream);
|
archive = ZipDecoder().decodeStream(inputStream);
|
||||||
|
|
@ -125,27 +131,35 @@ LocalArchive _extractArchive(String path) {
|
||||||
return localArchive;
|
return localArchive;
|
||||||
}
|
}
|
||||||
|
|
||||||
(String, LocalExtensionType, Uint8List, String) _extractArchiveOnly(String path) {
|
(String, LocalExtensionType, Uint8List, String) _extractArchiveOnly(
|
||||||
final extensionType = setTypeExtension(p.extension(path).replaceFirst('.', ''));
|
String path) {
|
||||||
|
final extensionType =
|
||||||
|
setTypeExtension(p.extension(path).replaceFirst('.', ''));
|
||||||
final name = p.basenameWithoutExtension(path);
|
final name = p.basenameWithoutExtension(path);
|
||||||
Uint8List? coverImage;
|
Uint8List? coverImage;
|
||||||
|
|
||||||
Archive? archive;
|
Archive? archive;
|
||||||
final inputStream = InputFileStream(path);
|
final inputStream = InputFileStream(path);
|
||||||
|
|
||||||
if (extensionType == LocalExtensionType.cbt || extensionType == LocalExtensionType.tar) {
|
if (extensionType == LocalExtensionType.cbt ||
|
||||||
|
extensionType == LocalExtensionType.tar) {
|
||||||
archive = TarDecoder().decodeStream(inputStream);
|
archive = TarDecoder().decodeStream(inputStream);
|
||||||
} else {
|
} else {
|
||||||
archive = ZipDecoder().decodeStream(inputStream);
|
archive = ZipDecoder().decodeStream(inputStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
final cover = archive.files.where((file) => file.isFile && _isImageFile(file.name) && file.name.contains("cover"));
|
final cover = archive.files.where((file) =>
|
||||||
|
file.isFile && _isImageFile(file.name) && file.name.contains("cover"));
|
||||||
|
|
||||||
if (cover.isNotEmpty) {
|
if (cover.isNotEmpty) {
|
||||||
coverImage = cover.first.content;
|
coverImage = cover.first.content;
|
||||||
} else {
|
} else {
|
||||||
List<ArchiveFile> lArchive =
|
List<ArchiveFile> lArchive = archive.files
|
||||||
archive.files.where((file) => file.isFile && _isImageFile(file.name) && !file.name.contains("cover")).toList();
|
.where((file) =>
|
||||||
|
file.isFile &&
|
||||||
|
_isImageFile(file.name) &&
|
||||||
|
!file.name.contains("cover"))
|
||||||
|
.toList();
|
||||||
lArchive.sort(
|
lArchive.sort(
|
||||||
(a, b) => a.name.compareTo(b.name),
|
(a, b) => a.name.compareTo(b.name),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,9 @@ class _MangaReaderDetailState extends ConsumerState<MangaReaderDetail> {
|
||||||
|
|
||||||
_init() async {
|
_init() async {
|
||||||
await Future.delayed(const Duration(milliseconds: 100));
|
await Future.delayed(const Duration(milliseconds: 100));
|
||||||
await ref.read(updateMangaDetailProvider(mangaId: widget.mangaId, isInit: true).future);
|
await ref.read(
|
||||||
|
updateMangaDetailProvider(mangaId: widget.mangaId, isInit: true)
|
||||||
|
.future);
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_isLoading = false;
|
_isLoading = false;
|
||||||
|
|
@ -37,7 +39,8 @@ class _MangaReaderDetailState extends ConsumerState<MangaReaderDetail> {
|
||||||
bool _isLoading = true;
|
bool _isLoading = true;
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final manga = ref.watch(getMangaDetailStreamProvider(mangaId: widget.mangaId));
|
final manga =
|
||||||
|
ref.watch(getMangaDetailStreamProvider(mangaId: widget.mangaId));
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
body: manga.when(
|
body: manga.when(
|
||||||
data: (manga) {
|
data: (manga) {
|
||||||
|
|
@ -59,7 +62,9 @@ class _MangaReaderDetailState extends ConsumerState<MangaReaderDetail> {
|
||||||
return RefreshIndicator(
|
return RefreshIndicator(
|
||||||
onRefresh: () async {
|
onRefresh: () async {
|
||||||
if (sourceExist && !_isLoading) {
|
if (sourceExist && !_isLoading) {
|
||||||
await ref.read(updateMangaDetailProvider(mangaId: manga.id, isInit: false).future);
|
await ref.read(updateMangaDetailProvider(
|
||||||
|
mangaId: manga.id, isInit: false)
|
||||||
|
.future);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: Stack(
|
child: Stack(
|
||||||
|
|
@ -73,7 +78,9 @@ class _MangaReaderDetailState extends ConsumerState<MangaReaderDetail> {
|
||||||
_isLoading = true;
|
_isLoading = true;
|
||||||
});
|
});
|
||||||
if (sourceExist) {
|
if (sourceExist) {
|
||||||
await ref.read(updateMangaDetailProvider(mangaId: manga.id, isInit: false).future);
|
await ref.read(updateMangaDetailProvider(
|
||||||
|
mangaId: manga.id, isInit: false)
|
||||||
|
.future);
|
||||||
}
|
}
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
setState(() {
|
setState(() {
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import 'package:flutter/rendering.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:isar/isar.dart';
|
import 'package:isar/isar.dart';
|
||||||
import 'package:mangayomi/eval/dart/model/m_bridge.dart';
|
import 'package:mangayomi/eval/model/m_bridge.dart';
|
||||||
import 'package:mangayomi/main.dart';
|
import 'package:mangayomi/main.dart';
|
||||||
import 'package:mangayomi/models/chapter.dart';
|
import 'package:mangayomi/models/chapter.dart';
|
||||||
import 'package:mangayomi/models/download.dart';
|
import 'package:mangayomi/models/download.dart';
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,8 @@ class _MangaDetailsViewState extends ConsumerState<MangaDetailsView> {
|
||||||
return textPainter.size;
|
return textPainter.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
double calculateDynamicButtonWidth(String text, TextStyle textStyle, double padding) {
|
double calculateDynamicButtonWidth(
|
||||||
|
String text, TextStyle textStyle, double padding) {
|
||||||
final textSize = measureText(text, textStyle);
|
final textSize = measureText(text, textStyle);
|
||||||
return textSize.width + padding;
|
return textSize.width + padding;
|
||||||
}
|
}
|
||||||
|
|
@ -57,20 +58,28 @@ class _MangaDetailsViewState extends ConsumerState<MangaDetailsView> {
|
||||||
final isExtended = ref.watch(isExtendedStateProvider);
|
final isExtended = ref.watch(isExtendedStateProvider);
|
||||||
return ref.watch(isLongPressedStateProvider) == true
|
return ref.watch(isLongPressedStateProvider) == true
|
||||||
? Container()
|
? Container()
|
||||||
: chaptersList.isNotEmpty && chaptersList.where((element) => !element.isRead!).toList().isNotEmpty
|
: chaptersList.isNotEmpty &&
|
||||||
|
chaptersList
|
||||||
|
.where((element) => !element.isRead!)
|
||||||
|
.toList()
|
||||||
|
.isNotEmpty
|
||||||
? StreamBuilder(
|
? StreamBuilder(
|
||||||
stream: isar.historys
|
stream: isar.historys
|
||||||
.filter()
|
.filter()
|
||||||
.idIsNotNull()
|
.idIsNotNull()
|
||||||
.and()
|
.and()
|
||||||
.chapter((q) => q.manga((q) => q.isMangaEqualTo(widget.manga.isManga!)))
|
.chapter((q) => q.manga(
|
||||||
|
(q) => q.isMangaEqualTo(widget.manga.isManga!)))
|
||||||
.watch(fireImmediately: true),
|
.watch(fireImmediately: true),
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
String buttonLabel = widget.manga.isManga! ? l10n.read : l10n.watch;
|
String buttonLabel =
|
||||||
|
widget.manga.isManga! ? l10n.read : l10n.watch;
|
||||||
if (snapshot.hasData && snapshot.data!.isNotEmpty) {
|
if (snapshot.hasData && snapshot.data!.isNotEmpty) {
|
||||||
final incognitoMode = ref.watch(incognitoModeStateProvider);
|
final incognitoMode =
|
||||||
|
ref.watch(incognitoModeStateProvider);
|
||||||
final entries = snapshot.data!
|
final entries = snapshot.data!
|
||||||
.where((element) => element.mangaId == widget.manga.id)
|
.where((element) =>
|
||||||
|
element.mangaId == widget.manga.id)
|
||||||
.toList()
|
.toList()
|
||||||
.reversed
|
.reversed
|
||||||
.toList();
|
.toList();
|
||||||
|
|
@ -83,8 +92,12 @@ class _MangaDetailsViewState extends ConsumerState<MangaDetailsView> {
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
chap.pushToReaderView(context);
|
chap.pushToReaderView(context);
|
||||||
},
|
},
|
||||||
textWidth: measureText(l10n.resume, Theme.of(context).textTheme.labelLarge!).width,
|
textWidth: measureText(l10n.resume,
|
||||||
width: calculateDynamicButtonWidth(l10n.resume, Theme.of(context).textTheme.labelLarge!,
|
Theme.of(context).textTheme.labelLarge!)
|
||||||
|
.width,
|
||||||
|
width: calculateDynamicButtonWidth(
|
||||||
|
l10n.resume,
|
||||||
|
Theme.of(context).textTheme.labelLarge!,
|
||||||
50), // 50 Padding, else RenderFlex overflow Exception
|
50), // 50 Padding, else RenderFlex overflow Exception
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -92,10 +105,19 @@ class _MangaDetailsViewState extends ConsumerState<MangaDetailsView> {
|
||||||
isExtended: !isExtended,
|
isExtended: !isExtended,
|
||||||
label: buttonLabel,
|
label: buttonLabel,
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
widget.manga.chapters.toList().reversed.toList().last.pushToReaderView(context);
|
widget.manga.chapters
|
||||||
|
.toList()
|
||||||
|
.reversed
|
||||||
|
.toList()
|
||||||
|
.last
|
||||||
|
.pushToReaderView(context);
|
||||||
},
|
},
|
||||||
textWidth: measureText(buttonLabel, Theme.of(context).textTheme.labelLarge!).width,
|
textWidth: measureText(buttonLabel,
|
||||||
width: calculateDynamicButtonWidth(buttonLabel, Theme.of(context).textTheme.labelLarge!,
|
Theme.of(context).textTheme.labelLarge!)
|
||||||
|
.width,
|
||||||
|
width: calculateDynamicButtonWidth(
|
||||||
|
buttonLabel,
|
||||||
|
Theme.of(context).textTheme.labelLarge!,
|
||||||
50), // 50 Padding, else RenderFlex overflow Exception
|
50), // 50 Padding, else RenderFlex overflow Exception
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -103,10 +125,19 @@ class _MangaDetailsViewState extends ConsumerState<MangaDetailsView> {
|
||||||
isExtended: !isExtended,
|
isExtended: !isExtended,
|
||||||
label: buttonLabel,
|
label: buttonLabel,
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
widget.manga.chapters.toList().reversed.toList().last.pushToReaderView(context);
|
widget.manga.chapters
|
||||||
|
.toList()
|
||||||
|
.reversed
|
||||||
|
.toList()
|
||||||
|
.last
|
||||||
|
.pushToReaderView(context);
|
||||||
},
|
},
|
||||||
textWidth: measureText(buttonLabel, Theme.of(context).textTheme.labelLarge!).width,
|
textWidth: measureText(buttonLabel,
|
||||||
width: calculateDynamicButtonWidth(buttonLabel, Theme.of(context).textTheme.labelLarge!,
|
Theme.of(context).textTheme.labelLarge!)
|
||||||
|
.width,
|
||||||
|
width: calculateDynamicButtonWidth(
|
||||||
|
buttonLabel,
|
||||||
|
Theme.of(context).textTheme.labelLarge!,
|
||||||
50), // 50 Padding, else RenderFlex overflow Exception
|
50), // 50 Padding, else RenderFlex overflow Exception
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
@ -155,7 +186,9 @@ class _MangaDetailsViewState extends ConsumerState<MangaDetailsView> {
|
||||||
? SizedBox(
|
? SizedBox(
|
||||||
child: ElevatedButton(
|
child: ElevatedButton(
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
backgroundColor: Theme.of(context).scaffoldBackgroundColor, elevation: 0),
|
backgroundColor:
|
||||||
|
Theme.of(context).scaffoldBackgroundColor,
|
||||||
|
elevation: 0),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
final model = widget.manga;
|
final model = widget.manga;
|
||||||
isar.writeTxnSync(() {
|
isar.writeTxnSync(() {
|
||||||
|
|
@ -183,8 +216,9 @@ class _MangaDetailsViewState extends ConsumerState<MangaDetailsView> {
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
: ElevatedButton(
|
: ElevatedButton(
|
||||||
style:
|
style: ElevatedButton.styleFrom(
|
||||||
ElevatedButton.styleFrom(backgroundColor: Theme.of(context).scaffoldBackgroundColor, elevation: 0),
|
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
|
||||||
|
elevation: 0),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
final checkCategoryList = isar.categorys
|
final checkCategoryList = isar.categorys
|
||||||
.filter()
|
.filter()
|
||||||
|
|
@ -215,7 +249,8 @@ class _MangaDetailsViewState extends ConsumerState<MangaDetailsView> {
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
l10n.add_to_library,
|
l10n.add_to_library,
|
||||||
style: TextStyle(color: context.secondaryColor, fontSize: 11),
|
style: TextStyle(
|
||||||
|
color: context.secondaryColor, fontSize: 11),
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
|
|
@ -264,14 +299,17 @@ class _MangaDetailsViewState extends ConsumerState<MangaDetailsView> {
|
||||||
label: entries[index].name!,
|
label: entries[index].name!,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
setState(() {
|
setState(() {
|
||||||
if (categoryIds.contains(entries[index].id)) {
|
if (categoryIds
|
||||||
|
.contains(entries[index].id)) {
|
||||||
categoryIds.remove(entries[index].id);
|
categoryIds.remove(entries[index].id);
|
||||||
} else {
|
} else {
|
||||||
categoryIds.add(entries[index].id!);
|
categoryIds.add(entries[index].id!);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
type: categoryIds.contains(entries[index].id) ? 1 : 0,
|
type: categoryIds.contains(entries[index].id)
|
||||||
|
? 1
|
||||||
|
: 0,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
@ -285,7 +323,8 @@ class _MangaDetailsViewState extends ConsumerState<MangaDetailsView> {
|
||||||
children: [
|
children: [
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
context.push("/categories", extra: (true, widget.manga.isManga! ? 0 : 1));
|
context.push("/categories",
|
||||||
|
extra: (true, widget.manga.isManga! ? 0 : 1));
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
},
|
},
|
||||||
child: Text(l10n.edit)),
|
child: Text(l10n.edit)),
|
||||||
|
|
@ -305,7 +344,8 @@ class _MangaDetailsViewState extends ConsumerState<MangaDetailsView> {
|
||||||
isar.writeTxnSync(() {
|
isar.writeTxnSync(() {
|
||||||
model.favorite = true;
|
model.favorite = true;
|
||||||
model.categories = categoryIds;
|
model.categories = categoryIds;
|
||||||
model.dateAdded = DateTime.now().millisecondsSinceEpoch;
|
model.dateAdded =
|
||||||
|
DateTime.now().millisecondsSinceEpoch;
|
||||||
isar.mangas.putSync(model);
|
isar.mangas.putSync(model);
|
||||||
});
|
});
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
|
|
|
||||||
|
|
@ -16,5 +16,8 @@ Stream<List<Chapter>> getChaptersStream(
|
||||||
Ref ref, {
|
Ref ref, {
|
||||||
required int mangaId,
|
required int mangaId,
|
||||||
}) async* {
|
}) async* {
|
||||||
yield* isar.chapters.filter().manga((q) => q.idEqualTo(mangaId)).watch(fireImmediately: true);
|
yield* isar.chapters
|
||||||
|
.filter()
|
||||||
|
.manga((q) => q.idEqualTo(mangaId))
|
||||||
|
.watch(fireImmediately: true);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -159,7 +159,8 @@ class ChapterFilterDownloadedState extends _$ChapterFilterDownloadedState {
|
||||||
}
|
}
|
||||||
chapterFilterDownloadedList.add(value);
|
chapterFilterDownloadedList.add(value);
|
||||||
isar.writeTxnSync(() {
|
isar.writeTxnSync(() {
|
||||||
isar.settings.putSync(settings..chapterFilterDownloadedList = chapterFilterDownloadedList);
|
isar.settings.putSync(
|
||||||
|
settings..chapterFilterDownloadedList = chapterFilterDownloadedList);
|
||||||
});
|
});
|
||||||
|
|
||||||
state = type;
|
state = type;
|
||||||
|
|
@ -211,7 +212,8 @@ class ChapterFilterUnreadState extends _$ChapterFilterUnreadState {
|
||||||
}
|
}
|
||||||
chapterFilterUnreadList.add(value);
|
chapterFilterUnreadList.add(value);
|
||||||
isar.writeTxnSync(() {
|
isar.writeTxnSync(() {
|
||||||
isar.settings.putSync(settings..chapterFilterUnreadList = chapterFilterUnreadList);
|
isar.settings
|
||||||
|
.putSync(settings..chapterFilterUnreadList = chapterFilterUnreadList);
|
||||||
});
|
});
|
||||||
state = type;
|
state = type;
|
||||||
}
|
}
|
||||||
|
|
@ -262,7 +264,8 @@ class ChapterFilterBookmarkedState extends _$ChapterFilterBookmarkedState {
|
||||||
}
|
}
|
||||||
chapterFilterBookmarkedList.add(value);
|
chapterFilterBookmarkedList.add(value);
|
||||||
isar.writeTxnSync(() {
|
isar.writeTxnSync(() {
|
||||||
isar.settings.putSync(settings..chapterFilterBookmarkedList = chapterFilterBookmarkedList);
|
isar.settings.putSync(
|
||||||
|
settings..chapterFilterBookmarkedList = chapterFilterBookmarkedList);
|
||||||
});
|
});
|
||||||
state = type;
|
state = type;
|
||||||
}
|
}
|
||||||
|
|
@ -282,12 +285,18 @@ class ChapterFilterBookmarkedState extends _$ChapterFilterBookmarkedState {
|
||||||
class ChapterFilterResultState extends _$ChapterFilterResultState {
|
class ChapterFilterResultState extends _$ChapterFilterResultState {
|
||||||
@override
|
@override
|
||||||
bool build({required Manga manga}) {
|
bool build({required Manga manga}) {
|
||||||
final downloadFilterType = ref.watch(chapterFilterDownloadedStateProvider(mangaId: manga.id!));
|
final downloadFilterType =
|
||||||
final unreadFilterType = ref.watch(chapterFilterUnreadStateProvider(mangaId: manga.id!));
|
ref.watch(chapterFilterDownloadedStateProvider(mangaId: manga.id!));
|
||||||
|
final unreadFilterType =
|
||||||
|
ref.watch(chapterFilterUnreadStateProvider(mangaId: manga.id!));
|
||||||
|
|
||||||
final bookmarkedFilterType = ref.watch(chapterFilterBookmarkedStateProvider(mangaId: manga.id!));
|
final bookmarkedFilterType =
|
||||||
|
ref.watch(chapterFilterBookmarkedStateProvider(mangaId: manga.id!));
|
||||||
final scanlators = ref.watch(scanlatorsFilterStateProvider(manga));
|
final scanlators = ref.watch(scanlatorsFilterStateProvider(manga));
|
||||||
return downloadFilterType == 0 && unreadFilterType == 0 && bookmarkedFilterType == 0 && scanlators.$2.isEmpty;
|
return downloadFilterType == 0 &&
|
||||||
|
unreadFilterType == 0 &&
|
||||||
|
bookmarkedFilterType == 0 &&
|
||||||
|
scanlators.$2.isEmpty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -301,7 +310,9 @@ class ChapterSetIsBookmarkState extends _$ChapterSetIsBookmarkState {
|
||||||
isar.writeTxnSync(() {
|
isar.writeTxnSync(() {
|
||||||
for (var chapter in chapters) {
|
for (var chapter in chapters) {
|
||||||
chapter.isBookmarked = !chapter.isBookmarked!;
|
chapter.isBookmarked = !chapter.isBookmarked!;
|
||||||
ref.read(changedItemsManagerProvider(managerId: 1).notifier).addUpdatedChapter(chapter, false, false);
|
ref
|
||||||
|
.read(changedItemsManagerProvider(managerId: 1).notifier)
|
||||||
|
.addUpdatedChapter(chapter, false, false);
|
||||||
isar.chapters.putSync(chapter..manga.value = manga);
|
isar.chapters.putSync(chapter..manga.value = manga);
|
||||||
chapter.manga.saveSync();
|
chapter.manga.saveSync();
|
||||||
}
|
}
|
||||||
|
|
@ -321,7 +332,9 @@ class ChapterSetIsReadState extends _$ChapterSetIsReadState {
|
||||||
isar.writeTxnSync(() {
|
isar.writeTxnSync(() {
|
||||||
for (var chapter in chapters) {
|
for (var chapter in chapters) {
|
||||||
chapter.isRead = !chapter.isRead!;
|
chapter.isRead = !chapter.isRead!;
|
||||||
ref.read(changedItemsManagerProvider(managerId: 1).notifier).addUpdatedChapter(chapter, false, false);
|
ref
|
||||||
|
.read(changedItemsManagerProvider(managerId: 1).notifier)
|
||||||
|
.addUpdatedChapter(chapter, false, false);
|
||||||
isar.chapters.putSync(chapter..manga.value = manga);
|
isar.chapters.putSync(chapter..manga.value = manga);
|
||||||
chapter.manga.saveSync();
|
chapter.manga.saveSync();
|
||||||
}
|
}
|
||||||
|
|
@ -340,7 +353,11 @@ class ChapterSetDownloadState extends _$ChapterSetDownloadState {
|
||||||
ref.read(isLongPressedStateProvider.notifier).update(false);
|
ref.read(isLongPressedStateProvider.notifier).update(false);
|
||||||
isar.txnSync(() {
|
isar.txnSync(() {
|
||||||
for (var chapter in ref.watch(chaptersListStateProvider)) {
|
for (var chapter in ref.watch(chaptersListStateProvider)) {
|
||||||
final entries = isar.downloads.filter().idIsNotNull().chapterIdEqualTo(chapter.id).findAllSync();
|
final entries = isar.downloads
|
||||||
|
.filter()
|
||||||
|
.idIsNotNull()
|
||||||
|
.chapterIdEqualTo(chapter.id)
|
||||||
|
.findAllSync();
|
||||||
if (entries.isEmpty || !entries.first.isDownload!) {
|
if (entries.isEmpty || !entries.first.isDownload!) {
|
||||||
ref.watch(downloadChapterProvider(chapter: chapter));
|
ref.watch(downloadChapterProvider(chapter: chapter));
|
||||||
}
|
}
|
||||||
|
|
@ -378,7 +395,8 @@ class ScanlatorsFilterState extends _$ScanlatorsFilterState {
|
||||||
List<String> _getScanlators() {
|
List<String> _getScanlators() {
|
||||||
List<String> scanlators = [];
|
List<String> scanlators = [];
|
||||||
for (var a in manga.chapters.toList()) {
|
for (var a in manga.chapters.toList()) {
|
||||||
if ((a.scanlator?.isNotEmpty ?? false) && !scanlators.contains(a.scanlator)) {
|
if ((a.scanlator?.isNotEmpty ?? false) &&
|
||||||
|
!scanlators.contains(a.scanlator)) {
|
||||||
scanlators.add(a.scanlator!);
|
scanlators.add(a.scanlator!);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -399,14 +417,16 @@ class ScanlatorsFilterState extends _$ScanlatorsFilterState {
|
||||||
}
|
}
|
||||||
filterScanlatorList.add(value);
|
filterScanlatorList.add(value);
|
||||||
isar.writeTxnSync(() {
|
isar.writeTxnSync(() {
|
||||||
isar.settings.putSync(settings..filterScanlatorList = filterScanlatorList);
|
isar.settings
|
||||||
|
.putSync(settings..filterScanlatorList = filterScanlatorList);
|
||||||
});
|
});
|
||||||
state = (_getScanlators(), _getFilterScanlator()!, filterScanlators);
|
state = (_getScanlators(), _getFilterScanlator()!, filterScanlators);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<String>? _getFilterScanlator() {
|
List<String>? _getFilterScanlator() {
|
||||||
final scanlators = isar.settings.getSync(227)!.filterScanlatorList ?? [];
|
final scanlators = isar.settings.getSync(227)!.filterScanlatorList ?? [];
|
||||||
final filter = scanlators.where((element) => element.mangaId == manga.id).toList();
|
final filter =
|
||||||
|
scanlators.where((element) => element.mangaId == manga.id).toList();
|
||||||
return filter.isEmpty ? null : filter.first.scanlators;
|
return filter.isEmpty ? null : filter.first.scanlators;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -421,6 +441,7 @@ class ScanlatorsFilterState extends _$ScanlatorsFilterState {
|
||||||
} else {
|
} else {
|
||||||
scanlatorFilteredList.add(scanlator);
|
scanlatorFilteredList.add(scanlator);
|
||||||
}
|
}
|
||||||
state = (_getScanlators(), _getFilterScanlator() ?? [], scanlatorFilteredList);
|
state =
|
||||||
|
(_getScanlators(), _getFilterScanlator() ?? [], scanlatorFilteredList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,19 +18,41 @@ class TrackState extends _$TrackState {
|
||||||
Track? updateTrack;
|
Track? updateTrack;
|
||||||
if (track!.syncId == 1) {
|
if (track!.syncId == 1) {
|
||||||
updateTrack = isManga!
|
updateTrack = isManga!
|
||||||
? await ref.read(myAnimeListProvider(syncId: track!.syncId!, isManga: isManga).notifier).updateManga(track!)
|
? await ref
|
||||||
: await ref.read(myAnimeListProvider(syncId: track!.syncId!, isManga: isManga).notifier).updateAnime(track!);
|
.read(
|
||||||
|
myAnimeListProvider(syncId: track!.syncId!, isManga: isManga)
|
||||||
|
.notifier)
|
||||||
|
.updateManga(track!)
|
||||||
|
: await ref
|
||||||
|
.read(
|
||||||
|
myAnimeListProvider(syncId: track!.syncId!, isManga: isManga)
|
||||||
|
.notifier)
|
||||||
|
.updateAnime(track!);
|
||||||
} else if (track!.syncId == 2) {
|
} else if (track!.syncId == 2) {
|
||||||
updateTrack = isManga!
|
updateTrack = isManga!
|
||||||
? await ref.read(anilistProvider(syncId: track!.syncId!, isManga: isManga).notifier).updateLibManga(track!)
|
? await ref
|
||||||
: await ref.read(anilistProvider(syncId: track!.syncId!, isManga: isManga).notifier).updateLibAnime(track!);
|
.read(anilistProvider(syncId: track!.syncId!, isManga: isManga)
|
||||||
|
.notifier)
|
||||||
|
.updateLibManga(track!)
|
||||||
|
: await ref
|
||||||
|
.read(anilistProvider(syncId: track!.syncId!, isManga: isManga)
|
||||||
|
.notifier)
|
||||||
|
.updateLibAnime(track!);
|
||||||
} else if (track!.syncId == 3) {
|
} else if (track!.syncId == 3) {
|
||||||
updateTrack = isManga!
|
updateTrack = isManga!
|
||||||
? await ref.read(kitsuProvider(syncId: track!.syncId!, isManga: isManga).notifier).updateLibManga(track!)
|
? await ref
|
||||||
: await ref.read(kitsuProvider(syncId: track!.syncId!, isManga: isManga).notifier).updateLibAnime(track!);
|
.read(kitsuProvider(syncId: track!.syncId!, isManga: isManga)
|
||||||
|
.notifier)
|
||||||
|
.updateLibManga(track!)
|
||||||
|
: await ref
|
||||||
|
.read(kitsuProvider(syncId: track!.syncId!, isManga: isManga)
|
||||||
|
.notifier)
|
||||||
|
.updateLibAnime(track!);
|
||||||
}
|
}
|
||||||
|
|
||||||
ref.read(tracksProvider(syncId: track!.syncId!).notifier).updateTrackManga(updateTrack!, isManga);
|
ref
|
||||||
|
.read(tracksProvider(syncId: track!.syncId!).notifier)
|
||||||
|
.updateTrackManga(updateTrack!, isManga);
|
||||||
}
|
}
|
||||||
|
|
||||||
int getScoreMaxValue() {
|
int getScoreMaxValue() {
|
||||||
|
|
@ -38,7 +60,11 @@ class TrackState extends _$TrackState {
|
||||||
if (track!.syncId == 1 || track!.syncId == 3) {
|
if (track!.syncId == 1 || track!.syncId == 3) {
|
||||||
maxValue = 10;
|
maxValue = 10;
|
||||||
} else if (track!.syncId == 2) {
|
} else if (track!.syncId == 2) {
|
||||||
maxValue = ref.read(anilistProvider(syncId: track!.syncId!, isManga: isManga).notifier).getScoreValue().$1;
|
maxValue = ref
|
||||||
|
.read(anilistProvider(syncId: track!.syncId!, isManga: isManga)
|
||||||
|
.notifier)
|
||||||
|
.getScoreValue()
|
||||||
|
.$1;
|
||||||
}
|
}
|
||||||
return maxValue!;
|
return maxValue!;
|
||||||
}
|
}
|
||||||
|
|
@ -46,7 +72,9 @@ class TrackState extends _$TrackState {
|
||||||
String getTextMapper(String numberText) {
|
String getTextMapper(String numberText) {
|
||||||
if (track!.syncId == 1 || track!.syncId == 3) {
|
if (track!.syncId == 1 || track!.syncId == 3) {
|
||||||
} else if (track!.syncId == 2) {
|
} else if (track!.syncId == 2) {
|
||||||
numberText = ref.read(anilistProvider(syncId: 2, isManga: isManga).notifier).displayScore(int.parse(numberText));
|
numberText = ref
|
||||||
|
.read(anilistProvider(syncId: 2, isManga: isManga).notifier)
|
||||||
|
.displayScore(int.parse(numberText));
|
||||||
}
|
}
|
||||||
return numberText;
|
return numberText;
|
||||||
}
|
}
|
||||||
|
|
@ -56,7 +84,11 @@ class TrackState extends _$TrackState {
|
||||||
if (track!.syncId == 1 || track!.syncId == 3) {
|
if (track!.syncId == 1 || track!.syncId == 3) {
|
||||||
step = 1;
|
step = 1;
|
||||||
} else if (track!.syncId == 2) {
|
} else if (track!.syncId == 2) {
|
||||||
step = ref.read(anilistProvider(syncId: track!.syncId!, isManga: isManga).notifier).getScoreValue().$2;
|
step = ref
|
||||||
|
.read(anilistProvider(syncId: track!.syncId!, isManga: isManga)
|
||||||
|
.notifier)
|
||||||
|
.getScoreValue()
|
||||||
|
.$2;
|
||||||
}
|
}
|
||||||
return step!;
|
return step!;
|
||||||
}
|
}
|
||||||
|
|
@ -66,12 +98,15 @@ class TrackState extends _$TrackState {
|
||||||
if (track!.syncId == 1 || track!.syncId == 3) {
|
if (track!.syncId == 1 || track!.syncId == 3) {
|
||||||
result = score.toString();
|
result = score.toString();
|
||||||
} else if (track!.syncId == 2) {
|
} else if (track!.syncId == 2) {
|
||||||
result = ref.read(anilistProvider(syncId: 2, isManga: isManga).notifier).displayScore(score);
|
result = ref
|
||||||
|
.read(anilistProvider(syncId: 2, isManga: isManga).notifier)
|
||||||
|
.displayScore(score);
|
||||||
}
|
}
|
||||||
return result!;
|
return result!;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future setTrackSearch(TrackSearch trackSearch, int mangaId, int syncId) async {
|
Future setTrackSearch(
|
||||||
|
TrackSearch trackSearch, int mangaId, int syncId) async {
|
||||||
Track? findManga;
|
Track? findManga;
|
||||||
final track = Track(
|
final track = Track(
|
||||||
mangaId: mangaId,
|
mangaId: mangaId,
|
||||||
|
|
@ -86,20 +121,36 @@ class TrackState extends _$TrackState {
|
||||||
startedReadingDate: 0,
|
startedReadingDate: 0,
|
||||||
finishedReadingDate: 0);
|
finishedReadingDate: 0);
|
||||||
if (syncId == 1) {
|
if (syncId == 1) {
|
||||||
findManga = await ref.read(myAnimeListProvider(syncId: syncId, isManga: isManga).notifier).findManga(track);
|
findManga = await ref
|
||||||
|
.read(myAnimeListProvider(syncId: syncId, isManga: isManga).notifier)
|
||||||
|
.findManga(track);
|
||||||
} else if (syncId == 2) {
|
} else if (syncId == 2) {
|
||||||
findManga = isManga!
|
findManga = isManga!
|
||||||
? await ref.read(anilistProvider(syncId: syncId, isManga: isManga).notifier).findLibManga(track)
|
? await ref
|
||||||
: await ref.read(anilistProvider(syncId: syncId, isManga: isManga).notifier).findLibAnime(track);
|
.read(anilistProvider(syncId: syncId, isManga: isManga).notifier)
|
||||||
|
.findLibManga(track)
|
||||||
|
: await ref
|
||||||
|
.read(anilistProvider(syncId: syncId, isManga: isManga).notifier)
|
||||||
|
.findLibAnime(track);
|
||||||
findManga ??= isManga!
|
findManga ??= isManga!
|
||||||
? await ref.read(anilistProvider(syncId: syncId, isManga: isManga).notifier).addLibManga(track)
|
? await ref
|
||||||
: await ref.read(anilistProvider(syncId: syncId, isManga: isManga).notifier).addLibAnime(track);
|
.read(anilistProvider(syncId: syncId, isManga: isManga).notifier)
|
||||||
|
.addLibManga(track)
|
||||||
|
: await ref
|
||||||
|
.read(anilistProvider(syncId: syncId, isManga: isManga).notifier)
|
||||||
|
.addLibAnime(track);
|
||||||
} else if (syncId == 3) {
|
} else if (syncId == 3) {
|
||||||
findManga = isManga!
|
findManga = isManga!
|
||||||
? await ref.read(kitsuProvider(syncId: syncId, isManga: isManga).notifier).addLibManga(track)
|
? await ref
|
||||||
: await ref.read(kitsuProvider(syncId: syncId, isManga: isManga).notifier).addLibAnime(track);
|
.read(kitsuProvider(syncId: syncId, isManga: isManga).notifier)
|
||||||
|
.addLibManga(track)
|
||||||
|
: await ref
|
||||||
|
.read(kitsuProvider(syncId: syncId, isManga: isManga).notifier)
|
||||||
|
.addLibAnime(track);
|
||||||
}
|
}
|
||||||
ref.read(tracksProvider(syncId: syncId).notifier).updateTrackManga(findManga!, isManga);
|
ref
|
||||||
|
.read(tracksProvider(syncId: syncId).notifier)
|
||||||
|
.updateTrackManga(findManga!, isManga);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<TrackStatus> getStatusList() {
|
List<TrackStatus> getStatusList() {
|
||||||
|
|
@ -107,16 +158,36 @@ class TrackState extends _$TrackState {
|
||||||
List<TrackStatus> list = [];
|
List<TrackStatus> list = [];
|
||||||
if (track!.syncId == 1) {
|
if (track!.syncId == 1) {
|
||||||
statusList = isManga!
|
statusList = isManga!
|
||||||
? ref.read(myAnimeListProvider(syncId: track!.syncId!, isManga: isManga).notifier).myAnimeListStatusListManga
|
? ref
|
||||||
: ref.read(myAnimeListProvider(syncId: track!.syncId!, isManga: isManga).notifier).myAnimeListStatusListAnime;
|
.read(
|
||||||
|
myAnimeListProvider(syncId: track!.syncId!, isManga: isManga)
|
||||||
|
.notifier)
|
||||||
|
.myAnimeListStatusListManga
|
||||||
|
: ref
|
||||||
|
.read(
|
||||||
|
myAnimeListProvider(syncId: track!.syncId!, isManga: isManga)
|
||||||
|
.notifier)
|
||||||
|
.myAnimeListStatusListAnime;
|
||||||
} else if (track!.syncId == 2) {
|
} else if (track!.syncId == 2) {
|
||||||
statusList = isManga!
|
statusList = isManga!
|
||||||
? ref.read(anilistProvider(syncId: track!.syncId!, isManga: isManga).notifier).aniListStatusListManga
|
? ref
|
||||||
: ref.read(anilistProvider(syncId: track!.syncId!, isManga: isManga).notifier).aniListStatusListAnime;
|
.read(anilistProvider(syncId: track!.syncId!, isManga: isManga)
|
||||||
|
.notifier)
|
||||||
|
.aniListStatusListManga
|
||||||
|
: ref
|
||||||
|
.read(anilistProvider(syncId: track!.syncId!, isManga: isManga)
|
||||||
|
.notifier)
|
||||||
|
.aniListStatusListAnime;
|
||||||
} else if (track!.syncId == 3) {
|
} else if (track!.syncId == 3) {
|
||||||
statusList = isManga!
|
statusList = isManga!
|
||||||
? ref.read(kitsuProvider(syncId: track!.syncId!, isManga: isManga).notifier).kitsuStatusListManga
|
? ref
|
||||||
: ref.read(kitsuProvider(syncId: track!.syncId!, isManga: isManga).notifier).kitsuStatusListAnime;
|
.read(kitsuProvider(syncId: track!.syncId!, isManga: isManga)
|
||||||
|
.notifier)
|
||||||
|
.kitsuStatusListManga
|
||||||
|
: ref
|
||||||
|
.read(kitsuProvider(syncId: track!.syncId!, isManga: isManga)
|
||||||
|
.notifier)
|
||||||
|
.kitsuStatusListAnime;
|
||||||
}
|
}
|
||||||
for (var element in TrackStatus.values) {
|
for (var element in TrackStatus.values) {
|
||||||
if (statusList.contains(element)) {
|
if (statusList.contains(element)) {
|
||||||
|
|
@ -129,16 +200,30 @@ class TrackState extends _$TrackState {
|
||||||
Future<Track?> findManga() async {
|
Future<Track?> findManga() async {
|
||||||
Track? findManga;
|
Track? findManga;
|
||||||
if (track!.syncId == 1) {
|
if (track!.syncId == 1) {
|
||||||
findManga =
|
findManga = await ref
|
||||||
await ref.read(myAnimeListProvider(syncId: track!.syncId!, isManga: isManga).notifier).findManga(track!);
|
.read(myAnimeListProvider(syncId: track!.syncId!, isManga: isManga)
|
||||||
|
.notifier)
|
||||||
|
.findManga(track!);
|
||||||
} else if (track!.syncId == 2) {
|
} else if (track!.syncId == 2) {
|
||||||
findManga = isManga!
|
findManga = isManga!
|
||||||
? await ref.read(anilistProvider(syncId: track!.syncId!, isManga: isManga).notifier).findLibManga(track!)
|
? await ref
|
||||||
: await ref.read(anilistProvider(syncId: track!.syncId!, isManga: isManga).notifier).findLibAnime(track!);
|
.read(anilistProvider(syncId: track!.syncId!, isManga: isManga)
|
||||||
|
.notifier)
|
||||||
|
.findLibManga(track!)
|
||||||
|
: await ref
|
||||||
|
.read(anilistProvider(syncId: track!.syncId!, isManga: isManga)
|
||||||
|
.notifier)
|
||||||
|
.findLibAnime(track!);
|
||||||
} else if (track!.syncId == 3) {
|
} else if (track!.syncId == 3) {
|
||||||
findManga = isManga!
|
findManga = isManga!
|
||||||
? await ref.read(kitsuProvider(syncId: track!.syncId!, isManga: isManga).notifier).findLibManga(track!)
|
? await ref
|
||||||
: await ref.read(kitsuProvider(syncId: track!.syncId!, isManga: isManga).notifier).findLibAnime(track!);
|
.read(kitsuProvider(syncId: track!.syncId!, isManga: isManga)
|
||||||
|
.notifier)
|
||||||
|
.findLibManga(track!)
|
||||||
|
: await ref
|
||||||
|
.read(kitsuProvider(syncId: track!.syncId!, isManga: isManga)
|
||||||
|
.notifier)
|
||||||
|
.findLibAnime(track!);
|
||||||
}
|
}
|
||||||
return findManga;
|
return findManga;
|
||||||
}
|
}
|
||||||
|
|
@ -146,15 +231,30 @@ class TrackState extends _$TrackState {
|
||||||
Future<List<TrackSearch>?> search(String query) async {
|
Future<List<TrackSearch>?> search(String query) async {
|
||||||
List<TrackSearch>? tracks;
|
List<TrackSearch>? tracks;
|
||||||
if (track!.syncId == 1) {
|
if (track!.syncId == 1) {
|
||||||
tracks = await ref.read(myAnimeListProvider(syncId: track!.syncId!, isManga: isManga).notifier).search(query);
|
tracks = await ref
|
||||||
|
.read(myAnimeListProvider(syncId: track!.syncId!, isManga: isManga)
|
||||||
|
.notifier)
|
||||||
|
.search(query);
|
||||||
} else if (track!.syncId == 2) {
|
} else if (track!.syncId == 2) {
|
||||||
tracks = isManga!
|
tracks = isManga!
|
||||||
? await ref.read(anilistProvider(syncId: track!.syncId!, isManga: isManga).notifier).search(query)
|
? await ref
|
||||||
: await ref.read(anilistProvider(syncId: track!.syncId!, isManga: isManga).notifier).searchAnime(query);
|
.read(anilistProvider(syncId: track!.syncId!, isManga: isManga)
|
||||||
|
.notifier)
|
||||||
|
.search(query)
|
||||||
|
: await ref
|
||||||
|
.read(anilistProvider(syncId: track!.syncId!, isManga: isManga)
|
||||||
|
.notifier)
|
||||||
|
.searchAnime(query);
|
||||||
} else if (track!.syncId == 3) {
|
} else if (track!.syncId == 3) {
|
||||||
tracks = isManga!
|
tracks = isManga!
|
||||||
? await ref.read(kitsuProvider(syncId: track!.syncId!, isManga: isManga).notifier).search(query)
|
? await ref
|
||||||
: await ref.read(kitsuProvider(syncId: track!.syncId!, isManga: isManga).notifier).searchAnime(query);
|
.read(kitsuProvider(syncId: track!.syncId!, isManga: isManga)
|
||||||
|
.notifier)
|
||||||
|
.search(query)
|
||||||
|
: await ref
|
||||||
|
.read(kitsuProvider(syncId: track!.syncId!, isManga: isManga)
|
||||||
|
.notifier)
|
||||||
|
.searchAnime(query);
|
||||||
}
|
}
|
||||||
return tracks;
|
return tracks;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,8 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
part 'update_manga_detail_providers.g.dart';
|
part 'update_manga_detail_providers.g.dart';
|
||||||
|
|
||||||
@riverpod
|
@riverpod
|
||||||
Future<dynamic> updateMangaDetail(Ref ref, {required int? mangaId, required bool isInit}) async {
|
Future<dynamic> updateMangaDetail(Ref ref,
|
||||||
|
{required int? mangaId, required bool isInit}) async {
|
||||||
final manga = isar.mangas.getSync(mangaId!);
|
final manga = isar.mangas.getSync(mangaId!);
|
||||||
if (manga!.chapters.isNotEmpty && isInit) {
|
if (manga!.chapters.isNotEmpty && isInit) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -20,20 +21,31 @@ Future<dynamic> updateMangaDetail(Ref ref, {required int? mangaId, required bool
|
||||||
final source = getSource(manga.lang!, manga.source!);
|
final source = getSource(manga.lang!, manga.source!);
|
||||||
MManga getManga;
|
MManga getManga;
|
||||||
try {
|
try {
|
||||||
getManga = await ref.watch(getDetailProvider(url: manga.link!, source: source!).future);
|
getManga = await ref
|
||||||
|
.watch(getDetailProvider(url: manga.link!, source: source!).future);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
botToast(e.toString());
|
botToast(e.toString());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final genre = getManga.genre?.map((e) => e.toString().trim().trimLeft().trimRight()).toList().toSet().toList() ?? [];
|
final genre = getManga.genre
|
||||||
|
?.map((e) => e.toString().trim().trimLeft().trimRight())
|
||||||
|
.toList()
|
||||||
|
.toSet()
|
||||||
|
.toList() ??
|
||||||
|
[];
|
||||||
manga
|
manga
|
||||||
..imageUrl = getManga.imageUrl ?? manga.imageUrl
|
..imageUrl = getManga.imageUrl ?? manga.imageUrl
|
||||||
..name = getManga.name?.trim().trimLeft().trimRight() ?? manga.name
|
..name = getManga.name?.trim().trimLeft().trimRight() ?? manga.name
|
||||||
..genre = (genre.isEmpty ? null : genre) ?? manga.genre ?? []
|
..genre = (genre.isEmpty ? null : genre) ?? manga.genre ?? []
|
||||||
..author = getManga.author?.trim().trimLeft().trimRight() ?? manga.author ?? ""
|
..author =
|
||||||
..artist = getManga.artist?.trim().trimLeft().trimRight() ?? manga.artist ?? ""
|
getManga.author?.trim().trimLeft().trimRight() ?? manga.author ?? ""
|
||||||
..status = getManga.status == Status.unknown ? manga.status : getManga.status!
|
..artist =
|
||||||
..description = getManga.description?.trim().trimLeft().trimRight() ?? manga.description ?? ""
|
getManga.artist?.trim().trimLeft().trimRight() ?? manga.artist ?? ""
|
||||||
|
..status =
|
||||||
|
getManga.status == Status.unknown ? manga.status : getManga.status!
|
||||||
|
..description = getManga.description?.trim().trimLeft().trimRight() ??
|
||||||
|
manga.description ??
|
||||||
|
""
|
||||||
..link = getManga.link?.trim().trimLeft().trimRight() ?? manga.link
|
..link = getManga.link?.trim().trimLeft().trimRight() ?? manga.link
|
||||||
..source = manga.source
|
..source = manga.source
|
||||||
..lang = manga.lang
|
..lang = manga.lang
|
||||||
|
|
@ -68,19 +80,24 @@ Future<dynamic> updateMangaDetail(Ref ref, {required int? mangaId, required bool
|
||||||
}
|
}
|
||||||
if (chapters.isNotEmpty) {
|
if (chapters.isNotEmpty) {
|
||||||
for (var chap in chapters.reversed.toList()) {
|
for (var chap in chapters.reversed.toList()) {
|
||||||
ref.read(changedItemsManagerProvider(managerId: 1).notifier).addUpdatedChapter(chap, false, false);
|
ref
|
||||||
|
.read(changedItemsManagerProvider(managerId: 1).notifier)
|
||||||
|
.addUpdatedChapter(chap, false, false);
|
||||||
isar.chapters.putSync(chap);
|
isar.chapters.putSync(chap);
|
||||||
chap.manga.saveSync();
|
chap.manga.saveSync();
|
||||||
if (manga.chapters.isNotEmpty) {
|
if (manga.chapters.isNotEmpty) {
|
||||||
final update =
|
final update = Update(
|
||||||
Update(mangaId: mangaId, chapterName: chap.name, date: DateTime.now().millisecondsSinceEpoch.toString())
|
mangaId: mangaId,
|
||||||
..chapter.value = chap;
|
chapterName: chap.name,
|
||||||
|
date: DateTime.now().millisecondsSinceEpoch.toString())
|
||||||
|
..chapter.value = chap;
|
||||||
isar.updates.putSync(update);
|
isar.updates.putSync(update);
|
||||||
update.chapter.saveSync();
|
update.chapter.saveSync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
final oldChapers = isar.mangas.getSync(mangaId)!.chapters.toList().reversed.toList();
|
final oldChapers =
|
||||||
|
isar.mangas.getSync(mangaId)!.chapters.toList().reversed.toList();
|
||||||
if (oldChapers.length == chaps.length) {
|
if (oldChapers.length == chaps.length) {
|
||||||
for (var i = 0; i < oldChapers.length; i++) {
|
for (var i = 0; i < oldChapers.length; i++) {
|
||||||
final oldChap = oldChapers[i];
|
final oldChap = oldChapers[i];
|
||||||
|
|
@ -91,7 +108,9 @@ Future<dynamic> updateMangaDetail(Ref ref, {required int? mangaId, required bool
|
||||||
newChap.name == oldChap.name) {
|
newChap.name == oldChap.name) {
|
||||||
oldChap.url = newChap.url;
|
oldChap.url = newChap.url;
|
||||||
oldChap.scanlator = newChap.scanlator;
|
oldChap.scanlator = newChap.scanlator;
|
||||||
ref.read(changedItemsManagerProvider(managerId: 1).notifier).addUpdatedChapter(oldChap, false, false);
|
ref
|
||||||
|
.read(changedItemsManagerProvider(managerId: 1).notifier)
|
||||||
|
.addUpdatedChapter(oldChap, false, false);
|
||||||
isar.chapters.putSync(oldChap);
|
isar.chapters.putSync(oldChap);
|
||||||
oldChap.manga.saveSync();
|
oldChap.manga.saveSync();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,11 @@ class ListTileChapterFilter extends StatelessWidget {
|
||||||
final String label;
|
final String label;
|
||||||
final int type;
|
final int type;
|
||||||
final VoidCallback onTap;
|
final VoidCallback onTap;
|
||||||
const ListTileChapterFilter({super.key, required this.label, required this.type, required this.onTap});
|
const ListTileChapterFilter(
|
||||||
|
{super.key,
|
||||||
|
required this.label,
|
||||||
|
required this.type,
|
||||||
|
required this.onTap});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
|
|
||||||
|
|
@ -25,19 +25,25 @@ class ChapterListTileWidget extends ConsumerWidget {
|
||||||
final isLongPressed = ref.watch(isLongPressedStateProvider);
|
final isLongPressed = ref.watch(isLongPressedStateProvider);
|
||||||
final l10n = l10nLocalizations(context)!;
|
final l10n = l10nLocalizations(context)!;
|
||||||
return Container(
|
return Container(
|
||||||
color: chapterList.contains(chapter) ? context.primaryColor.withValues(alpha: 0.4) : null,
|
color: chapterList.contains(chapter)
|
||||||
|
? context.primaryColor.withValues(alpha: 0.4)
|
||||||
|
: null,
|
||||||
child: ListTile(
|
child: ListTile(
|
||||||
textColor: chapter.isRead!
|
textColor: chapter.isRead!
|
||||||
? context.isLight
|
? context.isLight
|
||||||
? Colors.black.withValues(alpha: 0.4)
|
? Colors.black.withValues(alpha: 0.4)
|
||||||
: Colors.white.withValues(alpha: 0.3)
|
: Colors.white.withValues(alpha: 0.3)
|
||||||
: null,
|
: null,
|
||||||
selectedColor: chapter.isRead! ? Colors.white.withValues(alpha: 0.3) : Colors.white,
|
selectedColor: chapter.isRead!
|
||||||
|
? Colors.white.withValues(alpha: 0.3)
|
||||||
|
: Colors.white,
|
||||||
onLongPress: () {
|
onLongPress: () {
|
||||||
if (!isLongPressed) {
|
if (!isLongPressed) {
|
||||||
ref.read(chaptersListStateProvider.notifier).update(chapter);
|
ref.read(chaptersListStateProvider.notifier).update(chapter);
|
||||||
|
|
||||||
ref.read(isLongPressedStateProvider.notifier).update(!isLongPressed);
|
ref
|
||||||
|
.read(isLongPressedStateProvider.notifier)
|
||||||
|
.update(!isLongPressed);
|
||||||
} else {
|
} else {
|
||||||
ref.read(chaptersListStateProvider.notifier).update(chapter);
|
ref.read(chaptersListStateProvider.notifier).update(chapter);
|
||||||
}
|
}
|
||||||
|
|
@ -73,18 +79,23 @@ class ChapterListTileWidget extends ConsumerWidget {
|
||||||
Text(
|
Text(
|
||||||
chapter.dateUpload == null || chapter.dateUpload!.isEmpty
|
chapter.dateUpload == null || chapter.dateUpload!.isEmpty
|
||||||
? ""
|
? ""
|
||||||
: dateFormat(chapter.dateUpload!, ref: ref, context: context),
|
: dateFormat(chapter.dateUpload!,
|
||||||
|
ref: ref, context: context),
|
||||||
style: const TextStyle(fontSize: 11),
|
style: const TextStyle(fontSize: 11),
|
||||||
),
|
),
|
||||||
if (!chapter.isRead!)
|
if (!chapter.isRead!)
|
||||||
if (chapter.lastPageRead!.isNotEmpty && chapter.lastPageRead != "1")
|
if (chapter.lastPageRead!.isNotEmpty &&
|
||||||
|
chapter.lastPageRead != "1")
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
const Text(' • '),
|
const Text(' • '),
|
||||||
Text(
|
Text(
|
||||||
!chapter.manga.value!.isManga!
|
!chapter.manga.value!.isManga!
|
||||||
? l10n.episode_progress(
|
? l10n.episode_progress(Duration(
|
||||||
Duration(milliseconds: int.parse(chapter.lastPageRead!)).toString().substringBefore("."))
|
milliseconds:
|
||||||
|
int.parse(chapter.lastPageRead!))
|
||||||
|
.toString()
|
||||||
|
.substringBefore("."))
|
||||||
: l10n.page(chapter.lastPageRead!),
|
: l10n.page(chapter.lastPageRead!),
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 11,
|
fontSize: 11,
|
||||||
|
|
|
||||||
|
|
@ -6,15 +6,22 @@ class ListTileChapterSort extends StatelessWidget {
|
||||||
final VoidCallback onTap;
|
final VoidCallback onTap;
|
||||||
final bool showLeading;
|
final bool showLeading;
|
||||||
const ListTileChapterSort(
|
const ListTileChapterSort(
|
||||||
{super.key, required this.label, required this.reverse, required this.onTap, required this.showLeading});
|
{super.key,
|
||||||
|
required this.label,
|
||||||
|
required this.reverse,
|
||||||
|
required this.onTap,
|
||||||
|
required this.showLeading});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return ListTile(
|
return ListTile(
|
||||||
iconColor: Theme.of(context).primaryColor,
|
iconColor: Theme.of(context).primaryColor,
|
||||||
dense: true,
|
dense: true,
|
||||||
leading: Icon(reverse ? Icons.arrow_downward_sharp : Icons.arrow_upward_sharp,
|
leading: Icon(
|
||||||
color: showLeading ? Theme.of(context).primaryColor : Colors.transparent),
|
reverse ? Icons.arrow_downward_sharp : Icons.arrow_upward_sharp,
|
||||||
|
color: showLeading
|
||||||
|
? Theme.of(context).primaryColor
|
||||||
|
: Colors.transparent),
|
||||||
title: Text(
|
title: Text(
|
||||||
label,
|
label,
|
||||||
style: const TextStyle(fontSize: 14),
|
style: const TextStyle(fontSize: 14),
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,8 @@ import 'package:mangayomi/providers/l10n_providers.dart';
|
||||||
import 'package:mangayomi/utils/extensions/build_context_extensions.dart';
|
import 'package:mangayomi/utils/extensions/build_context_extensions.dart';
|
||||||
|
|
||||||
class ReadMoreWidget extends StatefulWidget {
|
class ReadMoreWidget extends StatefulWidget {
|
||||||
const ReadMoreWidget({super.key, required this.text, required this.onChanged});
|
const ReadMoreWidget(
|
||||||
|
{super.key, required this.text, required this.onChanged});
|
||||||
final Function(bool) onChanged;
|
final Function(bool) onChanged;
|
||||||
final String text;
|
final String text;
|
||||||
|
|
||||||
|
|
@ -12,7 +13,8 @@ class ReadMoreWidget extends StatefulWidget {
|
||||||
ReadMoreWidgetState createState() => ReadMoreWidgetState();
|
ReadMoreWidgetState createState() => ReadMoreWidgetState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class ReadMoreWidgetState extends State<ReadMoreWidget> with TickerProviderStateMixin {
|
class ReadMoreWidgetState extends State<ReadMoreWidget>
|
||||||
|
with TickerProviderStateMixin {
|
||||||
late bool expanded = true;
|
late bool expanded = true;
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
|
@ -61,7 +63,9 @@ class ReadMoreWidgetState extends State<ReadMoreWidget> with TickerProviderState
|
||||||
begin: Alignment.topCenter,
|
begin: Alignment.topCenter,
|
||||||
end: Alignment.bottomCenter,
|
end: Alignment.bottomCenter,
|
||||||
colors: [
|
colors: [
|
||||||
Theme.of(context).scaffoldBackgroundColor.withValues(alpha: 0.2),
|
Theme.of(context)
|
||||||
|
.scaffoldBackgroundColor
|
||||||
|
.withValues(alpha: 0.2),
|
||||||
Theme.of(context).scaffoldBackgroundColor
|
Theme.of(context).scaffoldBackgroundColor
|
||||||
],
|
],
|
||||||
stops: const [0, .9],
|
stops: const [0, .9],
|
||||||
|
|
|
||||||
|
|
@ -11,10 +11,12 @@ import 'package:mangayomi/utils/extensions/build_context_extensions.dart';
|
||||||
class TrackerWidgetSearch extends ConsumerStatefulWidget {
|
class TrackerWidgetSearch extends ConsumerStatefulWidget {
|
||||||
final bool isManga;
|
final bool isManga;
|
||||||
final Track track;
|
final Track track;
|
||||||
const TrackerWidgetSearch({required this.isManga, required this.track, super.key});
|
const TrackerWidgetSearch(
|
||||||
|
{required this.isManga, required this.track, super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
ConsumerState<TrackerWidgetSearch> createState() => _TrackerWidgetSearchState();
|
ConsumerState<TrackerWidgetSearch> createState() =>
|
||||||
|
_TrackerWidgetSearchState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _TrackerWidgetSearchState extends ConsumerState<TrackerWidgetSearch> {
|
class _TrackerWidgetSearchState extends ConsumerState<TrackerWidgetSearch> {
|
||||||
|
|
@ -28,7 +30,10 @@ class _TrackerWidgetSearchState extends ConsumerState<TrackerWidgetSearch> {
|
||||||
late List<TrackSearch>? tracks = [];
|
late List<TrackSearch>? tracks = [];
|
||||||
_init() async {
|
_init() async {
|
||||||
await Future.delayed(const Duration(microseconds: 100));
|
await Future.delayed(const Duration(microseconds: 100));
|
||||||
tracks = await ref.read(trackStateProvider(track: widget.track, isManga: widget.isManga).notifier).search(query);
|
tracks = await ref
|
||||||
|
.read(trackStateProvider(track: widget.track, isManga: widget.isManga)
|
||||||
|
.notifier)
|
||||||
|
.search(query);
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_isLoading = false;
|
_isLoading = false;
|
||||||
|
|
@ -42,7 +47,8 @@ class _TrackerWidgetSearchState extends ConsumerState<TrackerWidgetSearch> {
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Material(
|
return Material(
|
||||||
color: Theme.of(context).scaffoldBackgroundColor,
|
color: Theme.of(context).scaffoldBackgroundColor,
|
||||||
borderRadius: const BorderRadius.only(bottomLeft: Radius.circular(20), bottomRight: Radius.circular(20)),
|
borderRadius: const BorderRadius.only(
|
||||||
|
bottomLeft: Radius.circular(20), bottomRight: Radius.circular(20)),
|
||||||
clipBehavior: Clip.antiAliasWithSaveLayer,
|
clipBehavior: Clip.antiAliasWithSaveLayer,
|
||||||
child: _isLoading
|
child: _isLoading
|
||||||
? const ProgressCenter()
|
? const ProgressCenter()
|
||||||
|
|
@ -66,41 +72,50 @@ class _TrackerWidgetSearchState extends ConsumerState<TrackerWidgetSearch> {
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
Row(
|
Row(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment:
|
||||||
|
CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Material(
|
Material(
|
||||||
borderRadius: BorderRadius.circular(5),
|
borderRadius: BorderRadius.circular(5),
|
||||||
color: Colors.transparent,
|
color: Colors.transparent,
|
||||||
clipBehavior: Clip.antiAliasWithSaveLayer,
|
clipBehavior:
|
||||||
|
Clip.antiAliasWithSaveLayer,
|
||||||
child: Ink.image(
|
child: Ink.image(
|
||||||
height: 120,
|
height: 120,
|
||||||
width: 80,
|
width: 80,
|
||||||
fit: BoxFit.cover,
|
fit: BoxFit.cover,
|
||||||
image: CustomExtendedNetworkImageProvider(tracks![index].coverUrl!),
|
image:
|
||||||
|
CustomExtendedNetworkImageProvider(
|
||||||
|
tracks![index].coverUrl!),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
width: 10,
|
width: 10,
|
||||||
),
|
),
|
||||||
Column(
|
Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment:
|
||||||
|
CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: context.width(0.6),
|
width: context.width(0.6),
|
||||||
child: Text(
|
child: Text(
|
||||||
tracks![index].title!,
|
tracks![index].title!,
|
||||||
style: const TextStyle(fontWeight: FontWeight.bold),
|
style: const TextStyle(
|
||||||
|
fontWeight: FontWeight.bold),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
const Text(
|
const Text(
|
||||||
"Type : ",
|
"Type : ",
|
||||||
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 12),
|
style: TextStyle(
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
fontSize: 12),
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
tracks![index].publishingType!,
|
tracks![index].publishingType!,
|
||||||
style: const TextStyle(fontSize: 12),
|
style: const TextStyle(
|
||||||
|
fontSize: 12),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
@ -108,11 +123,15 @@ class _TrackerWidgetSearchState extends ConsumerState<TrackerWidgetSearch> {
|
||||||
children: [
|
children: [
|
||||||
const Text(
|
const Text(
|
||||||
"Status : ",
|
"Status : ",
|
||||||
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 12),
|
style: TextStyle(
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
fontSize: 12),
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
tracks![index].publishingStatus!,
|
tracks![index]
|
||||||
style: const TextStyle(fontSize: 12),
|
.publishingStatus!,
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 12),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
@ -153,7 +172,10 @@ class _TrackerWidgetSearchState extends ConsumerState<TrackerWidgetSearch> {
|
||||||
_isLoading = true;
|
_isLoading = true;
|
||||||
});
|
});
|
||||||
tracks = await ref
|
tracks = await ref
|
||||||
.read(trackStateProvider(track: widget.track, isManga: widget.isManga).notifier)
|
.read(trackStateProvider(
|
||||||
|
track: widget.track,
|
||||||
|
isManga: widget.isManga)
|
||||||
|
.notifier)
|
||||||
.search(d.trim());
|
.search(d.trim());
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
setState(() {
|
setState(() {
|
||||||
|
|
@ -173,12 +195,16 @@ class _TrackerWidgetSearchState extends ConsumerState<TrackerWidgetSearch> {
|
||||||
},
|
},
|
||||||
icon: const Icon(Icons.clear)),
|
icon: const Icon(Icons.clear)),
|
||||||
enabledBorder: OutlineInputBorder(
|
enabledBorder: OutlineInputBorder(
|
||||||
borderSide: BorderSide(color: context.primaryColor),
|
borderSide:
|
||||||
|
BorderSide(color: context.primaryColor),
|
||||||
),
|
),
|
||||||
focusedBorder: OutlineInputBorder(
|
focusedBorder: OutlineInputBorder(
|
||||||
borderSide: BorderSide(color: context.primaryColor),
|
borderSide:
|
||||||
|
BorderSide(color: context.primaryColor),
|
||||||
),
|
),
|
||||||
border: OutlineInputBorder(borderSide: BorderSide(color: context.primaryColor))),
|
border: OutlineInputBorder(
|
||||||
|
borderSide:
|
||||||
|
BorderSide(color: context.primaryColor))),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
@ -189,7 +215,8 @@ class _TrackerWidgetSearchState extends ConsumerState<TrackerWidgetSearch> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
trackersSearchraggableMenu(BuildContext context, {required Track track, required bool isManga}) async {
|
trackersSearchraggableMenu(BuildContext context,
|
||||||
|
{required Track track, required bool isManga}) async {
|
||||||
return await DraggableMenu.open(
|
return await DraggableMenu.open(
|
||||||
context,
|
context,
|
||||||
DraggableMenu(
|
DraggableMenu(
|
||||||
|
|
@ -199,7 +226,9 @@ trackersSearchraggableMenu(BuildContext context, {required Track track, required
|
||||||
barItem: Container(
|
barItem: Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Theme.of(context).scaffoldBackgroundColor,
|
color: Theme.of(context).scaffoldBackgroundColor,
|
||||||
borderRadius: const BorderRadius.only(topLeft: Radius.circular(20), topRight: Radius.circular(20))),
|
borderRadius: const BorderRadius.only(
|
||||||
|
topLeft: Radius.circular(20),
|
||||||
|
topRight: Radius.circular(20))),
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
Row(
|
Row(
|
||||||
|
|
|
||||||
|
|
@ -38,10 +38,15 @@ class _TrackerWidgetState extends ConsumerState<TrackerWidget> {
|
||||||
|
|
||||||
_init() async {
|
_init() async {
|
||||||
await Future.delayed(const Duration(microseconds: 100));
|
await Future.delayed(const Duration(microseconds: 100));
|
||||||
final findManga =
|
final findManga = await ref
|
||||||
await ref.read(trackStateProvider(track: widget.trackRes, isManga: widget.isManga).notifier).findManga();
|
.read(
|
||||||
|
trackStateProvider(track: widget.trackRes, isManga: widget.isManga)
|
||||||
|
.notifier)
|
||||||
|
.findManga();
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
ref.read(tracksProvider(syncId: widget.syncId).notifier).updateTrackManga(findManga!, widget.isManga);
|
ref
|
||||||
|
.read(tracksProvider(syncId: widget.syncId).notifier)
|
||||||
|
.updateTrackManga(findManga!, widget.isManga);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -51,7 +56,9 @@ class _TrackerWidgetState extends ConsumerState<TrackerWidget> {
|
||||||
final l10nLocale = ref.watch(l10nLocaleStateProvider);
|
final l10nLocale = ref.watch(l10nLocaleStateProvider);
|
||||||
return Container(
|
return Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: context.isLight ? Theme.of(context).scaffoldBackgroundColor : Colors.black,
|
color: context.isLight
|
||||||
|
? Theme.of(context).scaffoldBackgroundColor
|
||||||
|
: Colors.black,
|
||||||
borderRadius: BorderRadius.circular(20)),
|
borderRadius: BorderRadius.circular(20)),
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
|
|
@ -59,10 +66,12 @@ class _TrackerWidgetState extends ConsumerState<TrackerWidget> {
|
||||||
children: [
|
children: [
|
||||||
if (!widget.hide)
|
if (!widget.hide)
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 5),
|
padding:
|
||||||
|
const EdgeInsets.symmetric(horizontal: 12, vertical: 5),
|
||||||
child: Container(
|
child: Container(
|
||||||
decoration:
|
decoration: BoxDecoration(
|
||||||
BoxDecoration(borderRadius: BorderRadius.circular(10), color: trackInfos(widget.syncId).$3),
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
color: trackInfos(widget.syncId).$3),
|
||||||
width: 50,
|
width: 50,
|
||||||
height: 45,
|
height: 45,
|
||||||
child: Image.asset(
|
child: Image.asset(
|
||||||
|
|
@ -74,16 +83,22 @@ class _TrackerWidgetState extends ConsumerState<TrackerWidget> {
|
||||||
Expanded(
|
Expanded(
|
||||||
child: _elevatedButton(
|
child: _elevatedButton(
|
||||||
context,
|
context,
|
||||||
borderRadius: const BorderRadius.only(topRight: Radius.circular(20), topLeft: Radius.circular(20)),
|
borderRadius: const BorderRadius.only(
|
||||||
|
topRight: Radius.circular(20),
|
||||||
|
topLeft: Radius.circular(20)),
|
||||||
onPressed: !widget.hide
|
onPressed: !widget.hide
|
||||||
? () async {
|
? () async {
|
||||||
final trackSearch =
|
final trackSearch = await trackersSearchraggableMenu(
|
||||||
await trackersSearchraggableMenu(context, isManga: widget.isManga, track: widget.trackRes)
|
context,
|
||||||
as TrackSearch?;
|
isManga: widget.isManga,
|
||||||
|
track: widget.trackRes) as TrackSearch?;
|
||||||
if (trackSearch != null) {
|
if (trackSearch != null) {
|
||||||
await ref
|
await ref
|
||||||
.read(trackStateProvider(track: null, isManga: widget.isManga).notifier)
|
.read(trackStateProvider(
|
||||||
.setTrackSearch(trackSearch, widget.mangaId, widget.syncId);
|
track: null, isManga: widget.isManga)
|
||||||
|
.notifier)
|
||||||
|
.setTrackSearch(
|
||||||
|
trackSearch, widget.mangaId, widget.syncId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
: null,
|
: null,
|
||||||
|
|
@ -95,7 +110,10 @@ class _TrackerWidgetState extends ConsumerState<TrackerWidget> {
|
||||||
child: Text(
|
child: Text(
|
||||||
widget.trackRes.title!,
|
widget.trackRes.title!,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Theme.of(context).textTheme.bodyMedium!.color,
|
color: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.bodyMedium!
|
||||||
|
.color,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
fontWeight: FontWeight.bold),
|
fontWeight: FontWeight.bold),
|
||||||
|
|
@ -105,7 +123,10 @@ class _TrackerWidgetState extends ConsumerState<TrackerWidget> {
|
||||||
),
|
),
|
||||||
IconButton(
|
IconButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
ref.read(tracksProvider(syncId: widget.syncId).notifier).deleteTrackManga(widget.trackRes);
|
ref
|
||||||
|
.read(tracksProvider(syncId: widget.syncId)
|
||||||
|
.notifier)
|
||||||
|
.deleteTrackManga(widget.trackRes);
|
||||||
},
|
},
|
||||||
icon: const Icon(Icons.cancel_outlined))
|
icon: const Icon(Icons.cancel_outlined))
|
||||||
],
|
],
|
||||||
|
|
@ -130,29 +151,39 @@ class _TrackerWidgetState extends ConsumerState<TrackerWidget> {
|
||||||
child: ListView.builder(
|
child: ListView.builder(
|
||||||
shrinkWrap: true,
|
shrinkWrap: true,
|
||||||
itemCount: ref
|
itemCount: ref
|
||||||
.read(trackStateProvider(track: widget.trackRes, isManga: widget.isManga).notifier)
|
.read(trackStateProvider(
|
||||||
|
track: widget.trackRes,
|
||||||
|
isManga: widget.isManga)
|
||||||
|
.notifier)
|
||||||
.getStatusList()
|
.getStatusList()
|
||||||
.length,
|
.length,
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
final status = ref
|
final status = ref
|
||||||
.read(
|
.read(trackStateProvider(
|
||||||
trackStateProvider(track: widget.trackRes, isManga: widget.isManga).notifier)
|
track: widget.trackRes,
|
||||||
|
isManga: widget.isManga)
|
||||||
|
.notifier)
|
||||||
.getStatusList()[index];
|
.getStatusList()[index];
|
||||||
return RadioListTile(
|
return RadioListTile(
|
||||||
dense: true,
|
dense: true,
|
||||||
contentPadding: const EdgeInsets.all(0),
|
contentPadding: const EdgeInsets.all(0),
|
||||||
value: status,
|
value: status,
|
||||||
groupValue:
|
groupValue: toTrackStatus(
|
||||||
toTrackStatus(widget.trackRes.status, widget.isManga, widget.trackRes.syncId!),
|
widget.trackRes.status,
|
||||||
|
widget.isManga,
|
||||||
|
widget.trackRes.syncId!),
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
ref
|
ref
|
||||||
.read(trackStateProvider(
|
.read(trackStateProvider(
|
||||||
track: widget.trackRes..status = status, isManga: widget.isManga)
|
track: widget.trackRes
|
||||||
|
..status = status,
|
||||||
|
isManga: widget.isManga)
|
||||||
.notifier)
|
.notifier)
|
||||||
.updateManga();
|
.updateManga();
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
},
|
},
|
||||||
title: Text(getTrackStatus(status, context)),
|
title:
|
||||||
|
Text(getTrackStatus(status, context)),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
)),
|
)),
|
||||||
|
|
@ -166,7 +197,8 @@ class _TrackerWidgetState extends ConsumerState<TrackerWidget> {
|
||||||
},
|
},
|
||||||
child: Text(
|
child: Text(
|
||||||
l10n.cancel,
|
l10n.cancel,
|
||||||
style: TextStyle(color: context.primaryColor),
|
style: TextStyle(
|
||||||
|
color: context.primaryColor),
|
||||||
)),
|
)),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
@ -175,7 +207,9 @@ class _TrackerWidgetState extends ConsumerState<TrackerWidget> {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
text: getTrackStatus(
|
text: getTrackStatus(
|
||||||
toTrackStatus(widget.trackRes.status, widget.isManga, widget.trackRes.syncId!), context)),
|
toTrackStatus(widget.trackRes.status, widget.isManga,
|
||||||
|
widget.trackRes.syncId!),
|
||||||
|
context)),
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: _elevatedButton(context, onPressed: () {
|
child: _elevatedButton(context, onPressed: () {
|
||||||
|
|
@ -196,10 +230,13 @@ class _TrackerWidgetState extends ConsumerState<TrackerWidget> {
|
||||||
NumberPicker(
|
NumberPicker(
|
||||||
value: currentIntValue,
|
value: currentIntValue,
|
||||||
minValue: 0,
|
minValue: 0,
|
||||||
maxValue: widget.trackRes.totalChapter != 0 ? widget.trackRes.totalChapter! : 10000,
|
maxValue: widget.trackRes.totalChapter != 0
|
||||||
|
? widget.trackRes.totalChapter!
|
||||||
|
: 10000,
|
||||||
step: 1,
|
step: 1,
|
||||||
haptics: true,
|
haptics: true,
|
||||||
onChanged: (value) => setState(() => currentIntValue = value),
|
onChanged: (value) =>
|
||||||
|
setState(() => currentIntValue = value),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
@ -215,13 +252,16 @@ class _TrackerWidgetState extends ConsumerState<TrackerWidget> {
|
||||||
},
|
},
|
||||||
child: Text(
|
child: Text(
|
||||||
l10n.cancel,
|
l10n.cancel,
|
||||||
style: TextStyle(color: context.primaryColor),
|
style: TextStyle(
|
||||||
|
color: context.primaryColor),
|
||||||
)),
|
)),
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
ref
|
ref
|
||||||
.read(trackStateProvider(
|
.read(trackStateProvider(
|
||||||
track: widget.trackRes..lastChapterRead = currentIntValue,
|
track: widget.trackRes
|
||||||
|
..lastChapterRead =
|
||||||
|
currentIntValue,
|
||||||
isManga: widget.isManga)
|
isManga: widget.isManga)
|
||||||
.notifier)
|
.notifier)
|
||||||
.updateManga();
|
.updateManga();
|
||||||
|
|
@ -229,7 +269,8 @@ class _TrackerWidgetState extends ConsumerState<TrackerWidget> {
|
||||||
},
|
},
|
||||||
child: Text(
|
child: Text(
|
||||||
l10n.ok,
|
l10n.ok,
|
||||||
style: TextStyle(color: context.primaryColor),
|
style: TextStyle(
|
||||||
|
color: context.primaryColor),
|
||||||
)),
|
)),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
@ -261,21 +302,28 @@ class _TrackerWidgetState extends ConsumerState<TrackerWidget> {
|
||||||
value: currentIntValue,
|
value: currentIntValue,
|
||||||
minValue: 0,
|
minValue: 0,
|
||||||
maxValue: ref
|
maxValue: ref
|
||||||
.read(trackStateProvider(track: widget.trackRes, isManga: widget.isManga)
|
.read(trackStateProvider(
|
||||||
|
track: widget.trackRes,
|
||||||
|
isManga: widget.isManga)
|
||||||
.notifier)
|
.notifier)
|
||||||
.getScoreMaxValue(),
|
.getScoreMaxValue(),
|
||||||
textMapper: (numberText) {
|
textMapper: (numberText) {
|
||||||
return ref
|
return ref
|
||||||
.read(trackStateProvider(track: widget.trackRes, isManga: widget.isManga)
|
.read(trackStateProvider(
|
||||||
|
track: widget.trackRes,
|
||||||
|
isManga: widget.isManga)
|
||||||
.notifier)
|
.notifier)
|
||||||
.getTextMapper(numberText);
|
.getTextMapper(numberText);
|
||||||
},
|
},
|
||||||
step: ref
|
step: ref
|
||||||
.read(trackStateProvider(track: widget.trackRes, isManga: widget.isManga)
|
.read(trackStateProvider(
|
||||||
|
track: widget.trackRes,
|
||||||
|
isManga: widget.isManga)
|
||||||
.notifier)
|
.notifier)
|
||||||
.getScoreStep(),
|
.getScoreStep(),
|
||||||
haptics: true,
|
haptics: true,
|
||||||
onChanged: (value) => setState(() => currentIntValue = value),
|
onChanged: (value) =>
|
||||||
|
setState(() => currentIntValue = value),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
@ -291,13 +339,15 @@ class _TrackerWidgetState extends ConsumerState<TrackerWidget> {
|
||||||
},
|
},
|
||||||
child: Text(
|
child: Text(
|
||||||
l10n.cancel,
|
l10n.cancel,
|
||||||
style: TextStyle(color: context.primaryColor),
|
style: TextStyle(
|
||||||
|
color: context.primaryColor),
|
||||||
)),
|
)),
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
ref
|
ref
|
||||||
.read(trackStateProvider(
|
.read(trackStateProvider(
|
||||||
track: widget.trackRes..score = currentIntValue,
|
track: widget.trackRes
|
||||||
|
..score = currentIntValue,
|
||||||
isManga: widget.isManga)
|
isManga: widget.isManga)
|
||||||
.notifier)
|
.notifier)
|
||||||
.updateManga();
|
.updateManga();
|
||||||
|
|
@ -305,7 +355,8 @@ class _TrackerWidgetState extends ConsumerState<TrackerWidget> {
|
||||||
},
|
},
|
||||||
child: Text(
|
child: Text(
|
||||||
l10n.ok,
|
l10n.ok,
|
||||||
style: TextStyle(color: context.primaryColor),
|
style: TextStyle(
|
||||||
|
color: context.primaryColor),
|
||||||
)),
|
)),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
@ -315,7 +366,10 @@ class _TrackerWidgetState extends ConsumerState<TrackerWidget> {
|
||||||
},
|
},
|
||||||
text: widget.trackRes.score != 0
|
text: widget.trackRes.score != 0
|
||||||
? ref
|
? ref
|
||||||
.read(trackStateProvider(track: widget.trackRes, isManga: widget.isManga).notifier)
|
.read(trackStateProvider(
|
||||||
|
track: widget.trackRes,
|
||||||
|
isManga: widget.isManga)
|
||||||
|
.notifier)
|
||||||
.displayScore(widget.trackRes.score!)
|
.displayScore(widget.trackRes.score!)
|
||||||
: l10n!.score),
|
: l10n!.score),
|
||||||
)
|
)
|
||||||
|
|
@ -324,8 +378,9 @@ class _TrackerWidgetState extends ConsumerState<TrackerWidget> {
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: _elevatedButton(context, borderRadius: const BorderRadius.only(bottomLeft: Radius.circular(20)),
|
child: _elevatedButton(context,
|
||||||
onPressed: () async {
|
borderRadius: const BorderRadius.only(
|
||||||
|
bottomLeft: Radius.circular(20)), onPressed: () async {
|
||||||
DateTime? newDate = await showDatePicker(
|
DateTime? newDate = await showDatePicker(
|
||||||
helpText: l10n!.start_date,
|
helpText: l10n!.start_date,
|
||||||
locale: l10nLocale,
|
locale: l10nLocale,
|
||||||
|
|
@ -336,20 +391,27 @@ class _TrackerWidgetState extends ConsumerState<TrackerWidget> {
|
||||||
if (newDate == null) return;
|
if (newDate == null) return;
|
||||||
ref
|
ref
|
||||||
.read(trackStateProvider(
|
.read(trackStateProvider(
|
||||||
track: widget.trackRes..startedReadingDate = newDate.millisecondsSinceEpoch,
|
track: widget.trackRes
|
||||||
|
..startedReadingDate =
|
||||||
|
newDate.millisecondsSinceEpoch,
|
||||||
isManga: widget.isManga)
|
isManga: widget.isManga)
|
||||||
.notifier)
|
.notifier)
|
||||||
.updateManga();
|
.updateManga();
|
||||||
},
|
},
|
||||||
text: widget.trackRes.startedReadingDate != null &&
|
text: widget.trackRes.startedReadingDate != null &&
|
||||||
widget.trackRes.startedReadingDate! > DateTime(1970).millisecondsSinceEpoch
|
widget.trackRes.startedReadingDate! >
|
||||||
? dateFormat(widget.trackRes.startedReadingDate.toString(),
|
DateTime(1970).millisecondsSinceEpoch
|
||||||
ref: ref, useRelativeTimesTamps: false, context: context)
|
? dateFormat(
|
||||||
|
widget.trackRes.startedReadingDate.toString(),
|
||||||
|
ref: ref,
|
||||||
|
useRelativeTimesTamps: false,
|
||||||
|
context: context)
|
||||||
: l10n!.start_date),
|
: l10n!.start_date),
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: _elevatedButton(context, borderRadius: const BorderRadius.only(bottomRight: Radius.circular(20)),
|
child: _elevatedButton(context,
|
||||||
onPressed: () async {
|
borderRadius: const BorderRadius.only(
|
||||||
|
bottomRight: Radius.circular(20)), onPressed: () async {
|
||||||
DateTime? newDate = await showDatePicker(
|
DateTime? newDate = await showDatePicker(
|
||||||
helpText: l10n!.finish_date,
|
helpText: l10n!.finish_date,
|
||||||
locale: l10nLocale,
|
locale: l10nLocale,
|
||||||
|
|
@ -360,15 +422,21 @@ class _TrackerWidgetState extends ConsumerState<TrackerWidget> {
|
||||||
if (newDate == null) return;
|
if (newDate == null) return;
|
||||||
ref
|
ref
|
||||||
.read(trackStateProvider(
|
.read(trackStateProvider(
|
||||||
track: widget.trackRes..finishedReadingDate = newDate.millisecondsSinceEpoch,
|
track: widget.trackRes
|
||||||
|
..finishedReadingDate =
|
||||||
|
newDate.millisecondsSinceEpoch,
|
||||||
isManga: widget.isManga)
|
isManga: widget.isManga)
|
||||||
.notifier)
|
.notifier)
|
||||||
.updateManga();
|
.updateManga();
|
||||||
},
|
},
|
||||||
text: widget.trackRes.finishedReadingDate != null &&
|
text: widget.trackRes.finishedReadingDate != null &&
|
||||||
widget.trackRes.finishedReadingDate! > DateTime(1970).millisecondsSinceEpoch
|
widget.trackRes.finishedReadingDate! >
|
||||||
? dateFormat(widget.trackRes.finishedReadingDate.toString(),
|
DateTime(1970).millisecondsSinceEpoch
|
||||||
ref: ref, useRelativeTimesTamps: false, context: context)
|
? dateFormat(
|
||||||
|
widget.trackRes.finishedReadingDate.toString(),
|
||||||
|
ref: ref,
|
||||||
|
useRelativeTimesTamps: false,
|
||||||
|
context: context)
|
||||||
: l10n!.finish_date),
|
: l10n!.finish_date),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
|
|
@ -380,20 +448,32 @@ class _TrackerWidgetState extends ConsumerState<TrackerWidget> {
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _elevatedButton(BuildContext context,
|
Widget _elevatedButton(BuildContext context,
|
||||||
{required Function()? onPressed, String text = "", Widget? child, BorderRadiusGeometry? borderRadius}) {
|
{required Function()? onPressed,
|
||||||
|
String text = "",
|
||||||
|
Widget? child,
|
||||||
|
BorderRadiusGeometry? borderRadius}) {
|
||||||
return ElevatedButton(
|
return ElevatedButton(
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
padding: const EdgeInsets.all(0),
|
padding: const EdgeInsets.all(0),
|
||||||
backgroundColor: context.isLight ? Theme.of(context).scaffoldBackgroundColor : Colors.black,
|
backgroundColor: context.isLight
|
||||||
|
? Theme.of(context).scaffoldBackgroundColor
|
||||||
|
: Colors.black,
|
||||||
elevation: 0,
|
elevation: 0,
|
||||||
shadowColor: Colors.transparent,
|
shadowColor: Colors.transparent,
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
side: BorderSide(width: 0, color: context.secondaryColor.withValues(alpha: 0.1)),
|
side: BorderSide(
|
||||||
|
width: 0,
|
||||||
|
color: context.secondaryColor.withValues(alpha: 0.1)),
|
||||||
borderRadius: borderRadius ?? BorderRadius.circular(0))),
|
borderRadius: borderRadius ?? BorderRadius.circular(0))),
|
||||||
onPressed: onPressed,
|
onPressed: onPressed,
|
||||||
child: child ??
|
child: child ??
|
||||||
Text(
|
Text(
|
||||||
text,
|
text,
|
||||||
style: TextStyle(color: Theme.of(context).textTheme.bodyMedium!.color!.withValues(alpha: 0.9)),
|
style: TextStyle(
|
||||||
|
color: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.bodyMedium!
|
||||||
|
.color!
|
||||||
|
.withValues(alpha: 0.9)),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,19 +35,24 @@ class _ChapterPageDownloadState extends ConsumerState<ChapterPageDownload>
|
||||||
final StorageProvider _storageProvider = StorageProvider();
|
final StorageProvider _storageProvider = StorageProvider();
|
||||||
|
|
||||||
void _startDownload(bool? useWifi) async {
|
void _startDownload(bool? useWifi) async {
|
||||||
await ref.watch(downloadChapterProvider(chapter: widget.chapter, useWifi: useWifi).future);
|
await ref.watch(
|
||||||
|
downloadChapterProvider(chapter: widget.chapter, useWifi: useWifi)
|
||||||
|
.future);
|
||||||
}
|
}
|
||||||
|
|
||||||
late final manga = widget.chapter.manga.value!;
|
late final manga = widget.chapter.manga.value!;
|
||||||
|
|
||||||
void _sendFile() async {
|
void _sendFile() async {
|
||||||
final mangaDir = await _storageProvider.getMangaMainDirectory(widget.chapter);
|
final mangaDir =
|
||||||
final path = await _storageProvider.getMangaChapterDirectory(widget.chapter);
|
await _storageProvider.getMangaMainDirectory(widget.chapter);
|
||||||
|
final path =
|
||||||
|
await _storageProvider.getMangaChapterDirectory(widget.chapter);
|
||||||
|
|
||||||
List<XFile> files = [];
|
List<XFile> files = [];
|
||||||
|
|
||||||
final cbzFile = File(p.join(mangaDir!.path, "${widget.chapter.name}.cbz"));
|
final cbzFile = File(p.join(mangaDir!.path, "${widget.chapter.name}.cbz"));
|
||||||
final mp4File = File(p.join(mangaDir.path, "${widget.chapter.name!.replaceForbiddenCharacters(' ')}.mp4"));
|
final mp4File = File(p.join(mangaDir.path,
|
||||||
|
"${widget.chapter.name!.replaceForbiddenCharacters(' ')}.mp4"));
|
||||||
if (cbzFile.existsSync()) {
|
if (cbzFile.existsSync()) {
|
||||||
files = [XFile(cbzFile.path)];
|
files = [XFile(cbzFile.path)];
|
||||||
} else if (mp4File.existsSync()) {
|
} else if (mp4File.existsSync()) {
|
||||||
|
|
@ -61,18 +66,22 @@ class _ChapterPageDownloadState extends ConsumerState<ChapterPageDownload>
|
||||||
}
|
}
|
||||||
|
|
||||||
void _deleteFile() async {
|
void _deleteFile() async {
|
||||||
final mangaDir = await _storageProvider.getMangaMainDirectory(widget.chapter);
|
final mangaDir =
|
||||||
final path = await _storageProvider.getMangaChapterDirectory(widget.chapter);
|
await _storageProvider.getMangaMainDirectory(widget.chapter);
|
||||||
|
final path =
|
||||||
|
await _storageProvider.getMangaChapterDirectory(widget.chapter);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
try {
|
try {
|
||||||
final cbzFile = File(p.join(mangaDir!.path, "${widget.chapter.name}.cbz"));
|
final cbzFile =
|
||||||
|
File(p.join(mangaDir!.path, "${widget.chapter.name}.cbz"));
|
||||||
if (cbzFile.existsSync()) {
|
if (cbzFile.existsSync()) {
|
||||||
cbzFile.deleteSync();
|
cbzFile.deleteSync();
|
||||||
}
|
}
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
try {
|
try {
|
||||||
final mp4File = File(p.join(mangaDir!.path, "${widget.chapter.name!.replaceForbiddenCharacters(' ')}.mp4"));
|
final mp4File = File(p.join(mangaDir!.path,
|
||||||
|
"${widget.chapter.name!.replaceForbiddenCharacters(' ')}.mp4"));
|
||||||
if (mp4File.existsSync()) {
|
if (mp4File.existsSync()) {
|
||||||
mp4File.deleteSync();
|
mp4File.deleteSync();
|
||||||
}
|
}
|
||||||
|
|
@ -80,7 +89,11 @@ class _ChapterPageDownloadState extends ConsumerState<ChapterPageDownload>
|
||||||
path!.deleteSync(recursive: true);
|
path!.deleteSync(recursive: true);
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
isar.writeTxnSync(() {
|
isar.writeTxnSync(() {
|
||||||
int id = isar.downloads.filter().chapterIdEqualTo(widget.chapter.id!).findFirstSync()!.id!;
|
int id = isar.downloads
|
||||||
|
.filter()
|
||||||
|
.chapterIdEqualTo(widget.chapter.id!)
|
||||||
|
.findFirstSync()!
|
||||||
|
.id!;
|
||||||
isar.downloads.deleteSync(id);
|
isar.downloads.deleteSync(id);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -111,7 +124,10 @@ class _ChapterPageDownloadState extends ConsumerState<ChapterPageDownload>
|
||||||
child: Icon(
|
child: Icon(
|
||||||
size: 25,
|
size: 25,
|
||||||
Icons.check_circle,
|
Icons.check_circle,
|
||||||
color: Theme.of(context).iconTheme.color!.withValues(alpha: 0.7),
|
color: Theme.of(context)
|
||||||
|
.iconTheme
|
||||||
|
.color!
|
||||||
|
.withValues(alpha: 0.7),
|
||||||
),
|
),
|
||||||
onSelected: (value) {
|
onSelected: (value) {
|
||||||
if (value == 0) {
|
if (value == 0) {
|
||||||
|
|
@ -125,7 +141,8 @@ class _ChapterPageDownloadState extends ConsumerState<ChapterPageDownload>
|
||||||
PopupMenuItem(value: 1, child: Text(l10n.delete)),
|
PopupMenuItem(value: 1, child: Text(l10n.delete)),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
: entries.first.isStartDownload! && entries.first.succeeded == 0
|
: entries.first.isStartDownload! &&
|
||||||
|
entries.first.succeeded == 0
|
||||||
? SizedBox(
|
? SizedBox(
|
||||||
height: 41,
|
height: 41,
|
||||||
width: 35,
|
width: 35,
|
||||||
|
|
@ -144,7 +161,9 @@ class _ChapterPageDownloadState extends ConsumerState<ChapterPageDownload>
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
itemBuilder: (context) => [
|
itemBuilder: (context) => [
|
||||||
PopupMenuItem(value: 1, child: Text(l10n.start_downloading)),
|
PopupMenuItem(
|
||||||
|
value: 1,
|
||||||
|
child: Text(l10n.start_downloading)),
|
||||||
PopupMenuItem(value: 0, child: Text(l10n.cancel)),
|
PopupMenuItem(value: 0, child: Text(l10n.cancel)),
|
||||||
],
|
],
|
||||||
))
|
))
|
||||||
|
|
@ -159,19 +178,25 @@ class _ChapterPageDownloadState extends ConsumerState<ChapterPageDownload>
|
||||||
Align(
|
Align(
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
child: TweenAnimationBuilder<double>(
|
child: TweenAnimationBuilder<double>(
|
||||||
duration: const Duration(milliseconds: 250),
|
duration:
|
||||||
|
const Duration(milliseconds: 250),
|
||||||
curve: Curves.easeInOut,
|
curve: Curves.easeInOut,
|
||||||
tween: Tween<double>(
|
tween: Tween<double>(
|
||||||
begin: 0,
|
begin: 0,
|
||||||
end: (entries.first.succeeded! / entries.first.total!),
|
end: (entries.first.succeeded! /
|
||||||
|
entries.first.total!),
|
||||||
),
|
),
|
||||||
builder: (context, value, _) => SizedBox(
|
builder: (context, value, _) =>
|
||||||
|
SizedBox(
|
||||||
height: 2,
|
height: 2,
|
||||||
width: 2,
|
width: 2,
|
||||||
child: CircularProgressIndicator(
|
child: CircularProgressIndicator(
|
||||||
strokeWidth: 19,
|
strokeWidth: 19,
|
||||||
value: value,
|
value: value,
|
||||||
color: Theme.of(context).iconTheme.color!.withValues(alpha: 0.7),
|
color: Theme.of(context)
|
||||||
|
.iconTheme
|
||||||
|
.color!
|
||||||
|
.withValues(alpha: 0.7),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -180,9 +205,15 @@ class _ChapterPageDownloadState extends ConsumerState<ChapterPageDownload>
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
child: Icon(
|
child: Icon(
|
||||||
Icons.arrow_downward_sharp,
|
Icons.arrow_downward_sharp,
|
||||||
color: (entries.first.succeeded! / entries.first.total!) > 0.5
|
color: (entries.first.succeeded! /
|
||||||
? Theme.of(context).scaffoldBackgroundColor
|
entries.first.total!) >
|
||||||
: Theme.of(context).iconTheme.color!.withValues(alpha: 0.7),
|
0.5
|
||||||
|
? Theme.of(context)
|
||||||
|
.scaffoldBackgroundColor
|
||||||
|
: Theme.of(context)
|
||||||
|
.iconTheme
|
||||||
|
.color!
|
||||||
|
.withValues(alpha: 0.7),
|
||||||
)),
|
)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
@ -198,8 +229,11 @@ class _ChapterPageDownloadState extends ConsumerState<ChapterPageDownload>
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
itemBuilder: (context) => [
|
itemBuilder: (context) => [
|
||||||
PopupMenuItem(value: 1, child: Text(l10n.start_downloading)),
|
PopupMenuItem(
|
||||||
PopupMenuItem(value: 0, child: Text(l10n.cancel)),
|
value: 1,
|
||||||
|
child: Text(l10n.start_downloading)),
|
||||||
|
PopupMenuItem(
|
||||||
|
value: 0, child: Text(l10n.cancel)),
|
||||||
],
|
],
|
||||||
))
|
))
|
||||||
: entries.first.succeeded == 0
|
: entries.first.succeeded == 0
|
||||||
|
|
@ -212,7 +246,10 @@ class _ChapterPageDownloadState extends ConsumerState<ChapterPageDownload>
|
||||||
},
|
},
|
||||||
icon: Icon(
|
icon: Icon(
|
||||||
FontAwesomeIcons.circleDown,
|
FontAwesomeIcons.circleDown,
|
||||||
color: Theme.of(context).iconTheme.color!.withValues(alpha: 0.7),
|
color: Theme.of(context)
|
||||||
|
.iconTheme
|
||||||
|
.color!
|
||||||
|
.withValues(alpha: 0.7),
|
||||||
size: 25,
|
size: 25,
|
||||||
))
|
))
|
||||||
: SizedBox(
|
: SizedBox(
|
||||||
|
|
@ -235,7 +272,8 @@ class _ChapterPageDownloadState extends ConsumerState<ChapterPageDownload>
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
itemBuilder: (context) => [
|
itemBuilder: (context) => [
|
||||||
PopupMenuItem(value: 0, child: Text(l10n.retry)),
|
PopupMenuItem(
|
||||||
|
value: 0, child: Text(l10n.retry)),
|
||||||
],
|
],
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
@ -255,7 +293,8 @@ class _ChapterPageDownloadState extends ConsumerState<ChapterPageDownload>
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
itemBuilder: (context) => [
|
itemBuilder: (context) => [
|
||||||
PopupMenuItem(value: 1, child: Text(l10n.start_downloading)),
|
PopupMenuItem(
|
||||||
|
value: 1, child: Text(l10n.start_downloading)),
|
||||||
PopupMenuItem(value: 0, child: Text(l10n.cancel)),
|
PopupMenuItem(value: 0, child: Text(l10n.cancel)),
|
||||||
],
|
],
|
||||||
))
|
))
|
||||||
|
|
@ -287,7 +326,10 @@ class _ChapterPageDownloadState extends ConsumerState<ChapterPageDownload>
|
||||||
[];
|
[];
|
||||||
await FileDownloader().cancelTasksWithIds(_pageUrls);
|
await FileDownloader().cancelTasksWithIds(_pageUrls);
|
||||||
await Future.delayed(const Duration(seconds: 2));
|
await Future.delayed(const Duration(seconds: 2));
|
||||||
final chapterD = isar.downloads.filter().chapterIdEqualTo(widget.chapter.id!).findFirstSync();
|
final chapterD = isar.downloads
|
||||||
|
.filter()
|
||||||
|
.chapterIdEqualTo(widget.chapter.id!)
|
||||||
|
.findFirstSync();
|
||||||
if (chapterD != null) {
|
if (chapterD != null) {
|
||||||
final verifyId = isar.downloads.getSync(chapterD.id!);
|
final verifyId = isar.downloads.getSync(chapterD.id!);
|
||||||
isar.writeTxnSync(() {
|
isar.writeTxnSync(() {
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,8 @@ import 'package:path/path.dart' as path;
|
||||||
part 'convert_to_cbz.g.dart';
|
part 'convert_to_cbz.g.dart';
|
||||||
|
|
||||||
@riverpod
|
@riverpod
|
||||||
Future<List<String>> convertToCBZ(
|
Future<List<String>> convertToCBZ(Ref ref, String chapterDir, String mangaDir,
|
||||||
Ref ref, String chapterDir, String mangaDir, String chapterName, List<String> pageList) async {
|
String chapterName, List<String> pageList) async {
|
||||||
return compute(_convertToCBZ, (chapterDir, mangaDir, chapterName, pageList));
|
return compute(_convertToCBZ, (chapterDir, mangaDir, chapterName, pageList));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,8 +41,9 @@ Future<List<PageUrl>> downloadChapter(
|
||||||
bool isOk = false;
|
bool isOk = false;
|
||||||
final manga = chapter.manga.value!;
|
final manga = chapter.manga.value!;
|
||||||
final path1 = await storageProvider.getDirectory();
|
final path1 = await storageProvider.getDirectory();
|
||||||
String scanlator =
|
String scanlator = (chapter.scanlator?.isNotEmpty ?? false)
|
||||||
(chapter.scanlator?.isNotEmpty ?? false) ? "${chapter.scanlator!.replaceForbiddenCharacters('_')}_" : "";
|
? "${chapter.scanlator!.replaceForbiddenCharacters('_')}_"
|
||||||
|
: "";
|
||||||
final chapterName = chapter.name!.replaceForbiddenCharacters(' ');
|
final chapterName = chapter.name!.replaceForbiddenCharacters(' ');
|
||||||
|
|
||||||
final isManga = manga.isManga!;
|
final isManga = manga.isManga!;
|
||||||
|
|
@ -68,12 +69,13 @@ Future<List<PageUrl>> downloadChapter(
|
||||||
|
|
||||||
Future<void> processConvert() async {
|
Future<void> processConvert() async {
|
||||||
if (hasM3U8File) {
|
if (hasM3U8File) {
|
||||||
await m3u8Downloader?.mergeTsToMp4(p.join(path!.path, "$chapterName.mp4"), p.join(path.path, chapterName));
|
await m3u8Downloader?.mergeTsToMp4(p.join(path!.path, "$chapterName.mp4"),
|
||||||
|
p.join(path.path, chapterName));
|
||||||
} else {
|
} else {
|
||||||
if (ref.watch(saveAsCBZArchiveStateProvider)) {
|
if (ref.watch(saveAsCBZArchiveStateProvider)) {
|
||||||
await ref.watch(
|
await ref.watch(convertToCBZProvider(path!.path, mangaDir!.path,
|
||||||
convertToCBZProvider(path!.path, mangaDir!.path, chapter.name!, pageUrls.map((e) => e.url).toList())
|
chapter.name!, pageUrls.map((e) => e.url).toList())
|
||||||
.future);
|
.future);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -86,12 +88,17 @@ Future<List<PageUrl>> downloadChapter(
|
||||||
chapterPageUrls.add(chapterPageUrl);
|
chapterPageUrls.add(chapterPageUrl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
final chapterPageHeaders = pageUrls.map((e) => e.headers == null ? null : jsonEncode(e.headers)).toList();
|
final chapterPageHeaders = pageUrls
|
||||||
|
.map((e) => e.headers == null ? null : jsonEncode(e.headers))
|
||||||
|
.toList();
|
||||||
chapterPageUrls.add(ChapterPageurls()
|
chapterPageUrls.add(ChapterPageurls()
|
||||||
..chapterId = chapter.id
|
..chapterId = chapter.id
|
||||||
..urls = pageUrls.map((e) => e.url).toList()
|
..urls = pageUrls.map((e) => e.url).toList()
|
||||||
..headers = chapterPageHeaders.first != null ? chapterPageHeaders.map((e) => e.toString()).toList() : null);
|
..headers = chapterPageHeaders.first != null
|
||||||
isar.writeTxnSync(() => isar.settings.putSync(settings..chapterPageUrlsList = chapterPageUrls));
|
? chapterPageHeaders.map((e) => e.toString()).toList()
|
||||||
|
: null);
|
||||||
|
isar.writeTxnSync(() =>
|
||||||
|
isar.settings.putSync(settings..chapterPageUrlsList = chapterPageUrls));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isManga) {
|
if (isManga) {
|
||||||
|
|
@ -108,9 +115,13 @@ Future<List<PageUrl>> downloadChapter(
|
||||||
} else {
|
} else {
|
||||||
ref.read(getVideoListProvider(episode: chapter).future).then((value) async {
|
ref.read(getVideoListProvider(episode: chapter).future).then((value) async {
|
||||||
final m3u8Urls = value.$1
|
final m3u8Urls = value.$1
|
||||||
.where((element) => element.originalUrl.endsWith(".m3u8") || element.originalUrl.endsWith(".m3u"))
|
.where((element) =>
|
||||||
|
element.originalUrl.endsWith(".m3u8") ||
|
||||||
|
element.originalUrl.endsWith(".m3u"))
|
||||||
|
.toList();
|
||||||
|
final nonM3u8Urls = value.$1
|
||||||
|
.where((element) => element.originalUrl.isMediaVideo())
|
||||||
.toList();
|
.toList();
|
||||||
final nonM3u8Urls = value.$1.where((element) => element.originalUrl.isMediaVideo()).toList();
|
|
||||||
nonM3U8File = nonM3u8Urls.isNotEmpty;
|
nonM3U8File = nonM3u8Urls.isNotEmpty;
|
||||||
hasM3U8File = nonM3U8File ? false : m3u8Urls.isNotEmpty;
|
hasM3U8File = nonM3U8File ? false : m3u8Urls.isNotEmpty;
|
||||||
final videosUrls = nonM3U8File ? nonM3u8Urls : m3u8Urls;
|
final videosUrls = nonM3U8File ? nonM3u8Urls : m3u8Urls;
|
||||||
|
|
@ -121,9 +132,12 @@ Future<List<PageUrl>> downloadChapter(
|
||||||
m3u8Url: videosUrls.first.url,
|
m3u8Url: videosUrls.first.url,
|
||||||
downloadDir: p.join(path!.path, chapterName),
|
downloadDir: p.join(path!.path, chapterName),
|
||||||
headers: videosUrls.first.headers ?? {});
|
headers: videosUrls.first.headers ?? {});
|
||||||
(tsList, tsKey, tsIv, m3u8MediaSequence) = await m3u8Downloader!.getTsList();
|
(tsList, tsKey, tsIv, m3u8MediaSequence) =
|
||||||
|
await m3u8Downloader!.getTsList();
|
||||||
}
|
}
|
||||||
pageUrls = hasM3U8File ? [...tsList.map((e) => PageUrl(e.url))] : [PageUrl(videosUrls.first.url)];
|
pageUrls = hasM3U8File
|
||||||
|
? [...tsList.map((e) => PageUrl(e.url))]
|
||||||
|
: [PageUrl(videosUrls.first.url)];
|
||||||
videoHeader.addAll(videosUrls.first.headers ?? {});
|
videoHeader.addAll(videosUrls.first.headers ?? {});
|
||||||
isOk = true;
|
isOk = true;
|
||||||
}
|
}
|
||||||
|
|
@ -140,12 +154,18 @@ Future<List<PageUrl>> downloadChapter(
|
||||||
|
|
||||||
if (pageUrls.isNotEmpty) {
|
if (pageUrls.isNotEmpty) {
|
||||||
bool cbzFileExist =
|
bool cbzFileExist =
|
||||||
await File(p.join(mangaDir!.path, "${chapter.name}.cbz")).exists() && ref.watch(saveAsCBZArchiveStateProvider);
|
await File(p.join(mangaDir!.path, "${chapter.name}.cbz")).exists() &&
|
||||||
bool mp4FileExist = await File(p.join(mangaDir.path, "$chapterName.mp4")).exists();
|
ref.watch(saveAsCBZArchiveStateProvider);
|
||||||
|
bool mp4FileExist =
|
||||||
|
await File(p.join(mangaDir.path, "$chapterName.mp4")).exists();
|
||||||
if (!cbzFileExist && isManga || !mp4FileExist && !isManga) {
|
if (!cbzFileExist && isManga || !mp4FileExist && !isManga) {
|
||||||
for (var index = 0; index < pageUrls.length; index++) {
|
for (var index = 0; index < pageUrls.length; index++) {
|
||||||
final path2 = Directory(p.join(path1.path, "downloads", isManga ? "Manga" : "Anime",
|
final path2 = Directory(p.join(
|
||||||
"${manga.source} (${manga.lang!.toUpperCase()})", manga.name!.replaceForbiddenCharacters('_')));
|
path1.path,
|
||||||
|
"downloads",
|
||||||
|
isManga ? "Manga" : "Anime",
|
||||||
|
"${manga.source} (${manga.lang!.toUpperCase()})",
|
||||||
|
manga.name!.replaceForbiddenCharacters('_')));
|
||||||
if (!(await path2.exists())) {
|
if (!(await path2.exists())) {
|
||||||
await path2.create(recursive: true);
|
await path2.create(recursive: true);
|
||||||
}
|
}
|
||||||
|
|
@ -156,7 +176,10 @@ Future<List<PageUrl>> downloadChapter(
|
||||||
}
|
}
|
||||||
final page = pageUrls[index];
|
final page = pageUrls[index];
|
||||||
final cookie = MClient.getCookiesPref(page.url);
|
final cookie = MClient.getCookiesPref(page.url);
|
||||||
final headers = isManga ? ref.watch(headersProvider(source: manga.source!, lang: manga.lang!)) : videoHeader;
|
final headers = isManga
|
||||||
|
? ref.watch(
|
||||||
|
headersProvider(source: manga.source!, lang: manga.lang!))
|
||||||
|
: videoHeader;
|
||||||
if (cookie.isNotEmpty) {
|
if (cookie.isNotEmpty) {
|
||||||
final userAgent = isar.settings.getSync(227)!.userAgent!;
|
final userAgent = isar.settings.getSync(227)!.userAgent!;
|
||||||
headers.addAll(cookie);
|
headers.addAll(cookie);
|
||||||
|
|
@ -166,7 +189,8 @@ Future<List<PageUrl>> downloadChapter(
|
||||||
pageHeaders.addAll(page.headers ?? {});
|
pageHeaders.addAll(page.headers ?? {});
|
||||||
|
|
||||||
if (isManga) {
|
if (isManga) {
|
||||||
final file = File(p.join(tempDir.path, "Mangayomi", finalPath, "${padIndex(index + 1)}.jpg"));
|
final file = File(p.join(tempDir.path, "Mangayomi", finalPath,
|
||||||
|
"${padIndex(index + 1)}.jpg"));
|
||||||
if (file.existsSync()) {
|
if (file.existsSync()) {
|
||||||
Directory(path.path).createSync(recursive: true);
|
Directory(path.path).createSync(recursive: true);
|
||||||
await file.copy(p.join(path.path, "${padIndex(index + 1)}.jpg"));
|
await file.copy(p.join(path.path, "${padIndex(index + 1)}.jpg"));
|
||||||
|
|
@ -175,7 +199,8 @@ Future<List<PageUrl>> downloadChapter(
|
||||||
if (!(await path.exists())) {
|
if (!(await path.exists())) {
|
||||||
await path.create();
|
await path.create();
|
||||||
}
|
}
|
||||||
if (!(await File(p.join(path.path, "${padIndex(index + 1)}.jpg")).exists())) {
|
if (!(await File(p.join(path.path, "${padIndex(index + 1)}.jpg"))
|
||||||
|
.exists())) {
|
||||||
tasks.add(DownloadTask(
|
tasks.add(DownloadTask(
|
||||||
taskId: page.url,
|
taskId: page.url,
|
||||||
headers: pageHeaders,
|
headers: pageHeaders,
|
||||||
|
|
@ -190,16 +215,21 @@ Future<List<PageUrl>> downloadChapter(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
final file = File(p.join(tempDir.path, "Mangayomi", finalPath, "$chapterName.mp4"));
|
final file = File(
|
||||||
|
p.join(tempDir.path, "Mangayomi", finalPath, "$chapterName.mp4"));
|
||||||
if (file.existsSync()) {
|
if (file.existsSync()) {
|
||||||
await file.copy(p.join(path.path, "$chapterName.mp4"));
|
await file.copy(p.join(path.path, "$chapterName.mp4"));
|
||||||
await file.delete();
|
await file.delete();
|
||||||
} else if (hasM3U8File) {
|
} else if (hasM3U8File) {
|
||||||
final tempFile = File(p.join(tempDir.path, "Mangayomi", finalPath, chapterName, "TS_${index + 1}.ts"));
|
final tempFile = File(p.join(tempDir.path, "Mangayomi", finalPath,
|
||||||
final file = File(p.join(path.path, chapterName, "TS_${index + 1}.ts"));
|
chapterName, "TS_${index + 1}.ts"));
|
||||||
|
final file =
|
||||||
|
File(p.join(path.path, chapterName, "TS_${index + 1}.ts"));
|
||||||
if (tempFile.existsSync()) {
|
if (tempFile.existsSync()) {
|
||||||
Directory(p.join(path.path, chapterName)).createSync(recursive: true);
|
Directory(p.join(path.path, chapterName))
|
||||||
await tempFile.copy(p.join(path.path, chapterName, "TS_${index + 1}.ts"));
|
.createSync(recursive: true);
|
||||||
|
await tempFile
|
||||||
|
.copy(p.join(path.path, chapterName, "TS_${index + 1}.ts"));
|
||||||
await tempFile.delete();
|
await tempFile.delete();
|
||||||
} else if (!(file.existsSync())) {
|
} else if (!(file.existsSync())) {
|
||||||
tasks.add(DownloadTask(
|
tasks.add(DownloadTask(
|
||||||
|
|
@ -264,7 +294,10 @@ Future<List<PageUrl>> downloadChapter(
|
||||||
if (succeeded == tasks.length) {
|
if (succeeded == tasks.length) {
|
||||||
await processConvert();
|
await processConvert();
|
||||||
}
|
}
|
||||||
bool isEmpty = isar.downloads.filter().chapterIdEqualTo(chapter.id!).isEmptySync();
|
bool isEmpty = isar.downloads
|
||||||
|
.filter()
|
||||||
|
.chapterIdEqualTo(chapter.id!)
|
||||||
|
.isEmptySync();
|
||||||
if (isEmpty) {
|
if (isEmpty) {
|
||||||
final download = Download(
|
final download = Download(
|
||||||
succeeded: succeeded,
|
succeeded: succeeded,
|
||||||
|
|
@ -279,7 +312,10 @@ Future<List<PageUrl>> downloadChapter(
|
||||||
isar.downloads.putSync(download..chapter.value = chapter);
|
isar.downloads.putSync(download..chapter.value = chapter);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
final download = isar.downloads.filter().chapterIdEqualTo(chapter.id!).findFirstSync()!;
|
final download = isar.downloads
|
||||||
|
.filter()
|
||||||
|
.chapterIdEqualTo(chapter.id!)
|
||||||
|
.findFirstSync()!;
|
||||||
isar.writeTxnSync(() {
|
isar.writeTxnSync(() {
|
||||||
isar.downloads.putSync(download
|
isar.downloads.putSync(download
|
||||||
..succeeded = succeeded
|
..succeeded = succeeded
|
||||||
|
|
@ -292,7 +328,10 @@ Future<List<PageUrl>> downloadChapter(
|
||||||
taskProgressCallback: (taskProgress) async {
|
taskProgressCallback: (taskProgress) async {
|
||||||
final progress = taskProgress.progress;
|
final progress = taskProgress.progress;
|
||||||
if (!isManga && !hasM3U8File) {
|
if (!isManga && !hasM3U8File) {
|
||||||
bool isEmpty = isar.downloads.filter().chapterIdEqualTo(chapter.id!).isEmptySync();
|
bool isEmpty = isar.downloads
|
||||||
|
.filter()
|
||||||
|
.chapterIdEqualTo(chapter.id!)
|
||||||
|
.isEmptySync();
|
||||||
if (isEmpty) {
|
if (isEmpty) {
|
||||||
final download = Download(
|
final download = Download(
|
||||||
succeeded: (progress * 100).toInt(),
|
succeeded: (progress * 100).toInt(),
|
||||||
|
|
@ -307,7 +346,10 @@ Future<List<PageUrl>> downloadChapter(
|
||||||
isar.downloads.putSync(download..chapter.value = chapter);
|
isar.downloads.putSync(download..chapter.value = chapter);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
final download = isar.downloads.filter().chapterIdEqualTo(chapter.id!).findFirstSync()!;
|
final download = isar.downloads
|
||||||
|
.filter()
|
||||||
|
.chapterIdEqualTo(chapter.id!)
|
||||||
|
.findFirstSync()!;
|
||||||
isar.writeTxnSync(() {
|
isar.writeTxnSync(() {
|
||||||
isar.downloads.putSync(download
|
isar.downloads.putSync(download
|
||||||
..succeeded = (progress * 100).toInt()
|
..succeeded = (progress * 100).toInt()
|
||||||
|
|
@ -317,11 +359,14 @@ Future<List<PageUrl>> downloadChapter(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (progress == 1.0) {
|
if (progress == 1.0) {
|
||||||
final file = File(p.join(tempDir.path, taskProgress.task.directory, taskProgress.task.filename));
|
final file = File(p.join(tempDir.path, taskProgress.task.directory,
|
||||||
|
taskProgress.task.filename));
|
||||||
if (hasM3U8File) {
|
if (hasM3U8File) {
|
||||||
final newFile = await file.copy(p.join(path!.path, chapterName, taskProgress.task.filename));
|
final newFile = await file.copy(
|
||||||
|
p.join(path!.path, chapterName, taskProgress.task.filename));
|
||||||
await file.delete();
|
await file.delete();
|
||||||
await m3u8Downloader?.processBytes(newFile, tsKey, tsIv, m3u8MediaSequence);
|
await m3u8Downloader?.processBytes(
|
||||||
|
newFile, tsKey, tsIv, m3u8MediaSequence);
|
||||||
} else {
|
} else {
|
||||||
await file.copy(p.join(path!.path, taskProgress.task.filename));
|
await file.copy(p.join(path!.path, taskProgress.task.filename));
|
||||||
await file.delete();
|
await file.delete();
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,11 @@ class MangaHomeScreen extends ConsumerStatefulWidget {
|
||||||
final bool isLatest;
|
final bool isLatest;
|
||||||
final String query;
|
final String query;
|
||||||
const MangaHomeScreen(
|
const MangaHomeScreen(
|
||||||
{required this.source, this.query = "", this.isSearch = false, this.isLatest = false, super.key});
|
{required this.source,
|
||||||
|
this.query = "",
|
||||||
|
this.isSearch = false,
|
||||||
|
this.isLatest = false,
|
||||||
|
super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
ConsumerState<MangaHomeScreen> createState() => _MangaHomeScreenState();
|
ConsumerState<MangaHomeScreen> createState() => _MangaHomeScreenState();
|
||||||
|
|
@ -86,9 +90,14 @@ class _MangaHomeScreenState extends ConsumerState<MangaHomeScreen> {
|
||||||
source: source,
|
source: source,
|
||||||
page: _page + 1,
|
page: _page + 1,
|
||||||
).future);
|
).future);
|
||||||
} else if (_selectedIndex == 2 && (_isSearch && _query.isNotEmpty) || _isFiltering) {
|
} else if (_selectedIndex == 2 && (_isSearch && _query.isNotEmpty) ||
|
||||||
mangaRes = await ref
|
_isFiltering) {
|
||||||
.watch(searchProvider(source: source, query: _query, page: _page + 1, filterList: filters).future);
|
mangaRes = await ref.watch(searchProvider(
|
||||||
|
source: source,
|
||||||
|
query: _query,
|
||||||
|
page: _page + 1,
|
||||||
|
filterList: filters)
|
||||||
|
.future);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (mangaRes!.list.isNotEmpty) {
|
if (mangaRes!.list.isNotEmpty) {
|
||||||
|
|
@ -115,8 +124,10 @@ class _MangaHomeScreenState extends ConsumerState<MangaHomeScreen> {
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final supportsLatest = ref.watch(supportsLatestProvider(source: source));
|
final supportsLatest = ref.watch(supportsLatestProvider(source: source));
|
||||||
final filterList = getFilterList(source: source);
|
final filterList = getFilterList(source: source);
|
||||||
if (_selectedIndex == 2 && (_isSearch && _query.isNotEmpty) || _isFiltering) {
|
if (_selectedIndex == 2 && (_isSearch && _query.isNotEmpty) ||
|
||||||
_getManga = ref.watch(searchProvider(source: source, query: _query, page: 1, filterList: filters));
|
_isFiltering) {
|
||||||
|
_getManga = ref.watch(searchProvider(
|
||||||
|
source: source, query: _query, page: 1, filterList: filters));
|
||||||
} else if (_selectedIndex == 1 && !_isSearch && _query.isEmpty) {
|
} else if (_selectedIndex == 1 && !_isSearch && _query.isEmpty) {
|
||||||
_getManga = ref.watch(getLatestUpdatesProvider(source: source, page: 1));
|
_getManga = ref.watch(getLatestUpdatesProvider(source: source, page: 1));
|
||||||
} else if (_selectedIndex == 0 && !_isSearch && _query.isEmpty) {
|
} else if (_selectedIndex == 0 && !_isSearch && _query.isEmpty) {
|
||||||
|
|
@ -125,7 +136,9 @@ class _MangaHomeScreenState extends ConsumerState<MangaHomeScreen> {
|
||||||
final l10n = context.l10n;
|
final l10n = context.l10n;
|
||||||
final displayType = ref.watch(mangaHomeDisplayTypeStateProvider);
|
final displayType = ref.watch(mangaHomeDisplayTypeStateProvider);
|
||||||
final displayTypeIcon = switch (displayType) {
|
final displayTypeIcon = switch (displayType) {
|
||||||
DisplayType.comfortableGrid || DisplayType.compactGrid => Icons.view_module,
|
DisplayType.comfortableGrid ||
|
||||||
|
DisplayType.compactGrid =>
|
||||||
|
Icons.view_module,
|
||||||
_ => Icons.view_list,
|
_ => Icons.view_list,
|
||||||
};
|
};
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
|
|
@ -179,13 +192,16 @@ class _MangaHomeScreenState extends ConsumerState<MangaHomeScreen> {
|
||||||
_isSearch = true;
|
_isSearch = true;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
icon: Icon(Icons.search, color: Theme.of(context).hintColor)),
|
icon:
|
||||||
|
Icon(Icons.search, color: Theme.of(context).hintColor)),
|
||||||
PopupMenuButton(
|
PopupMenuButton(
|
||||||
popUpAnimationStyle: popupAnimationStyle,
|
popUpAnimationStyle: popupAnimationStyle,
|
||||||
icon: Icon(displayTypeIcon),
|
icon: Icon(displayTypeIcon),
|
||||||
itemBuilder: (context) {
|
itemBuilder: (context) {
|
||||||
final displayType = ref.watch(mangaHomeDisplayTypeStateProvider);
|
final displayType =
|
||||||
final displayTypeNotifier = ref.read(mangaHomeDisplayTypeStateProvider.notifier);
|
ref.watch(mangaHomeDisplayTypeStateProvider);
|
||||||
|
final displayTypeNotifier =
|
||||||
|
ref.read(mangaHomeDisplayTypeStateProvider.notifier);
|
||||||
return [
|
return [
|
||||||
PopupMenuItem<int>(
|
PopupMenuItem<int>(
|
||||||
value: 0,
|
value: 0,
|
||||||
|
|
@ -242,11 +258,17 @@ class _MangaHomeScreenState extends ConsumerState<MangaHomeScreen> {
|
||||||
},
|
},
|
||||||
onSelected: (value) async {
|
onSelected: (value) async {
|
||||||
if (value == 0) {
|
if (value == 0) {
|
||||||
final baseUrl = ref.watch(sourceBaseUrlProvider(source: source));
|
final baseUrl =
|
||||||
Map<String, dynamic> data = {'url': baseUrl, 'sourceId': source.id.toString(), 'title': ''};
|
ref.watch(sourceBaseUrlProvider(source: source));
|
||||||
|
Map<String, dynamic> data = {
|
||||||
|
'url': baseUrl,
|
||||||
|
'sourceId': source.id.toString(),
|
||||||
|
'title': ''
|
||||||
|
};
|
||||||
context.push("/mangawebview", extra: data);
|
context.push("/mangawebview", extra: data);
|
||||||
} else {
|
} else {
|
||||||
final res = await context.push('/extension_detail', extra: source);
|
final res =
|
||||||
|
await context.push('/extension_detail', extra: source);
|
||||||
if (res != null && mounted) {
|
if (res != null && mounted) {
|
||||||
setState(() {
|
setState(() {
|
||||||
source = res as Source;
|
source = res as Source;
|
||||||
|
|
@ -284,7 +306,8 @@ class _MangaHomeScreenState extends ConsumerState<MangaHomeScreen> {
|
||||||
if (index == 2) {
|
if (index == 2) {
|
||||||
final result = await showModalBottomSheet(
|
final result = await showModalBottomSheet(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => StatefulBuilder(builder: (context, setState) {
|
builder: (context) =>
|
||||||
|
StatefulBuilder(builder: (context, setState) {
|
||||||
return Column(
|
return Column(
|
||||||
children: [
|
children: [
|
||||||
Padding(
|
Padding(
|
||||||
|
|
@ -294,20 +317,25 @@ class _MangaHomeScreenState extends ConsumerState<MangaHomeScreen> {
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
setState(() {
|
setState(() {
|
||||||
filters = getFilterList(source: source);
|
filters = getFilterList(
|
||||||
|
source: source);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
child: Text(l10n.reset),
|
child: Text(l10n.reset),
|
||||||
),
|
),
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
style: ElevatedButton.styleFrom(backgroundColor: context.primaryColor),
|
style: ElevatedButton.styleFrom(
|
||||||
|
backgroundColor:
|
||||||
|
context.primaryColor),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.pop(context, 'filter');
|
Navigator.pop(context, 'filter');
|
||||||
},
|
},
|
||||||
child: Text(
|
child: Text(
|
||||||
l10n.filter,
|
l10n.filter,
|
||||||
style: TextStyle(color: Theme.of(context).scaffoldBackgroundColor),
|
style: TextStyle(
|
||||||
|
color: Theme.of(context)
|
||||||
|
.scaffoldBackgroundColor),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
@ -339,8 +367,11 @@ class _MangaHomeScreenState extends ConsumerState<MangaHomeScreen> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
_getManga = ref
|
_getManga = ref.refresh(searchProvider(
|
||||||
.refresh(searchProvider(source: source, query: _query, page: 1, filterList: filters));
|
source: source,
|
||||||
|
query: _query,
|
||||||
|
page: 1,
|
||||||
|
filterList: filters));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_mangaList.clear();
|
_mangaList.clear();
|
||||||
|
|
@ -385,7 +416,8 @@ class _MangaHomeScreenState extends ConsumerState<MangaHomeScreen> {
|
||||||
_mangaList.addAll(data.list);
|
_mangaList.addAll(data.list);
|
||||||
}
|
}
|
||||||
Widget buildProgressIndicator() {
|
Widget buildProgressIndicator() {
|
||||||
return !(data!.list.isNotEmpty && (data.hasNextPage || _hasNextPage))
|
return !(data!.list.isNotEmpty &&
|
||||||
|
(data.hasNextPage || _hasNextPage))
|
||||||
? Container()
|
? Container()
|
||||||
: _isLoading
|
: _isLoading
|
||||||
? const Center(
|
? const Center(
|
||||||
|
|
@ -401,7 +433,9 @@ class _MangaHomeScreenState extends ConsumerState<MangaHomeScreen> {
|
||||||
padding: const EdgeInsets.all(4),
|
padding: const EdgeInsets.all(4),
|
||||||
child: ElevatedButton(
|
child: ElevatedButton(
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(5))),
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius:
|
||||||
|
BorderRadius.circular(5))),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
if (!_getManga!.isLoading) {
|
if (!_getManga!.isLoading) {
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
|
|
@ -420,15 +454,19 @@ class _MangaHomeScreenState extends ConsumerState<MangaHomeScreen> {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment:
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
CrossAxisAlignment.center,
|
||||||
|
mainAxisAlignment:
|
||||||
|
MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
l10n.load_more,
|
l10n.load_more,
|
||||||
style: const TextStyle(overflow: TextOverflow.ellipsis),
|
style: const TextStyle(
|
||||||
|
overflow: TextOverflow.ellipsis),
|
||||||
maxLines: 2,
|
maxLines: 2,
|
||||||
),
|
),
|
||||||
const Icon(Icons.arrow_forward_outlined),
|
const Icon(
|
||||||
|
Icons.arrow_forward_outlined),
|
||||||
],
|
],
|
||||||
)),
|
)),
|
||||||
);
|
);
|
||||||
|
|
@ -438,8 +476,12 @@ class _MangaHomeScreenState extends ConsumerState<MangaHomeScreen> {
|
||||||
return Center(child: Text(l10n.no_result));
|
return Center(child: Text(l10n.no_result));
|
||||||
}
|
}
|
||||||
_scrollController.addListener(() {
|
_scrollController.addListener(() {
|
||||||
if (_scrollController.position.pixels == _scrollController.position.maxScrollExtent) {
|
if (_scrollController.position.pixels ==
|
||||||
if (_mangaList.isNotEmpty && (_hasNextPage) && !_isLoading && !_getManga!.isLoading) {
|
_scrollController.position.maxScrollExtent) {
|
||||||
|
if (_mangaList.isNotEmpty &&
|
||||||
|
(_hasNextPage) &&
|
||||||
|
!_isLoading &&
|
||||||
|
!_getManga!.isLoading) {
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_isLoading = true;
|
_isLoading = true;
|
||||||
|
|
@ -457,9 +499,13 @@ class _MangaHomeScreenState extends ConsumerState<MangaHomeScreen> {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
_length = source.isFullData! ? _fullDataLength : _mangaList.length;
|
_length =
|
||||||
_length = (_mangaList.length < _length ? _mangaList.length : _length);
|
source.isFullData! ? _fullDataLength : _mangaList.length;
|
||||||
final isComfortableGrid = displayType == DisplayType.comfortableGrid;
|
_length = (_mangaList.length < _length
|
||||||
|
? _mangaList.length
|
||||||
|
: _length);
|
||||||
|
final isComfortableGrid =
|
||||||
|
displayType == DisplayType.comfortableGrid;
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.only(top: 10),
|
padding: const EdgeInsets.only(top: 10),
|
||||||
child: Column(
|
child: Column(
|
||||||
|
|
@ -474,16 +520,21 @@ class _MangaHomeScreenState extends ConsumerState<MangaHomeScreen> {
|
||||||
return buildProgressIndicator();
|
return buildProgressIndicator();
|
||||||
}
|
}
|
||||||
return MangaHomeImageCardListTile(
|
return MangaHomeImageCardListTile(
|
||||||
isManga: source.isManga ?? true, manga: _mangaList[index], source: source);
|
isManga: source.isManga ?? true,
|
||||||
|
manga: _mangaList[index],
|
||||||
|
source: source);
|
||||||
})
|
})
|
||||||
: Consumer(builder: (context, ref, child) {
|
: Consumer(builder: (context, ref, child) {
|
||||||
final gridSize = ref.watch(libraryGridSizeStateProvider(isManga: source.isManga!));
|
final gridSize = ref.watch(
|
||||||
|
libraryGridSizeStateProvider(
|
||||||
|
isManga: source.isManga!));
|
||||||
|
|
||||||
return GridViewWidget(
|
return GridViewWidget(
|
||||||
gridSize: gridSize,
|
gridSize: gridSize,
|
||||||
controller: _scrollController,
|
controller: _scrollController,
|
||||||
itemCount: _length + 1,
|
itemCount: _length + 1,
|
||||||
childAspectRatio: isComfortableGrid ? 0.642 : 0.69,
|
childAspectRatio:
|
||||||
|
isComfortableGrid ? 0.642 : 0.69,
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
if (index == _length) {
|
if (index == _length) {
|
||||||
return buildProgressIndicator();
|
return buildProgressIndicator();
|
||||||
|
|
@ -514,12 +565,22 @@ class _MangaHomeScreenState extends ConsumerState<MangaHomeScreen> {
|
||||||
children: [
|
children: [
|
||||||
IconButton(
|
IconButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
if (_selectedIndex == 2 && (_isSearch && _query.isNotEmpty) || _isFiltering) {
|
if (_selectedIndex == 2 &&
|
||||||
ref.invalidate(
|
(_isSearch && _query.isNotEmpty) ||
|
||||||
searchProvider(source: source, query: _query, page: 1, filterList: filters));
|
_isFiltering) {
|
||||||
} else if (_selectedIndex == 1 && !_isSearch && _query.isEmpty) {
|
ref.invalidate(searchProvider(
|
||||||
ref.invalidate(getLatestUpdatesProvider(source: source, page: 1));
|
source: source,
|
||||||
} else if (_selectedIndex == 0 && !_isSearch && _query.isEmpty) {
|
query: _query,
|
||||||
|
page: 1,
|
||||||
|
filterList: filters));
|
||||||
|
} else if (_selectedIndex == 1 &&
|
||||||
|
!_isSearch &&
|
||||||
|
_query.isEmpty) {
|
||||||
|
ref.invalidate(getLatestUpdatesProvider(
|
||||||
|
source: source, page: 1));
|
||||||
|
} else if (_selectedIndex == 0 &&
|
||||||
|
!_isSearch &&
|
||||||
|
_query.isEmpty) {
|
||||||
ref.invalidate(getPopularProvider(
|
ref.invalidate(getPopularProvider(
|
||||||
source: source,
|
source: source,
|
||||||
page: 1,
|
page: 1,
|
||||||
|
|
@ -537,12 +598,14 @@ class _MangaHomeScreenState extends ConsumerState<MangaHomeScreen> {
|
||||||
children: [
|
children: [
|
||||||
IconButton(
|
IconButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
final baseUrl = ref.watch(sourceBaseUrlProvider(source: source));
|
final baseUrl = ref.watch(
|
||||||
|
sourceBaseUrlProvider(source: source));
|
||||||
Map<String, dynamic> data = {
|
Map<String, dynamic> data = {
|
||||||
'url': baseUrl,
|
'url': baseUrl,
|
||||||
'sourceId': source.id.toString(),
|
'sourceId': source.id.toString(),
|
||||||
'title': '',
|
'title': '',
|
||||||
"hasCloudFlare": source.hasCloudflare ?? false
|
"hasCloudFlare":
|
||||||
|
source.hasCloudflare ?? false
|
||||||
};
|
};
|
||||||
context.push("/mangawebview", extra: data);
|
context.push("/mangawebview", extra: data);
|
||||||
},
|
},
|
||||||
|
|
@ -580,7 +643,11 @@ class MangaHomeImageCard extends ConsumerStatefulWidget {
|
||||||
final Source source;
|
final Source source;
|
||||||
final bool isComfortableGrid;
|
final bool isComfortableGrid;
|
||||||
const MangaHomeImageCard(
|
const MangaHomeImageCard(
|
||||||
{super.key, required this.manga, required this.source, required this.isManga, required this.isComfortableGrid});
|
{super.key,
|
||||||
|
required this.manga,
|
||||||
|
required this.source,
|
||||||
|
required this.isManga,
|
||||||
|
required this.isComfortableGrid});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
ConsumerState<MangaHomeImageCard> createState() => _MangaHomeImageCardState();
|
ConsumerState<MangaHomeImageCard> createState() => _MangaHomeImageCardState();
|
||||||
|
|
@ -607,19 +674,28 @@ class MangaHomeImageCardListTile extends ConsumerStatefulWidget {
|
||||||
final MManga manga;
|
final MManga manga;
|
||||||
final bool isManga;
|
final bool isManga;
|
||||||
final Source source;
|
final Source source;
|
||||||
const MangaHomeImageCardListTile({super.key, required this.manga, required this.source, required this.isManga});
|
const MangaHomeImageCardListTile(
|
||||||
|
{super.key,
|
||||||
|
required this.manga,
|
||||||
|
required this.source,
|
||||||
|
required this.isManga});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
ConsumerState<MangaHomeImageCardListTile> createState() => _MangaHomeImageCardListTileState();
|
ConsumerState<MangaHomeImageCardListTile> createState() =>
|
||||||
|
_MangaHomeImageCardListTileState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _MangaHomeImageCardListTileState extends ConsumerState<MangaHomeImageCardListTile>
|
class _MangaHomeImageCardListTileState
|
||||||
|
extends ConsumerState<MangaHomeImageCardListTile>
|
||||||
with AutomaticKeepAliveClientMixin<MangaHomeImageCardListTile> {
|
with AutomaticKeepAliveClientMixin<MangaHomeImageCardListTile> {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
super.build(context);
|
super.build(context);
|
||||||
|
|
||||||
return MangaImageCardListTileWidget(getMangaDetail: widget.manga, source: widget.source, isManga: widget.isManga);
|
return MangaImageCardListTileWidget(
|
||||||
|
getMangaDetail: widget.manga,
|
||||||
|
source: widget.source,
|
||||||
|
isManga: widget.isManga);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,8 @@ import 'package:mangayomi/utils/extensions/build_context_extensions.dart';
|
||||||
class FilterWidget extends StatelessWidget {
|
class FilterWidget extends StatelessWidget {
|
||||||
final List<dynamic> filterList;
|
final List<dynamic> filterList;
|
||||||
final Function(List<dynamic>) onChanged;
|
final Function(List<dynamic>) onChanged;
|
||||||
const FilterWidget({super.key, required this.onChanged, required this.filterList});
|
const FilterWidget(
|
||||||
|
{super.key, required this.onChanged, required this.filterList});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
|
@ -83,14 +84,18 @@ class FilterWidget extends StatelessWidget {
|
||||||
final selected = filterState.values[filterState.state.index] == e;
|
final selected = filterState.values[filterState.state.index] == e;
|
||||||
return ListTile(
|
return ListTile(
|
||||||
dense: true,
|
dense: true,
|
||||||
leading: Icon(ascending ? Icons.arrow_upward_rounded : Icons.arrow_downward_rounded,
|
leading: Icon(
|
||||||
|
ascending
|
||||||
|
? Icons.arrow_upward_rounded
|
||||||
|
: Icons.arrow_downward_rounded,
|
||||||
color: selected ? null : Colors.transparent),
|
color: selected ? null : Colors.transparent),
|
||||||
title: Text(e.name),
|
title: Text(e.name),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
if (selected) {
|
if (selected) {
|
||||||
filterState.state.ascending = !ascending;
|
filterState.state.ascending = !ascending;
|
||||||
} else {
|
} else {
|
||||||
filterState.state.index = filterState.values.indexWhere((element) => element == e);
|
filterState.state.index = filterState.values
|
||||||
|
.indexWhere((element) => element == e);
|
||||||
}
|
}
|
||||||
filterList[idx] = filterState;
|
filterList[idx] = filterState;
|
||||||
onChanged(filterList);
|
onChanged(filterList);
|
||||||
|
|
@ -113,20 +118,24 @@ class FilterWidget extends StatelessWidget {
|
||||||
Expanded(
|
Expanded(
|
||||||
child: DropdownButtonHideUnderline(
|
child: DropdownButtonHideUnderline(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 25),
|
padding: const EdgeInsets.symmetric(
|
||||||
|
vertical: 8, horizontal: 25),
|
||||||
child: DropdownButton(
|
child: DropdownButton(
|
||||||
icon: const Icon(Icons.keyboard_arrow_down),
|
icon: const Icon(Icons.keyboard_arrow_down),
|
||||||
isExpanded: true,
|
isExpanded: true,
|
||||||
value: filterState.values[filterState.state],
|
value: filterState.values[filterState.state],
|
||||||
hint: Text(filterState.name, style: const TextStyle(fontSize: 13)),
|
hint: Text(filterState.name,
|
||||||
|
style: const TextStyle(fontSize: 13)),
|
||||||
items: filterState.values
|
items: filterState.values
|
||||||
.map((e) => DropdownMenuItem(
|
.map((e) => DropdownMenuItem(
|
||||||
value: e,
|
value: e,
|
||||||
child: Text(e.name, style: const TextStyle(fontSize: 13)),
|
child: Text(e.name,
|
||||||
|
style: const TextStyle(fontSize: 13)),
|
||||||
))
|
))
|
||||||
.toList(),
|
.toList(),
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
filterState.state = filterState.values.indexWhere((element) => element == value);
|
filterState.state = filterState.values
|
||||||
|
.indexWhere((element) => element == value);
|
||||||
onChanged(filterList);
|
onChanged(filterList);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|
@ -147,10 +156,15 @@ class SeachFormTextFieldWidget extends StatefulWidget {
|
||||||
final String labelText;
|
final String labelText;
|
||||||
final String text;
|
final String text;
|
||||||
final Function(String) onChanged;
|
final Function(String) onChanged;
|
||||||
const SeachFormTextFieldWidget({super.key, required this.text, required this.onChanged, required this.labelText});
|
const SeachFormTextFieldWidget(
|
||||||
|
{super.key,
|
||||||
|
required this.text,
|
||||||
|
required this.onChanged,
|
||||||
|
required this.labelText});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<SeachFormTextFieldWidget> createState() => _SeachFormTextFieldWidgetState();
|
State<SeachFormTextFieldWidget> createState() =>
|
||||||
|
_SeachFormTextFieldWidgetState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _SeachFormTextFieldWidgetState extends State<SeachFormTextFieldWidget> {
|
class _SeachFormTextFieldWidgetState extends State<SeachFormTextFieldWidget> {
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,11 @@ class MangasCardSelector extends StatelessWidget {
|
||||||
final bool selected;
|
final bool selected;
|
||||||
final VoidCallback onPressed;
|
final VoidCallback onPressed;
|
||||||
const MangasCardSelector(
|
const MangasCardSelector(
|
||||||
{super.key, required this.text, required this.icon, required this.selected, required this.onPressed});
|
{super.key,
|
||||||
|
required this.text,
|
||||||
|
required this.icon,
|
||||||
|
required this.selected,
|
||||||
|
required this.onPressed});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
|
@ -18,7 +22,8 @@ class MangasCardSelector extends StatelessWidget {
|
||||||
padding: const EdgeInsets.all(0),
|
padding: const EdgeInsets.all(0),
|
||||||
side: BorderSide(width: 0.6, color: context.primaryColor),
|
side: BorderSide(width: 0.6, color: context.primaryColor),
|
||||||
backgroundColor: selected ? context.primaryColor : null,
|
backgroundColor: selected ? context.primaryColor : null,
|
||||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(7)),
|
shape:
|
||||||
|
RoundedRectangleBorder(borderRadius: BorderRadius.circular(7)),
|
||||||
),
|
),
|
||||||
onPressed: onPressed,
|
onPressed: onPressed,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
|
|
|
||||||
|
|
@ -27,14 +27,17 @@ class DoubleColummView extends StatefulWidget {
|
||||||
State<DoubleColummView> createState() => _DoubleColummViewState();
|
State<DoubleColummView> createState() => _DoubleColummViewState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _DoubleColummViewState extends State<DoubleColummView> with TickerProviderStateMixin {
|
class _DoubleColummViewState extends State<DoubleColummView>
|
||||||
|
with TickerProviderStateMixin {
|
||||||
late AnimationController _scaleAnimationController;
|
late AnimationController _scaleAnimationController;
|
||||||
late Animation<double> _animation;
|
late Animation<double> _animation;
|
||||||
Alignment _scalePosition = Alignment.center;
|
Alignment _scalePosition = Alignment.center;
|
||||||
final PhotoViewController _photoViewController = PhotoViewController();
|
final PhotoViewController _photoViewController = PhotoViewController();
|
||||||
final PhotoViewScaleStateController _photoViewScaleStateController = PhotoViewScaleStateController();
|
final PhotoViewScaleStateController _photoViewScaleStateController =
|
||||||
|
PhotoViewScaleStateController();
|
||||||
Duration? _doubleTapAnimationDuration() {
|
Duration? _doubleTapAnimationDuration() {
|
||||||
int doubleTapAnimationValue = isar.settings.getSync(227)!.doubleTapAnimationSpeed!;
|
int doubleTapAnimationValue =
|
||||||
|
isar.settings.getSync(227)!.doubleTapAnimationSpeed!;
|
||||||
if (doubleTapAnimationValue == 0) {
|
if (doubleTapAnimationValue == 0) {
|
||||||
return const Duration(milliseconds: 10);
|
return const Duration(milliseconds: 10);
|
||||||
} else if (doubleTapAnimationValue == 1) {
|
} else if (doubleTapAnimationValue == 1) {
|
||||||
|
|
@ -43,7 +46,8 @@ class _DoubleColummViewState extends State<DoubleColummView> with TickerProvider
|
||||||
return const Duration(milliseconds: 200);
|
return const Duration(milliseconds: 200);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onScaleEnd(BuildContext context, ScaleEndDetails details, PhotoViewControllerValue controllerValue) {
|
void _onScaleEnd(BuildContext context, ScaleEndDetails details,
|
||||||
|
PhotoViewControllerValue controllerValue) {
|
||||||
if (controllerValue.scale! < 1) {
|
if (controllerValue.scale! < 1) {
|
||||||
_photoViewScaleStateController.reset();
|
_photoViewScaleStateController.reset();
|
||||||
}
|
}
|
||||||
|
|
@ -52,15 +56,16 @@ class _DoubleColummViewState extends State<DoubleColummView> with TickerProvider
|
||||||
double get pixelRatio => View.of(context).devicePixelRatio;
|
double get pixelRatio => View.of(context).devicePixelRatio;
|
||||||
Size get size => View.of(context).physicalSize / pixelRatio;
|
Size get size => View.of(context).physicalSize / pixelRatio;
|
||||||
Alignment _computeAlignmentByTapOffset(Offset offset) {
|
Alignment _computeAlignmentByTapOffset(Offset offset) {
|
||||||
return Alignment(
|
return Alignment((offset.dx - size.width / 2) / (size.width / 2),
|
||||||
(offset.dx - size.width / 2) / (size.width / 2), (offset.dy - size.height / 2) / (size.height / 2));
|
(offset.dy - size.height / 2) / (size.height / 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
_scaleAnimationController = AnimationController(duration: _doubleTapAnimationDuration(), vsync: this);
|
_scaleAnimationController = AnimationController(
|
||||||
_animation =
|
duration: _doubleTapAnimationDuration(), vsync: this);
|
||||||
Tween(begin: 1.0, end: 2.0).animate(CurvedAnimation(curve: Curves.ease, parent: _scaleAnimationController));
|
_animation = Tween(begin: 1.0, end: 2.0).animate(
|
||||||
|
CurvedAnimation(curve: Curves.ease, parent: _scaleAnimationController));
|
||||||
_animation.addListener(() {
|
_animation.addListener(() {
|
||||||
_photoViewController.scale = _animation.value;
|
_photoViewController.scale = _animation.value;
|
||||||
});
|
});
|
||||||
|
|
@ -122,32 +127,42 @@ class _DoubleColummViewState extends State<DoubleColummView> with TickerProvider
|
||||||
child: ImageViewPaged(
|
child: ImageViewPaged(
|
||||||
data: widget.datas[0]!,
|
data: widget.datas[0]!,
|
||||||
loadStateChanged: (state) {
|
loadStateChanged: (state) {
|
||||||
if (state.extendedImageLoadState == LoadState.loading) {
|
if (state.extendedImageLoadState ==
|
||||||
final ImageChunkEvent? loadingProgress = state.loadingProgress;
|
LoadState.loading) {
|
||||||
final double progress = loadingProgress?.expectedTotalBytes != null
|
final ImageChunkEvent? loadingProgress =
|
||||||
? loadingProgress!.cumulativeBytesLoaded / loadingProgress.expectedTotalBytes!
|
state.loadingProgress;
|
||||||
: 0;
|
final double progress =
|
||||||
|
loadingProgress?.expectedTotalBytes != null
|
||||||
|
? loadingProgress!.cumulativeBytesLoaded /
|
||||||
|
loadingProgress.expectedTotalBytes!
|
||||||
|
: 0;
|
||||||
return Container(
|
return Container(
|
||||||
color: getBackgroundColor(widget.backgroundColor),
|
color: getBackgroundColor(widget.backgroundColor),
|
||||||
height: context.height(0.8),
|
height: context.height(0.8),
|
||||||
child: CircularProgressIndicatorAnimateRotate(progress: progress),
|
child: CircularProgressIndicatorAnimateRotate(
|
||||||
|
progress: progress),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (state.extendedImageLoadState == LoadState.completed) {
|
if (state.extendedImageLoadState ==
|
||||||
|
LoadState.completed) {
|
||||||
widget.isFailedToLoadImage(false);
|
widget.isFailedToLoadImage(false);
|
||||||
return Image(image: state.imageProvider);
|
return Image(image: state.imageProvider);
|
||||||
}
|
}
|
||||||
if (state.extendedImageLoadState == LoadState.failed) {
|
if (state.extendedImageLoadState ==
|
||||||
|
LoadState.failed) {
|
||||||
widget.isFailedToLoadImage(true);
|
widget.isFailedToLoadImage(true);
|
||||||
return Container(
|
return Container(
|
||||||
color: getBackgroundColor(widget.backgroundColor),
|
color:
|
||||||
|
getBackgroundColor(widget.backgroundColor),
|
||||||
height: context.height(0.8),
|
height: context.height(0.8),
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
l10n.image_loading_error,
|
l10n.image_loading_error,
|
||||||
style: TextStyle(color: Colors.white.withValues(alpha: 0.7)),
|
style: TextStyle(
|
||||||
|
color: Colors.white
|
||||||
|
.withValues(alpha: 0.7)),
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
|
@ -162,9 +177,14 @@ class _DoubleColummViewState extends State<DoubleColummView> with TickerProvider
|
||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: context.primaryColor, borderRadius: BorderRadius.circular(30)),
|
color: context.primaryColor,
|
||||||
|
borderRadius:
|
||||||
|
BorderRadius.circular(30)),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16),
|
padding:
|
||||||
|
const EdgeInsets.symmetric(
|
||||||
|
vertical: 8,
|
||||||
|
horizontal: 16),
|
||||||
child: Text(
|
child: Text(
|
||||||
l10n.retry,
|
l10n.retry,
|
||||||
),
|
),
|
||||||
|
|
@ -176,7 +196,8 @@ class _DoubleColummViewState extends State<DoubleColummView> with TickerProvider
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
onLongPressData: (datas) => widget.onLongPressData.call(datas),
|
onLongPressData: (datas) =>
|
||||||
|
widget.onLongPressData.call(datas),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
// if (widget.datas[1] != null) const SizedBox(width: 10),
|
// if (widget.datas[1] != null) const SizedBox(width: 10),
|
||||||
|
|
@ -185,32 +206,42 @@ class _DoubleColummViewState extends State<DoubleColummView> with TickerProvider
|
||||||
child: ImageViewPaged(
|
child: ImageViewPaged(
|
||||||
data: widget.datas[1]!,
|
data: widget.datas[1]!,
|
||||||
loadStateChanged: (state) {
|
loadStateChanged: (state) {
|
||||||
if (state.extendedImageLoadState == LoadState.loading) {
|
if (state.extendedImageLoadState ==
|
||||||
final ImageChunkEvent? loadingProgress = state.loadingProgress;
|
LoadState.loading) {
|
||||||
final double progress = loadingProgress?.expectedTotalBytes != null
|
final ImageChunkEvent? loadingProgress =
|
||||||
? loadingProgress!.cumulativeBytesLoaded / loadingProgress.expectedTotalBytes!
|
state.loadingProgress;
|
||||||
: 0;
|
final double progress =
|
||||||
|
loadingProgress?.expectedTotalBytes != null
|
||||||
|
? loadingProgress!.cumulativeBytesLoaded /
|
||||||
|
loadingProgress.expectedTotalBytes!
|
||||||
|
: 0;
|
||||||
return Container(
|
return Container(
|
||||||
color: getBackgroundColor(widget.backgroundColor),
|
color: getBackgroundColor(widget.backgroundColor),
|
||||||
height: context.height(0.8),
|
height: context.height(0.8),
|
||||||
child: CircularProgressIndicatorAnimateRotate(progress: progress),
|
child: CircularProgressIndicatorAnimateRotate(
|
||||||
|
progress: progress),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (state.extendedImageLoadState == LoadState.completed) {
|
if (state.extendedImageLoadState ==
|
||||||
|
LoadState.completed) {
|
||||||
widget.isFailedToLoadImage(false);
|
widget.isFailedToLoadImage(false);
|
||||||
return Image(image: state.imageProvider);
|
return Image(image: state.imageProvider);
|
||||||
}
|
}
|
||||||
if (state.extendedImageLoadState == LoadState.failed) {
|
if (state.extendedImageLoadState ==
|
||||||
|
LoadState.failed) {
|
||||||
widget.isFailedToLoadImage(true);
|
widget.isFailedToLoadImage(true);
|
||||||
return Container(
|
return Container(
|
||||||
color: getBackgroundColor(widget.backgroundColor),
|
color:
|
||||||
|
getBackgroundColor(widget.backgroundColor),
|
||||||
height: context.height(0.8),
|
height: context.height(0.8),
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
l10n.image_loading_error,
|
l10n.image_loading_error,
|
||||||
style: TextStyle(color: Colors.white.withValues(alpha: 0.7)),
|
style: TextStyle(
|
||||||
|
color: Colors.white
|
||||||
|
.withValues(alpha: 0.7)),
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
|
@ -225,9 +256,14 @@ class _DoubleColummViewState extends State<DoubleColummView> with TickerProvider
|
||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: context.primaryColor, borderRadius: BorderRadius.circular(30)),
|
color: context.primaryColor,
|
||||||
|
borderRadius:
|
||||||
|
BorderRadius.circular(30)),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16),
|
padding:
|
||||||
|
const EdgeInsets.symmetric(
|
||||||
|
vertical: 8,
|
||||||
|
horizontal: 16),
|
||||||
child: Text(
|
child: Text(
|
||||||
l10n.retry,
|
l10n.retry,
|
||||||
),
|
),
|
||||||
|
|
@ -239,7 +275,8 @@ class _DoubleColummViewState extends State<DoubleColummView> with TickerProvider
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
onLongPressData: (datas) => widget.onLongPressData.call(datas),
|
onLongPressData: (datas) =>
|
||||||
|
widget.onLongPressData.call(datas),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -39,14 +39,18 @@ class DoubleColummVerticalView extends StatelessWidget {
|
||||||
data: datas[0]!,
|
data: datas[0]!,
|
||||||
loadStateChanged: (state) {
|
loadStateChanged: (state) {
|
||||||
if (state.extendedImageLoadState == LoadState.loading) {
|
if (state.extendedImageLoadState == LoadState.loading) {
|
||||||
final ImageChunkEvent? loadingProgress = state.loadingProgress;
|
final ImageChunkEvent? loadingProgress =
|
||||||
final double progress = loadingProgress?.expectedTotalBytes != null
|
state.loadingProgress;
|
||||||
? loadingProgress!.cumulativeBytesLoaded / loadingProgress.expectedTotalBytes!
|
final double progress =
|
||||||
: 0;
|
loadingProgress?.expectedTotalBytes != null
|
||||||
|
? loadingProgress!.cumulativeBytesLoaded /
|
||||||
|
loadingProgress.expectedTotalBytes!
|
||||||
|
: 0;
|
||||||
return Container(
|
return Container(
|
||||||
color: getBackgroundColor(backgroundColor),
|
color: getBackgroundColor(backgroundColor),
|
||||||
height: context.height(0.8),
|
height: context.height(0.8),
|
||||||
child: CircularProgressIndicatorAnimateRotate(progress: progress),
|
child: CircularProgressIndicatorAnimateRotate(
|
||||||
|
progress: progress),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (state.extendedImageLoadState == LoadState.completed) {
|
if (state.extendedImageLoadState == LoadState.completed) {
|
||||||
|
|
@ -63,7 +67,8 @@ class DoubleColummVerticalView extends StatelessWidget {
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
l10n.image_loading_error,
|
l10n.image_loading_error,
|
||||||
style: TextStyle(color: Colors.white.withValues(alpha: 0.7)),
|
style: TextStyle(
|
||||||
|
color: Colors.white.withValues(alpha: 0.7)),
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
|
@ -78,9 +83,12 @@ class DoubleColummVerticalView extends StatelessWidget {
|
||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: context.primaryColor, borderRadius: BorderRadius.circular(30)),
|
color: context.primaryColor,
|
||||||
|
borderRadius:
|
||||||
|
BorderRadius.circular(30)),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16),
|
padding: const EdgeInsets.symmetric(
|
||||||
|
vertical: 8, horizontal: 16),
|
||||||
child: Text(
|
child: Text(
|
||||||
l10n.retry,
|
l10n.retry,
|
||||||
),
|
),
|
||||||
|
|
@ -102,14 +110,18 @@ class DoubleColummVerticalView extends StatelessWidget {
|
||||||
data: datas[1]!,
|
data: datas[1]!,
|
||||||
loadStateChanged: (state) {
|
loadStateChanged: (state) {
|
||||||
if (state.extendedImageLoadState == LoadState.loading) {
|
if (state.extendedImageLoadState == LoadState.loading) {
|
||||||
final ImageChunkEvent? loadingProgress = state.loadingProgress;
|
final ImageChunkEvent? loadingProgress =
|
||||||
final double progress = loadingProgress?.expectedTotalBytes != null
|
state.loadingProgress;
|
||||||
? loadingProgress!.cumulativeBytesLoaded / loadingProgress.expectedTotalBytes!
|
final double progress =
|
||||||
: 0;
|
loadingProgress?.expectedTotalBytes != null
|
||||||
|
? loadingProgress!.cumulativeBytesLoaded /
|
||||||
|
loadingProgress.expectedTotalBytes!
|
||||||
|
: 0;
|
||||||
return Container(
|
return Container(
|
||||||
color: getBackgroundColor(backgroundColor),
|
color: getBackgroundColor(backgroundColor),
|
||||||
height: context.height(0.8),
|
height: context.height(0.8),
|
||||||
child: CircularProgressIndicatorAnimateRotate(progress: progress),
|
child: CircularProgressIndicatorAnimateRotate(
|
||||||
|
progress: progress),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (state.extendedImageLoadState == LoadState.completed) {
|
if (state.extendedImageLoadState == LoadState.completed) {
|
||||||
|
|
@ -126,7 +138,8 @@ class DoubleColummVerticalView extends StatelessWidget {
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
l10n.image_loading_error,
|
l10n.image_loading_error,
|
||||||
style: TextStyle(color: Colors.white.withValues(alpha: 0.7)),
|
style: TextStyle(
|
||||||
|
color: Colors.white.withValues(alpha: 0.7)),
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
|
@ -141,9 +154,12 @@ class DoubleColummVerticalView extends StatelessWidget {
|
||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: context.primaryColor, borderRadius: BorderRadius.circular(30)),
|
color: context.primaryColor,
|
||||||
|
borderRadius:
|
||||||
|
BorderRadius.circular(30)),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16),
|
padding: const EdgeInsets.symmetric(
|
||||||
|
vertical: 8, horizontal: 16),
|
||||||
child: Text(
|
child: Text(
|
||||||
l10n.retry,
|
l10n.retry,
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,8 @@ class ImageViewPaged extends ConsumerWidget {
|
||||||
final Function(UChapDataPreload data) onLongPressData;
|
final Function(UChapDataPreload data) onLongPressData;
|
||||||
final Widget? Function(ExtendedImageState state) loadStateChanged;
|
final Widget? Function(ExtendedImageState state) loadStateChanged;
|
||||||
final Function(ExtendedImageGestureState state)? onDoubleTap;
|
final Function(ExtendedImageGestureState state)? onDoubleTap;
|
||||||
final GestureConfig Function(ExtendedImageState state)? initGestureConfigHandler;
|
final GestureConfig Function(ExtendedImageState state)?
|
||||||
|
initGestureConfigHandler;
|
||||||
const ImageViewPaged({
|
const ImageViewPaged({
|
||||||
super.key,
|
super.key,
|
||||||
required this.data,
|
required this.data,
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,8 @@ class ImageViewVertical extends ConsumerWidget {
|
||||||
if (state.extendedImageLoadState == LoadState.loading) {
|
if (state.extendedImageLoadState == LoadState.loading) {
|
||||||
final ImageChunkEvent? loadingProgress = state.loadingProgress;
|
final ImageChunkEvent? loadingProgress = state.loadingProgress;
|
||||||
final double progress = loadingProgress?.expectedTotalBytes != null
|
final double progress = loadingProgress?.expectedTotalBytes != null
|
||||||
? loadingProgress!.cumulativeBytesLoaded / loadingProgress.expectedTotalBytes!
|
? loadingProgress!.cumulativeBytesLoaded /
|
||||||
|
loadingProgress.expectedTotalBytes!
|
||||||
: 0;
|
: 0;
|
||||||
return Container(
|
return Container(
|
||||||
color: Colors.black,
|
color: Colors.black,
|
||||||
|
|
@ -59,7 +60,8 @@ class ImageViewVertical extends ConsumerWidget {
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Text(context.l10n.image_loading_error,
|
Text(context.l10n.image_loading_error,
|
||||||
style: TextStyle(color: Colors.white.withValues(alpha: 0.7))),
|
style: TextStyle(
|
||||||
|
color: Colors.white.withValues(alpha: 0.7))),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8.0),
|
||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
|
|
@ -72,10 +74,12 @@ class ImageViewVertical extends ConsumerWidget {
|
||||||
failedToLoadImage(false);
|
failedToLoadImage(false);
|
||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
decoration:
|
decoration: BoxDecoration(
|
||||||
BoxDecoration(color: context.primaryColor, borderRadius: BorderRadius.circular(30)),
|
color: context.primaryColor,
|
||||||
|
borderRadius: BorderRadius.circular(30)),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16),
|
padding: const EdgeInsets.symmetric(
|
||||||
|
vertical: 8, horizontal: 16),
|
||||||
child: Text(
|
child: Text(
|
||||||
context.l10n.retry,
|
context.l10n.retry,
|
||||||
),
|
),
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue