mirror of
https://github.com/kodjodevf/mangayomi.git
synced 2026-04-20 23:22:07 +00:00
Merge branch 'temp/mihon' into feature/mihon
This commit is contained in:
commit
604e1b18d3
73 changed files with 3976 additions and 993 deletions
|
|
@ -3,10 +3,12 @@ import 'package:mangayomi/models/source.dart';
|
|||
|
||||
import 'dart/service.dart';
|
||||
import 'javascript/service.dart';
|
||||
import 'mihon/service.dart';
|
||||
|
||||
ExtensionService getExtensionService(Source source) {
|
||||
ExtensionService getExtensionService(Source source, String androidProxyServer) {
|
||||
return switch (source.sourceCodeLanguage) {
|
||||
SourceCodeLanguage.dart => DartExtensionService(source),
|
||||
SourceCodeLanguage.javascript => JsExtensionService(source),
|
||||
SourceCodeLanguage.mihon => MihonExtensionService(source, androidProxyServer),
|
||||
};
|
||||
}
|
||||
|
|
|
|||
85
lib/eval/mihon/models.dart
Normal file
85
lib/eval/mihon/models.dart
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
import 'package:mangayomi/models/manga.dart';
|
||||
|
||||
class MangaPages {
|
||||
List<SManga> list;
|
||||
bool hasNextPage;
|
||||
MangaPages({required this.list, this.hasNextPage = false});
|
||||
|
||||
factory MangaPages.fromJson(Map<String, dynamic> json, ItemType itemType) {
|
||||
final name = itemType == ItemType.anime ? "animes" : "mangas";
|
||||
return MangaPages(
|
||||
list: json[name] != null
|
||||
? (json[name] as List).map((e) => SManga.fromJson(e)).toList()
|
||||
: [],
|
||||
hasNextPage: json['hasNextPage'],
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson(ItemType itemType) => {
|
||||
itemType == ItemType.anime ? "animes" : "mangas": list
|
||||
.map((v) => v.toJson())
|
||||
.toList(),
|
||||
'hasNextPage': hasNextPage,
|
||||
};
|
||||
}
|
||||
|
||||
class SManga {
|
||||
String? url;
|
||||
|
||||
String? title;
|
||||
|
||||
String? artist;
|
||||
|
||||
String? author;
|
||||
|
||||
String? description;
|
||||
|
||||
List<String>? genre;
|
||||
|
||||
Status? status;
|
||||
|
||||
String? thumbnailUrl;
|
||||
|
||||
SManga({
|
||||
this.url,
|
||||
this.title,
|
||||
this.artist,
|
||||
this.author,
|
||||
this.description,
|
||||
this.genre,
|
||||
this.status = Status.unknown,
|
||||
this.thumbnailUrl,
|
||||
});
|
||||
|
||||
factory SManga.fromJson(Map<String, dynamic> json) {
|
||||
return SManga(
|
||||
url: json['url'],
|
||||
title: json['title'],
|
||||
artist: json['artist'],
|
||||
author: json['author'],
|
||||
description: json['description'],
|
||||
genre: (json['genres'] as List?)?.map((e) => e.toString()).toList() ?? [],
|
||||
status: switch (json['status'] as int?) {
|
||||
1 => Status.ongoing,
|
||||
2 => Status.completed,
|
||||
4 => Status.publishingFinished,
|
||||
5 => Status.canceled,
|
||||
6 => Status.onHiatus,
|
||||
_ => Status.unknown,
|
||||
},
|
||||
thumbnailUrl: json['thumbnail_url'],
|
||||
);
|
||||
}
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'url': url,
|
||||
'title': title,
|
||||
'artist': artist,
|
||||
'author': author,
|
||||
'description': description,
|
||||
'genre': genre?.join(", "),
|
||||
'status': status,
|
||||
'thumbnail_url': thumbnailUrl,
|
||||
};
|
||||
}
|
||||
}
|
||||
339
lib/eval/mihon/service.dart
Normal file
339
lib/eval/mihon/service.dart
Normal file
|
|
@ -0,0 +1,339 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:math';
|
||||
import 'package:http_interceptor/http_interceptor.dart';
|
||||
import 'package:mangayomi/eval/javascript/http.dart';
|
||||
import 'package:mangayomi/eval/model/filter.dart';
|
||||
import 'package:mangayomi/eval/model/m_chapter.dart';
|
||||
import 'package:mangayomi/eval/model/m_manga.dart';
|
||||
import 'package:mangayomi/eval/model/m_pages.dart';
|
||||
import 'package:mangayomi/eval/model/source_preference.dart';
|
||||
import 'package:mangayomi/models/page.dart';
|
||||
import 'package:mangayomi/models/source.dart';
|
||||
import 'package:mangayomi/models/video.dart';
|
||||
import 'package:mangayomi/services/http/m_client.dart';
|
||||
|
||||
import '../../models/manga.dart';
|
||||
import '../interface.dart';
|
||||
import 'models.dart';
|
||||
|
||||
class MihonExtensionService implements ExtensionService {
|
||||
late String androidProxyServer;
|
||||
@override
|
||||
late Source source;
|
||||
late InterceptedClient client;
|
||||
|
||||
MihonExtensionService(this.source, this.androidProxyServer) {
|
||||
client = MClient.init();
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, String> getHeaders() {
|
||||
return source.headers != null && source.headers!.isNotEmpty
|
||||
? (jsonDecode(source.headers!) as Map?)?.toMapStringString ?? {}
|
||||
: {};
|
||||
}
|
||||
|
||||
@override
|
||||
bool get supportsLatest {
|
||||
return source.supportLatest ?? false;
|
||||
}
|
||||
|
||||
@override
|
||||
String get sourceBaseUrl {
|
||||
return source.baseUrl!;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<MPages> getPopular(int page) async {
|
||||
final name = source.itemType == ItemType.anime ? "Anime" : "Manga";
|
||||
final res = await client.post(
|
||||
Uri.parse("$androidProxyServer/dalvik"),
|
||||
body: jsonEncode({
|
||||
"method": "getPopular$name",
|
||||
"page": page + 1,
|
||||
"search": "",
|
||||
"preferences": getSourcePreferences(),
|
||||
"data": source.sourceCode,
|
||||
}),
|
||||
);
|
||||
final data = jsonDecode(res.body) as Map<String, dynamic>;
|
||||
final pages = MangaPages.fromJson(data, source.itemType);
|
||||
return MPages(
|
||||
list: pages.list
|
||||
.map(
|
||||
(e) => MManga(
|
||||
name: e.title,
|
||||
link: e.url,
|
||||
artist: e.artist,
|
||||
author: e.author,
|
||||
description: e.description,
|
||||
genre: e.genre,
|
||||
status: e.status,
|
||||
imageUrl: e.thumbnailUrl,
|
||||
chapters: [],
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
hasNextPage: pages.hasNextPage,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<MPages> getLatestUpdates(int page) async {
|
||||
final name = source.itemType == ItemType.anime ? "Anime" : "Manga";
|
||||
final res = await client.post(
|
||||
Uri.parse("$androidProxyServer/dalvik"),
|
||||
body: jsonEncode({
|
||||
"method": "getLatest$name",
|
||||
"page": page + 1,
|
||||
"search": "",
|
||||
"preferences": getSourcePreferences(),
|
||||
"data": source.sourceCode,
|
||||
}),
|
||||
);
|
||||
final data = jsonDecode(res.body) as Map<String, dynamic>;
|
||||
final pages = MangaPages.fromJson(data, source.itemType);
|
||||
return MPages(
|
||||
list: pages.list
|
||||
.map(
|
||||
(e) => MManga(
|
||||
name: e.title,
|
||||
link: e.url,
|
||||
artist: e.artist,
|
||||
author: e.author,
|
||||
description: e.description,
|
||||
genre: e.genre,
|
||||
status: e.status,
|
||||
imageUrl: e.thumbnailUrl,
|
||||
chapters: [],
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
hasNextPage: pages.hasNextPage,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<MPages> search(String query, int page, List<dynamic> filters) async {
|
||||
final name = source.itemType == ItemType.anime ? "Anime" : "Manga";
|
||||
final res = await client.post(
|
||||
Uri.parse("$androidProxyServer/dalvik"),
|
||||
body: jsonEncode({
|
||||
"method": "getSearch$name",
|
||||
"page": max(1, page),
|
||||
"search": query,
|
||||
"filterList": _convertFilters(filters),
|
||||
"preferences": getSourcePreferences(),
|
||||
"data": source.sourceCode,
|
||||
}),
|
||||
);
|
||||
final data = jsonDecode(res.body) as Map<String, dynamic>;
|
||||
final pages = MangaPages.fromJson(data, source.itemType);
|
||||
return MPages(
|
||||
list: pages.list
|
||||
.map(
|
||||
(e) => MManga(
|
||||
name: e.title,
|
||||
link: e.url,
|
||||
artist: e.artist,
|
||||
author: e.author,
|
||||
description: e.description,
|
||||
genre: e.genre,
|
||||
status: e.status,
|
||||
imageUrl: e.thumbnailUrl,
|
||||
chapters: [],
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
hasNextPage: pages.hasNextPage,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<MManga> getDetail(String url) async {
|
||||
final name = source.itemType == ItemType.anime ? "Anime" : "Manga";
|
||||
final res = await client.post(
|
||||
Uri.parse("$androidProxyServer/dalvik"),
|
||||
body: jsonEncode({
|
||||
"method": "getDetails$name",
|
||||
if (source.itemType == ItemType.manga) "mangaData": {"url": url},
|
||||
if (source.itemType == ItemType.anime) "animeData": {"url": url},
|
||||
"preferences": getSourcePreferences(),
|
||||
"data": source.sourceCode,
|
||||
}),
|
||||
);
|
||||
final data = jsonDecode(res.body) as Map<String, dynamic>;
|
||||
final chapters = await getChapterList(url);
|
||||
return MManga(
|
||||
name: data['title'],
|
||||
link: data['url'],
|
||||
artist: data['artist'],
|
||||
author: data['author'],
|
||||
description: data['description'],
|
||||
genre: (data['genres'] as List?)?.map((e) => e.toString()).toList() ?? [],
|
||||
status: switch (data['status'] as int?) {
|
||||
1 => Status.ongoing,
|
||||
2 => Status.completed,
|
||||
4 => Status.publishingFinished,
|
||||
5 => Status.canceled,
|
||||
6 => Status.onHiatus,
|
||||
_ => Status.unknown,
|
||||
},
|
||||
imageUrl: data['thumbnail_url'],
|
||||
chapters: chapters,
|
||||
);
|
||||
}
|
||||
|
||||
Future<List<MChapter>> getChapterList(String url) async {
|
||||
final res = await client.post(
|
||||
Uri.parse("$androidProxyServer/dalvik"),
|
||||
body: jsonEncode({
|
||||
"method": source.itemType == ItemType.anime
|
||||
? "getEpisodeList"
|
||||
: "getChapterList",
|
||||
if (source.itemType == ItemType.manga) "mangaData": {"url": url},
|
||||
if (source.itemType == ItemType.anime) "animeData": {"url": url},
|
||||
"preferences": getSourcePreferences(),
|
||||
"data": source.sourceCode,
|
||||
}),
|
||||
);
|
||||
final data = jsonDecode(res.body) as List;
|
||||
return data
|
||||
.map(
|
||||
(e) => MChapter(
|
||||
name: e['name'],
|
||||
url: e['url'],
|
||||
dateUpload: e['date_upload'] is int
|
||||
? (e['date_upload'] as int).toString()
|
||||
: e['date_upload'],
|
||||
scanlator: e['scanlator'],
|
||||
),
|
||||
)
|
||||
.toList();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<PageUrl>> getPageList(String url) async {
|
||||
final res = await client.post(
|
||||
Uri.parse("$androidProxyServer/dalvik"),
|
||||
body: jsonEncode({
|
||||
"method": "getPageList",
|
||||
"chapterData": {"url": url},
|
||||
"preferences": getSourcePreferences(),
|
||||
"data": source.sourceCode,
|
||||
}),
|
||||
);
|
||||
final data = jsonDecode(res.body) as List;
|
||||
return data.map((e) => PageUrl(e['imageUrl'])).toList();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<Video>> getVideoList(String url) async {
|
||||
final res = await client.post(
|
||||
Uri.parse("$androidProxyServer/dalvik"),
|
||||
body: jsonEncode({
|
||||
"method": "getVideoList",
|
||||
"episodeData": {"url": url},
|
||||
"preferences": getSourcePreferences(),
|
||||
"data": source.sourceCode,
|
||||
}),
|
||||
);
|
||||
final data = jsonDecode(res.body) as List;
|
||||
return data.map((e) {
|
||||
final tempHeaders =
|
||||
e['headers']?['namesAndValues\$okhttp'] as List<dynamic>?;
|
||||
final Map<String, String> headers = {};
|
||||
if (tempHeaders != null) {
|
||||
for (var i = 0; i + 1 < tempHeaders.length; i += 2) {
|
||||
headers[tempHeaders[i]] = tempHeaders[i + 1];
|
||||
}
|
||||
}
|
||||
return Video(
|
||||
e['videoUrl'],
|
||||
e['quality'],
|
||||
e['url'],
|
||||
headers: headers,
|
||||
audios:
|
||||
(e['audioTracks'] as List?)
|
||||
?.map(
|
||||
(e) => Track(
|
||||
file: e['file'] ?? e['url'],
|
||||
label: e['label'] ?? e['lang'],
|
||||
),
|
||||
)
|
||||
.toList() ??
|
||||
[],
|
||||
subtitles:
|
||||
(e['subtitleTracks'] as List?)
|
||||
?.map(
|
||||
(e) => Track(
|
||||
file: e['file'] ?? e['url'],
|
||||
label: e['label'] ?? e['lang'],
|
||||
),
|
||||
)
|
||||
.toList() ??
|
||||
[],
|
||||
);
|
||||
}).toList();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<String> getHtmlContent(String name, String url) async {
|
||||
return "";
|
||||
}
|
||||
|
||||
@override
|
||||
Future<String> cleanHtmlContent(String html) async {
|
||||
return html;
|
||||
}
|
||||
|
||||
@override
|
||||
FilterList getFilterList() {
|
||||
return source.getFilterList() ?? FilterList([]);
|
||||
}
|
||||
|
||||
@override
|
||||
List<SourcePreference> getSourcePreferences() {
|
||||
if (source.preferenceList == null) {
|
||||
return [];
|
||||
}
|
||||
final data = jsonDecode(source.preferenceList!) as List;
|
||||
return data.map((e) => SourcePreference.fromJson(e)).toList();
|
||||
}
|
||||
|
||||
List<dynamic> _convertFilters(List<dynamic> filters) {
|
||||
return filters.expand((e) sync* {
|
||||
if (e is TextFilter) {
|
||||
yield {"name": e.name, "stateString": e.state, "type": "TextFilter"};
|
||||
} else if (e is GroupFilter) {
|
||||
yield {
|
||||
"name": e.name,
|
||||
"stateList": e.state.expand((e) sync* {
|
||||
if (e is CheckBoxFilter) {
|
||||
yield {
|
||||
"name": e.name,
|
||||
"stateBoolean": e.state,
|
||||
"type": "CheckBoxFilter",
|
||||
};
|
||||
} else if (e is TriStateFilter) {
|
||||
yield {
|
||||
"name": e.name,
|
||||
"stateInt": e.state,
|
||||
"type": "TriStateFilter",
|
||||
};
|
||||
}
|
||||
}).toList(),
|
||||
"type": "GroupFilter",
|
||||
};
|
||||
} else if (e is SelectFilter) {
|
||||
yield {"name": e.name, "stateInt": e.state, "type": "SelectFilter"};
|
||||
} else if (e is SortFilter) {
|
||||
yield {
|
||||
"name": e.name,
|
||||
"stateSort": {"ascending": e.state.ascending, "index": e.state.index},
|
||||
"type": "SortFilter",
|
||||
};
|
||||
}
|
||||
}).toList();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,3 +1,5 @@
|
|||
import 'dart:math';
|
||||
|
||||
import 'package:isar/isar.dart';
|
||||
part 'source_preference.g.dart';
|
||||
|
||||
|
|
@ -139,7 +141,9 @@ class ListPreference {
|
|||
return ListPreference(
|
||||
title: json['title'],
|
||||
summary: json['summary'],
|
||||
valueIndex: json['valueIndex'],
|
||||
valueIndex: json['valueIndex'] != null
|
||||
? max(0, json['valueIndex'])
|
||||
: null,
|
||||
entries: json['entries']?.cast<String>(),
|
||||
entryValues: json['entryValues']?.cast<String>(),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -446,6 +446,8 @@
|
|||
"manga_extensions_repo": "Manga extensions repo",
|
||||
"anime_extensions_repo": "Anime extensions repo",
|
||||
"novel_extensions_repo": "Novel extensions repo",
|
||||
"custom_dns": "Custom DNS (leave blank to use system DNS)",
|
||||
"android_proxy_server": "Android Proxy Server (ApkBridge)",
|
||||
"undefined": "undefined",
|
||||
"empty_extensions_repo": "You don't have any repository urls here. Click on the plus button to add one!",
|
||||
"add_extensions_repo": "Add repo URL",
|
||||
|
|
|
|||
|
|
@ -2751,6 +2751,18 @@ abstract class AppLocalizations {
|
|||
/// **'Novel extensions repo'**
|
||||
String get novel_extensions_repo;
|
||||
|
||||
/// No description provided for @custom_dns.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Custom DNS (leave blank to use system DNS)'**
|
||||
String get custom_dns;
|
||||
|
||||
/// No description provided for @android_proxy_server.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Android Proxy Server (ApkBridge)'**
|
||||
String get android_proxy_server;
|
||||
|
||||
/// No description provided for @undefined.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
|
|
@ -3279,17 +3291,11 @@ abstract class AppLocalizations {
|
|||
/// **'Type \'manga\', \'anime\' and/or \'novel\' (separated by a comma) to remove all related entries'**
|
||||
String get clear_library_input;
|
||||
|
||||
/// No description provided for @enable_pip.
|
||||
/// No description provided for @recommendations_similarity.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Enable Picture-in-Picture (PiP)'**
|
||||
String get enable_pip;
|
||||
|
||||
/// No description provided for @enable_auto_pip.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Enter PiP automatically when moving out of app'**
|
||||
String get enable_auto_pip;
|
||||
/// **'Similarity:'**
|
||||
String get recommendations_similarity;
|
||||
}
|
||||
|
||||
class _AppLocalizationsDelegate
|
||||
|
|
|
|||
|
|
@ -1412,6 +1412,12 @@ class AppLocalizationsAr extends AppLocalizations {
|
|||
@override
|
||||
String get novel_extensions_repo => 'مستودع إضافات الروايات';
|
||||
|
||||
@override
|
||||
String get custom_dns => 'Custom DNS (leave blank to use system DNS)';
|
||||
|
||||
@override
|
||||
String get android_proxy_server => 'Android Proxy Server (ApkBridge)';
|
||||
|
||||
@override
|
||||
String get undefined => 'غير محدد';
|
||||
|
||||
|
|
@ -1698,9 +1704,5 @@ class AppLocalizationsAr extends AppLocalizations {
|
|||
'Type \'manga\', \'anime\' and/or \'novel\' (separated by a comma) to remove all related entries';
|
||||
|
||||
@override
|
||||
String get enable_pip => 'Enable Picture-in-Picture (PiP)';
|
||||
|
||||
@override
|
||||
String get enable_auto_pip =>
|
||||
'Enter PiP automatically when moving out of app';
|
||||
String get recommendations_similarity => 'Similarity:';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1414,6 +1414,12 @@ class AppLocalizationsAs extends AppLocalizations {
|
|||
@override
|
||||
String get novel_extensions_repo => 'Novel extensions repo';
|
||||
|
||||
@override
|
||||
String get custom_dns => 'Custom DNS (leave blank to use system DNS)';
|
||||
|
||||
@override
|
||||
String get android_proxy_server => 'Android Proxy Server (ApkBridge)';
|
||||
|
||||
@override
|
||||
String get undefined => 'undefined';
|
||||
|
||||
|
|
@ -1700,9 +1706,5 @@ class AppLocalizationsAs extends AppLocalizations {
|
|||
'Type \'manga\', \'anime\' and/or \'novel\' (separated by a comma) to remove all related entries';
|
||||
|
||||
@override
|
||||
String get enable_pip => 'Enable Picture-in-Picture (PiP)';
|
||||
|
||||
@override
|
||||
String get enable_auto_pip =>
|
||||
'Enter PiP automatically when moving out of app';
|
||||
String get recommendations_similarity => 'Similarity:';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1423,6 +1423,12 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||
@override
|
||||
String get novel_extensions_repo => 'Roman-Erweiterungs-Repository';
|
||||
|
||||
@override
|
||||
String get custom_dns => 'Custom DNS (leave blank to use system DNS)';
|
||||
|
||||
@override
|
||||
String get android_proxy_server => 'Android Proxy Server (ApkBridge)';
|
||||
|
||||
@override
|
||||
String get undefined => 'Nicht definiert';
|
||||
|
||||
|
|
@ -1711,9 +1717,5 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||
'Type \'manga\', \'anime\' and/or \'novel\' (separated by a comma) to remove all related entries';
|
||||
|
||||
@override
|
||||
String get enable_pip => 'Enable Picture-in-Picture (PiP)';
|
||||
|
||||
@override
|
||||
String get enable_auto_pip =>
|
||||
'Enter PiP automatically when moving out of app';
|
||||
String get recommendations_similarity => 'Similarity:';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1413,6 +1413,12 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||
@override
|
||||
String get novel_extensions_repo => 'Novel extensions repo';
|
||||
|
||||
@override
|
||||
String get custom_dns => 'Custom DNS (leave blank to use system DNS)';
|
||||
|
||||
@override
|
||||
String get android_proxy_server => 'Android Proxy Server (ApkBridge)';
|
||||
|
||||
@override
|
||||
String get undefined => 'undefined';
|
||||
|
||||
|
|
@ -1699,9 +1705,5 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||
'Type \'manga\', \'anime\' and/or \'novel\' (separated by a comma) to remove all related entries';
|
||||
|
||||
@override
|
||||
String get enable_pip => 'Enable Picture-in-Picture (PiP)';
|
||||
|
||||
@override
|
||||
String get enable_auto_pip =>
|
||||
'Enter PiP automatically when moving out of app';
|
||||
String get recommendations_similarity => 'Similarity:';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1427,6 +1427,12 @@ class AppLocalizationsEs extends AppLocalizations {
|
|||
@override
|
||||
String get novel_extensions_repo => 'Repositorio de extensiones de novelas';
|
||||
|
||||
@override
|
||||
String get custom_dns => 'Custom DNS (leave blank to use system DNS)';
|
||||
|
||||
@override
|
||||
String get android_proxy_server => 'Android Proxy Server (ApkBridge)';
|
||||
|
||||
@override
|
||||
String get undefined => 'Indefinido';
|
||||
|
||||
|
|
@ -1716,11 +1722,7 @@ class AppLocalizationsEs extends AppLocalizations {
|
|||
'Type \'manga\', \'anime\' and/or \'novel\' (separated by a comma) to remove all related entries';
|
||||
|
||||
@override
|
||||
String get enable_pip => 'Enable Picture-in-Picture (PiP)';
|
||||
|
||||
@override
|
||||
String get enable_auto_pip =>
|
||||
'Enter PiP automatically when moving out of app';
|
||||
String get recommendations_similarity => 'Similarity:';
|
||||
}
|
||||
|
||||
/// The translations for Spanish Castilian, as used in Latin America and the Caribbean (`es_419`).
|
||||
|
|
|
|||
|
|
@ -1430,6 +1430,12 @@ class AppLocalizationsFr extends AppLocalizations {
|
|||
@override
|
||||
String get novel_extensions_repo => 'Dépôt d\'extensions de romans';
|
||||
|
||||
@override
|
||||
String get custom_dns => 'Custom DNS (leave blank to use system DNS)';
|
||||
|
||||
@override
|
||||
String get android_proxy_server => 'Android Proxy Server (ApkBridge)';
|
||||
|
||||
@override
|
||||
String get undefined => 'Indéfini';
|
||||
|
||||
|
|
@ -1717,9 +1723,5 @@ class AppLocalizationsFr extends AppLocalizations {
|
|||
'Type \'manga\', \'anime\' and/or \'novel\' (separated by a comma) to remove all related entries';
|
||||
|
||||
@override
|
||||
String get enable_pip => 'Enable Picture-in-Picture (PiP)';
|
||||
|
||||
@override
|
||||
String get enable_auto_pip =>
|
||||
'Enter PiP automatically when moving out of app';
|
||||
String get recommendations_similarity => 'Similarity:';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1415,6 +1415,12 @@ class AppLocalizationsHi extends AppLocalizations {
|
|||
@override
|
||||
String get novel_extensions_repo => 'Novel extensions repo';
|
||||
|
||||
@override
|
||||
String get custom_dns => 'Custom DNS (leave blank to use system DNS)';
|
||||
|
||||
@override
|
||||
String get android_proxy_server => 'Android Proxy Server (ApkBridge)';
|
||||
|
||||
@override
|
||||
String get undefined => 'undefined';
|
||||
|
||||
|
|
@ -1701,9 +1707,5 @@ class AppLocalizationsHi extends AppLocalizations {
|
|||
'Type \'manga\', \'anime\' and/or \'novel\' (separated by a comma) to remove all related entries';
|
||||
|
||||
@override
|
||||
String get enable_pip => 'Enable Picture-in-Picture (PiP)';
|
||||
|
||||
@override
|
||||
String get enable_auto_pip =>
|
||||
'Enter PiP automatically when moving out of app';
|
||||
String get recommendations_similarity => 'Similarity:';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1419,6 +1419,12 @@ class AppLocalizationsId extends AppLocalizations {
|
|||
@override
|
||||
String get novel_extensions_repo => 'Repositori ekstensi novel';
|
||||
|
||||
@override
|
||||
String get custom_dns => 'Custom DNS (leave blank to use system DNS)';
|
||||
|
||||
@override
|
||||
String get android_proxy_server => 'Android Proxy Server (ApkBridge)';
|
||||
|
||||
@override
|
||||
String get undefined => 'Tidak terdefinisi';
|
||||
|
||||
|
|
@ -1705,9 +1711,5 @@ class AppLocalizationsId extends AppLocalizations {
|
|||
'Type \'manga\', \'anime\' and/or \'novel\' (separated by a comma) to remove all related entries';
|
||||
|
||||
@override
|
||||
String get enable_pip => 'Enable Picture-in-Picture (PiP)';
|
||||
|
||||
@override
|
||||
String get enable_auto_pip =>
|
||||
'Enter PiP automatically when moving out of app';
|
||||
String get recommendations_similarity => 'Similarity:';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1427,6 +1427,12 @@ class AppLocalizationsIt extends AppLocalizations {
|
|||
@override
|
||||
String get novel_extensions_repo => 'Repository delle estensioni romanzi';
|
||||
|
||||
@override
|
||||
String get custom_dns => 'Custom DNS (leave blank to use system DNS)';
|
||||
|
||||
@override
|
||||
String get android_proxy_server => 'Android Proxy Server (ApkBridge)';
|
||||
|
||||
@override
|
||||
String get undefined => 'Non definito';
|
||||
|
||||
|
|
@ -1714,9 +1720,5 @@ class AppLocalizationsIt extends AppLocalizations {
|
|||
'Type \'manga\', \'anime\' and/or \'novel\' (separated by a comma) to remove all related entries';
|
||||
|
||||
@override
|
||||
String get enable_pip => 'Enable Picture-in-Picture (PiP)';
|
||||
|
||||
@override
|
||||
String get enable_auto_pip =>
|
||||
'Enter PiP automatically when moving out of app';
|
||||
String get recommendations_similarity => 'Similarity:';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1424,6 +1424,12 @@ class AppLocalizationsPt extends AppLocalizations {
|
|||
@override
|
||||
String get novel_extensions_repo => 'Repositório de extensões de romances';
|
||||
|
||||
@override
|
||||
String get custom_dns => 'Custom DNS (leave blank to use system DNS)';
|
||||
|
||||
@override
|
||||
String get android_proxy_server => 'Android Proxy Server (ApkBridge)';
|
||||
|
||||
@override
|
||||
String get undefined => 'Indefinido';
|
||||
|
||||
|
|
@ -1713,11 +1719,7 @@ class AppLocalizationsPt extends AppLocalizations {
|
|||
'Type \'manga\', \'anime\' and/or \'novel\' (separated by a comma) to remove all related entries';
|
||||
|
||||
@override
|
||||
String get enable_pip => 'Enable Picture-in-Picture (PiP)';
|
||||
|
||||
@override
|
||||
String get enable_auto_pip =>
|
||||
'Enter PiP automatically when moving out of app';
|
||||
String get recommendations_similarity => 'Similarity:';
|
||||
}
|
||||
|
||||
/// The translations for Portuguese, as used in Brazil (`pt_BR`).
|
||||
|
|
|
|||
|
|
@ -1426,6 +1426,12 @@ class AppLocalizationsRu extends AppLocalizations {
|
|||
@override
|
||||
String get novel_extensions_repo => 'Репозиторий расширений новелл';
|
||||
|
||||
@override
|
||||
String get custom_dns => 'Custom DNS (leave blank to use system DNS)';
|
||||
|
||||
@override
|
||||
String get android_proxy_server => 'Android Proxy Server (ApkBridge)';
|
||||
|
||||
@override
|
||||
String get undefined => 'Не определено';
|
||||
|
||||
|
|
@ -1715,9 +1721,5 @@ class AppLocalizationsRu extends AppLocalizations {
|
|||
'Type \'manga\', \'anime\' and/or \'novel\' (separated by a comma) to remove all related entries';
|
||||
|
||||
@override
|
||||
String get enable_pip => 'Enable Picture-in-Picture (PiP)';
|
||||
|
||||
@override
|
||||
String get enable_auto_pip =>
|
||||
'Enter PiP automatically when moving out of app';
|
||||
String get recommendations_similarity => 'Similarity:';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1413,6 +1413,12 @@ class AppLocalizationsTh extends AppLocalizations {
|
|||
@override
|
||||
String get novel_extensions_repo => 'ที่เก็บส่วนขยายโนเวล';
|
||||
|
||||
@override
|
||||
String get custom_dns => 'Custom DNS (leave blank to use system DNS)';
|
||||
|
||||
@override
|
||||
String get android_proxy_server => 'Android Proxy Server (ApkBridge)';
|
||||
|
||||
@override
|
||||
String get undefined => 'ไม่ได้กำหนด';
|
||||
|
||||
|
|
@ -1699,9 +1705,5 @@ class AppLocalizationsTh extends AppLocalizations {
|
|||
'Type \'manga\', \'anime\' and/or \'novel\' (separated by a comma) to remove all related entries';
|
||||
|
||||
@override
|
||||
String get enable_pip => 'Enable Picture-in-Picture (PiP)';
|
||||
|
||||
@override
|
||||
String get enable_auto_pip =>
|
||||
'Enter PiP automatically when moving out of app';
|
||||
String get recommendations_similarity => 'Similarity:';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1419,6 +1419,12 @@ class AppLocalizationsTr extends AppLocalizations {
|
|||
@override
|
||||
String get novel_extensions_repo => 'Roman uzantıları deposu';
|
||||
|
||||
@override
|
||||
String get custom_dns => 'Custom DNS (leave blank to use system DNS)';
|
||||
|
||||
@override
|
||||
String get android_proxy_server => 'Android Proxy Server (ApkBridge)';
|
||||
|
||||
@override
|
||||
String get undefined => 'Tanımsız';
|
||||
|
||||
|
|
@ -1705,9 +1711,5 @@ class AppLocalizationsTr extends AppLocalizations {
|
|||
'Type \'manga\', \'anime\' and/or \'novel\' (separated by a comma) to remove all related entries';
|
||||
|
||||
@override
|
||||
String get enable_pip => 'Enable Picture-in-Picture (PiP)';
|
||||
|
||||
@override
|
||||
String get enable_auto_pip =>
|
||||
'Enter PiP automatically when moving out of app';
|
||||
String get recommendations_similarity => 'Similarity:';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1387,6 +1387,12 @@ class AppLocalizationsZh extends AppLocalizations {
|
|||
@override
|
||||
String get novel_extensions_repo => '小说扩展库';
|
||||
|
||||
@override
|
||||
String get custom_dns => 'Custom DNS (leave blank to use system DNS)';
|
||||
|
||||
@override
|
||||
String get android_proxy_server => 'Android Proxy Server (ApkBridge)';
|
||||
|
||||
@override
|
||||
String get undefined => '未定义';
|
||||
|
||||
|
|
@ -1670,9 +1676,5 @@ class AppLocalizationsZh extends AppLocalizations {
|
|||
'Type \'manga\', \'anime\' and/or \'novel\' (separated by a comma) to remove all related entries';
|
||||
|
||||
@override
|
||||
String get enable_pip => 'Enable Picture-in-Picture (PiP)';
|
||||
|
||||
@override
|
||||
String get enable_auto_pip =>
|
||||
'Enter PiP automatically when moving out of app';
|
||||
String get recommendations_similarity => 'Similarity:';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import 'package:mangayomi/models/source.dart';
|
|||
import 'package:mangayomi/models/track_search.dart';
|
||||
import 'package:mangayomi/modules/more/data_and_storage/providers/storage_usage.dart';
|
||||
import 'package:mangayomi/modules/more/settings/browse/providers/browse_state_provider.dart';
|
||||
import 'package:mangayomi/modules/more/settings/general/providers/general_state_provider.dart';
|
||||
import 'package:mangayomi/providers/l10n_providers.dart';
|
||||
import 'package:mangayomi/providers/storage_provider.dart';
|
||||
import 'package:mangayomi/router/router.dart';
|
||||
|
|
@ -42,6 +43,7 @@ import 'package:flutter/services.dart' show rootBundle;
|
|||
late Isar isar;
|
||||
DiscordRPC? discordRpc;
|
||||
WebViewEnvironment? webViewEnvironment;
|
||||
String? customDns;
|
||||
void main(List<String> args) async {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
if (Platform.isLinux && runWebViewTitleBarWidget(args)) return;
|
||||
|
|
@ -102,6 +104,7 @@ class _MyAppState extends ConsumerState<MyApp> {
|
|||
unawaited(ref.read(scanLocalLibraryProvider.future));
|
||||
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
customDns = ref.read(customDnsStateProvider);
|
||||
if (ref.read(clearChapterCacheOnAppLaunchStateProvider)) {
|
||||
ref
|
||||
.read(totalChapterCacheSizeStateProvider.notifier)
|
||||
|
|
|
|||
|
|
@ -169,6 +169,8 @@ class Settings {
|
|||
|
||||
int? aniSkipTimeoutLength;
|
||||
|
||||
String? customDns;
|
||||
|
||||
String? btServerAddress;
|
||||
|
||||
int? btServerPort;
|
||||
|
|
@ -201,6 +203,8 @@ class Settings {
|
|||
|
||||
List<Repo>? novelExtensionsRepo;
|
||||
|
||||
String? androidProxyServer;
|
||||
|
||||
@enumerated
|
||||
late SectionType disableSectionType;
|
||||
|
||||
|
|
@ -277,7 +281,7 @@ class Settings {
|
|||
int? volumeBoostCap;
|
||||
|
||||
bool? downloadedOnlyMode;
|
||||
|
||||
|
||||
late AlgorithmWeights? algorithmWeights;
|
||||
|
||||
Settings({
|
||||
|
|
@ -354,6 +358,7 @@ class Settings {
|
|||
this.enableAniSkip,
|
||||
this.enableAutoSkip,
|
||||
this.aniSkipTimeoutLength,
|
||||
this.customDns = "",
|
||||
this.btServerAddress = "127.0.0.1",
|
||||
this.btServerPort,
|
||||
this.fullScreenReader = true,
|
||||
|
|
@ -388,6 +393,7 @@ class Settings {
|
|||
this.mangaExtensionsRepo,
|
||||
this.animeExtensionsRepo,
|
||||
this.novelExtensionsRepo,
|
||||
this.androidProxyServer,
|
||||
this.lastTrackerLibraryLocation,
|
||||
this.mergeLibraryNavMobile = false,
|
||||
this.enableDiscordRpc = true,
|
||||
|
|
@ -548,6 +554,7 @@ class Settings {
|
|||
enableAniSkip = json['enableAniSkip'];
|
||||
enableAutoSkip = json['enableAutoSkip'];
|
||||
aniSkipTimeoutLength = json['aniSkipTimeoutLength'];
|
||||
customDns = json['customDns'];
|
||||
btServerAddress = json['btServerAddress'];
|
||||
btServerPort = json['btServerPort'];
|
||||
customColorFilter = json['customColorFilter'] != null
|
||||
|
|
@ -619,6 +626,7 @@ class Settings {
|
|||
.map((e) => Repo.fromJson(e))
|
||||
.toList();
|
||||
}
|
||||
androidProxyServer = json['androidProxyServer'];
|
||||
lastTrackerLibraryLocation = json['lastTrackerLibraryLocation'];
|
||||
mergeLibraryNavMobile = json['mergeLibraryNavMobile'];
|
||||
enableDiscordRpc = json['enableDiscordRpc'];
|
||||
|
|
@ -734,6 +742,7 @@ class Settings {
|
|||
'enableAniSkip': enableAniSkip,
|
||||
'enableAutoSkip': enableAutoSkip,
|
||||
'aniSkipTimeoutLength': aniSkipTimeoutLength,
|
||||
'customDns': customDns,
|
||||
'btServerAddress': btServerAddress,
|
||||
'btServerPort': btServerPort,
|
||||
'fullScreenReader': fullScreenReader,
|
||||
|
|
@ -771,6 +780,7 @@ class Settings {
|
|||
'mangaExtensionsRepo': mangaExtensionsRepo?.map((e) => e.toJson()).toList(),
|
||||
'animeExtensionsRepo': animeExtensionsRepo?.map((e) => e.toJson()).toList(),
|
||||
'novelExtensionsRepo': novelExtensionsRepo?.map((e) => e.toJson()).toList(),
|
||||
'androidProxyServer': androidProxyServer,
|
||||
'lastTrackerLibraryLocation': lastTrackerLibraryLocation,
|
||||
'mergeLibraryNavMobile': mergeLibraryNavMobile,
|
||||
'enableDiscordRpc': enableDiscordRpc,
|
||||
|
|
@ -989,20 +999,34 @@ class Repo {
|
|||
String? name;
|
||||
String? website;
|
||||
String? jsonUrl;
|
||||
bool? hidden;
|
||||
|
||||
Repo({this.name, this.website, this.jsonUrl});
|
||||
Repo({this.name, this.website, this.jsonUrl, this.hidden});
|
||||
|
||||
Repo.fromJson(Map<String, dynamic> json) {
|
||||
name = json['name'];
|
||||
website = json['website'];
|
||||
name = json['meta']?['name'] ?? json['name'];
|
||||
website = json['meta']?['website'] ?? json['website'];
|
||||
jsonUrl = json['jsonUrl'];
|
||||
hidden = json['hidden'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
'name': name,
|
||||
'website': website,
|
||||
'jsonUrl': jsonUrl,
|
||||
'hidden': hidden,
|
||||
};
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return other is Repo &&
|
||||
name == other.name &&
|
||||
website == other.website &&
|
||||
jsonUrl == other.jsonUrl;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(name, website, jsonUrl);
|
||||
}
|
||||
|
||||
@embedded
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,4 +1,7 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:isar/isar.dart';
|
||||
import 'package:mangayomi/eval/model/filter.dart';
|
||||
import 'package:mangayomi/eval/model/m_source.dart';
|
||||
import 'package:mangayomi/models/manga.dart';
|
||||
import 'package:mangayomi/models/settings.dart';
|
||||
|
|
@ -49,6 +52,15 @@ class Source {
|
|||
|
||||
String? headers;
|
||||
|
||||
/// For Mihon ext
|
||||
bool? supportLatest;
|
||||
|
||||
/// For Mihon ext
|
||||
String? filterList;
|
||||
|
||||
/// For Mihon ext
|
||||
String? preferenceList;
|
||||
|
||||
bool? isManga;
|
||||
|
||||
@enumerated
|
||||
|
|
@ -93,6 +105,9 @@ class Source {
|
|||
this.versionLast = "0.0.1",
|
||||
this.sourceCode = '',
|
||||
this.headers = '',
|
||||
this.supportLatest,
|
||||
this.filterList,
|
||||
this.preferenceList,
|
||||
this.isManga,
|
||||
this.itemType = ItemType.manga,
|
||||
this.appMinVerReq = "",
|
||||
|
|
@ -104,6 +119,10 @@ class Source {
|
|||
this.updatedAt = 0,
|
||||
});
|
||||
|
||||
FilterList? getFilterList() => filterList != null
|
||||
? FilterList.fromJson(jsonDecode(filterList!) as Map<String, dynamic>)
|
||||
: null;
|
||||
|
||||
Source.fromJson(Map<String, dynamic> json) {
|
||||
apiUrl = json['apiUrl'];
|
||||
appMinVerReq = json['appMinVerReq'];
|
||||
|
|
@ -112,6 +131,9 @@ class Source {
|
|||
dateFormatLocale = json['dateFormatLocale'];
|
||||
hasCloudflare = json['hasCloudflare'];
|
||||
headers = json['headers'];
|
||||
supportLatest = json['supportLatest'];
|
||||
filterList = json['filterList'];
|
||||
preferenceList = json['preferenceList'];
|
||||
iconUrl = json['iconUrl'];
|
||||
id = json['id'];
|
||||
isActive = json['isActive'];
|
||||
|
|
@ -147,6 +169,9 @@ class Source {
|
|||
'dateFormatLocale': dateFormatLocale,
|
||||
'hasCloudflare': hasCloudflare,
|
||||
'headers': headers,
|
||||
'supportLatest': supportLatest,
|
||||
'filterList': filterList,
|
||||
'preferenceList': preferenceList,
|
||||
'iconUrl': iconUrl,
|
||||
'id': id,
|
||||
'isActive': isActive,
|
||||
|
|
@ -191,4 +216,4 @@ class Source {
|
|||
}
|
||||
}
|
||||
|
||||
enum SourceCodeLanguage { dart, javascript }
|
||||
enum SourceCodeLanguage { dart, javascript, mihon }
|
||||
|
|
|
|||
|
|
@ -47,131 +47,146 @@ const SourceSchema = CollectionSchema(
|
|||
name: r'dateFormatLocale',
|
||||
type: IsarType.string,
|
||||
),
|
||||
r'hasCloudflare': PropertySchema(
|
||||
r'filterList': PropertySchema(
|
||||
id: 6,
|
||||
name: r'filterList',
|
||||
type: IsarType.string,
|
||||
),
|
||||
r'hasCloudflare': PropertySchema(
|
||||
id: 7,
|
||||
name: r'hasCloudflare',
|
||||
type: IsarType.bool,
|
||||
),
|
||||
r'headers': PropertySchema(
|
||||
id: 7,
|
||||
id: 8,
|
||||
name: r'headers',
|
||||
type: IsarType.string,
|
||||
),
|
||||
r'iconUrl': PropertySchema(
|
||||
id: 8,
|
||||
id: 9,
|
||||
name: r'iconUrl',
|
||||
type: IsarType.string,
|
||||
),
|
||||
r'isActive': PropertySchema(
|
||||
id: 9,
|
||||
id: 10,
|
||||
name: r'isActive',
|
||||
type: IsarType.bool,
|
||||
),
|
||||
r'isAdded': PropertySchema(
|
||||
id: 10,
|
||||
id: 11,
|
||||
name: r'isAdded',
|
||||
type: IsarType.bool,
|
||||
),
|
||||
r'isFullData': PropertySchema(
|
||||
id: 11,
|
||||
id: 12,
|
||||
name: r'isFullData',
|
||||
type: IsarType.bool,
|
||||
),
|
||||
r'isLocal': PropertySchema(
|
||||
id: 12,
|
||||
id: 13,
|
||||
name: r'isLocal',
|
||||
type: IsarType.bool,
|
||||
),
|
||||
r'isManga': PropertySchema(
|
||||
id: 13,
|
||||
id: 14,
|
||||
name: r'isManga',
|
||||
type: IsarType.bool,
|
||||
),
|
||||
r'isNsfw': PropertySchema(
|
||||
id: 14,
|
||||
id: 15,
|
||||
name: r'isNsfw',
|
||||
type: IsarType.bool,
|
||||
),
|
||||
r'isObsolete': PropertySchema(
|
||||
id: 15,
|
||||
id: 16,
|
||||
name: r'isObsolete',
|
||||
type: IsarType.bool,
|
||||
),
|
||||
r'isPinned': PropertySchema(
|
||||
id: 16,
|
||||
id: 17,
|
||||
name: r'isPinned',
|
||||
type: IsarType.bool,
|
||||
),
|
||||
r'isTorrent': PropertySchema(
|
||||
id: 17,
|
||||
id: 18,
|
||||
name: r'isTorrent',
|
||||
type: IsarType.bool,
|
||||
),
|
||||
r'itemType': PropertySchema(
|
||||
id: 18,
|
||||
id: 19,
|
||||
name: r'itemType',
|
||||
type: IsarType.byte,
|
||||
enumMap: _SourceitemTypeEnumValueMap,
|
||||
),
|
||||
r'lang': PropertySchema(
|
||||
id: 19,
|
||||
id: 20,
|
||||
name: r'lang',
|
||||
type: IsarType.string,
|
||||
),
|
||||
r'lastUsed': PropertySchema(
|
||||
id: 20,
|
||||
id: 21,
|
||||
name: r'lastUsed',
|
||||
type: IsarType.bool,
|
||||
),
|
||||
r'name': PropertySchema(
|
||||
id: 21,
|
||||
id: 22,
|
||||
name: r'name',
|
||||
type: IsarType.string,
|
||||
),
|
||||
r'notes': PropertySchema(
|
||||
id: 22,
|
||||
id: 23,
|
||||
name: r'notes',
|
||||
type: IsarType.string,
|
||||
),
|
||||
r'preferenceList': PropertySchema(
|
||||
id: 24,
|
||||
name: r'preferenceList',
|
||||
type: IsarType.string,
|
||||
),
|
||||
r'repo': PropertySchema(
|
||||
id: 23,
|
||||
id: 25,
|
||||
name: r'repo',
|
||||
type: IsarType.object,
|
||||
target: r'Repo',
|
||||
),
|
||||
r'sourceCode': PropertySchema(
|
||||
id: 24,
|
||||
id: 26,
|
||||
name: r'sourceCode',
|
||||
type: IsarType.string,
|
||||
),
|
||||
r'sourceCodeLanguage': PropertySchema(
|
||||
id: 25,
|
||||
id: 27,
|
||||
name: r'sourceCodeLanguage',
|
||||
type: IsarType.byte,
|
||||
enumMap: _SourcesourceCodeLanguageEnumValueMap,
|
||||
),
|
||||
r'sourceCodeUrl': PropertySchema(
|
||||
id: 26,
|
||||
id: 28,
|
||||
name: r'sourceCodeUrl',
|
||||
type: IsarType.string,
|
||||
),
|
||||
r'supportLatest': PropertySchema(
|
||||
id: 29,
|
||||
name: r'supportLatest',
|
||||
type: IsarType.bool,
|
||||
),
|
||||
r'typeSource': PropertySchema(
|
||||
id: 27,
|
||||
id: 30,
|
||||
name: r'typeSource',
|
||||
type: IsarType.string,
|
||||
),
|
||||
r'updatedAt': PropertySchema(
|
||||
id: 28,
|
||||
id: 31,
|
||||
name: r'updatedAt',
|
||||
type: IsarType.long,
|
||||
),
|
||||
r'version': PropertySchema(
|
||||
id: 29,
|
||||
id: 32,
|
||||
name: r'version',
|
||||
type: IsarType.string,
|
||||
),
|
||||
r'versionLast': PropertySchema(
|
||||
id: 30,
|
||||
id: 33,
|
||||
name: r'versionLast',
|
||||
type: IsarType.string,
|
||||
)
|
||||
|
|
@ -232,6 +247,12 @@ int _sourceEstimateSize(
|
|||
bytesCount += 3 + value.length * 3;
|
||||
}
|
||||
}
|
||||
{
|
||||
final value = object.filterList;
|
||||
if (value != null) {
|
||||
bytesCount += 3 + value.length * 3;
|
||||
}
|
||||
}
|
||||
{
|
||||
final value = object.headers;
|
||||
if (value != null) {
|
||||
|
|
@ -262,6 +283,12 @@ int _sourceEstimateSize(
|
|||
bytesCount += 3 + value.length * 3;
|
||||
}
|
||||
}
|
||||
{
|
||||
final value = object.preferenceList;
|
||||
if (value != null) {
|
||||
bytesCount += 3 + value.length * 3;
|
||||
}
|
||||
}
|
||||
{
|
||||
final value = object.repo;
|
||||
if (value != null) {
|
||||
|
|
@ -314,36 +341,39 @@ void _sourceSerialize(
|
|||
writer.writeString(offsets[3], object.baseUrl);
|
||||
writer.writeString(offsets[4], object.dateFormat);
|
||||
writer.writeString(offsets[5], object.dateFormatLocale);
|
||||
writer.writeBool(offsets[6], object.hasCloudflare);
|
||||
writer.writeString(offsets[7], object.headers);
|
||||
writer.writeString(offsets[8], object.iconUrl);
|
||||
writer.writeBool(offsets[9], object.isActive);
|
||||
writer.writeBool(offsets[10], object.isAdded);
|
||||
writer.writeBool(offsets[11], object.isFullData);
|
||||
writer.writeBool(offsets[12], object.isLocal);
|
||||
writer.writeBool(offsets[13], object.isManga);
|
||||
writer.writeBool(offsets[14], object.isNsfw);
|
||||
writer.writeBool(offsets[15], object.isObsolete);
|
||||
writer.writeBool(offsets[16], object.isPinned);
|
||||
writer.writeBool(offsets[17], object.isTorrent);
|
||||
writer.writeByte(offsets[18], object.itemType.index);
|
||||
writer.writeString(offsets[19], object.lang);
|
||||
writer.writeBool(offsets[20], object.lastUsed);
|
||||
writer.writeString(offsets[21], object.name);
|
||||
writer.writeString(offsets[22], object.notes);
|
||||
writer.writeString(offsets[6], object.filterList);
|
||||
writer.writeBool(offsets[7], object.hasCloudflare);
|
||||
writer.writeString(offsets[8], object.headers);
|
||||
writer.writeString(offsets[9], object.iconUrl);
|
||||
writer.writeBool(offsets[10], object.isActive);
|
||||
writer.writeBool(offsets[11], object.isAdded);
|
||||
writer.writeBool(offsets[12], object.isFullData);
|
||||
writer.writeBool(offsets[13], object.isLocal);
|
||||
writer.writeBool(offsets[14], object.isManga);
|
||||
writer.writeBool(offsets[15], object.isNsfw);
|
||||
writer.writeBool(offsets[16], object.isObsolete);
|
||||
writer.writeBool(offsets[17], object.isPinned);
|
||||
writer.writeBool(offsets[18], object.isTorrent);
|
||||
writer.writeByte(offsets[19], object.itemType.index);
|
||||
writer.writeString(offsets[20], object.lang);
|
||||
writer.writeBool(offsets[21], object.lastUsed);
|
||||
writer.writeString(offsets[22], object.name);
|
||||
writer.writeString(offsets[23], object.notes);
|
||||
writer.writeString(offsets[24], object.preferenceList);
|
||||
writer.writeObject<Repo>(
|
||||
offsets[23],
|
||||
offsets[25],
|
||||
allOffsets,
|
||||
RepoSchema.serialize,
|
||||
object.repo,
|
||||
);
|
||||
writer.writeString(offsets[24], object.sourceCode);
|
||||
writer.writeByte(offsets[25], object.sourceCodeLanguage.index);
|
||||
writer.writeString(offsets[26], object.sourceCodeUrl);
|
||||
writer.writeString(offsets[27], object.typeSource);
|
||||
writer.writeLong(offsets[28], object.updatedAt);
|
||||
writer.writeString(offsets[29], object.version);
|
||||
writer.writeString(offsets[30], object.versionLast);
|
||||
writer.writeString(offsets[26], object.sourceCode);
|
||||
writer.writeByte(offsets[27], object.sourceCodeLanguage.index);
|
||||
writer.writeString(offsets[28], object.sourceCodeUrl);
|
||||
writer.writeBool(offsets[29], object.supportLatest);
|
||||
writer.writeString(offsets[30], object.typeSource);
|
||||
writer.writeLong(offsets[31], object.updatedAt);
|
||||
writer.writeString(offsets[32], object.version);
|
||||
writer.writeString(offsets[33], object.versionLast);
|
||||
}
|
||||
|
||||
Source _sourceDeserialize(
|
||||
|
|
@ -359,38 +389,41 @@ Source _sourceDeserialize(
|
|||
baseUrl: reader.readStringOrNull(offsets[3]),
|
||||
dateFormat: reader.readStringOrNull(offsets[4]),
|
||||
dateFormatLocale: reader.readStringOrNull(offsets[5]),
|
||||
hasCloudflare: reader.readBoolOrNull(offsets[6]),
|
||||
headers: reader.readStringOrNull(offsets[7]),
|
||||
iconUrl: reader.readStringOrNull(offsets[8]),
|
||||
filterList: reader.readStringOrNull(offsets[6]),
|
||||
hasCloudflare: reader.readBoolOrNull(offsets[7]),
|
||||
headers: reader.readStringOrNull(offsets[8]),
|
||||
iconUrl: reader.readStringOrNull(offsets[9]),
|
||||
id: id,
|
||||
isActive: reader.readBoolOrNull(offsets[9]),
|
||||
isAdded: reader.readBoolOrNull(offsets[10]),
|
||||
isFullData: reader.readBoolOrNull(offsets[11]),
|
||||
isLocal: reader.readBoolOrNull(offsets[12]),
|
||||
isManga: reader.readBoolOrNull(offsets[13]),
|
||||
isNsfw: reader.readBoolOrNull(offsets[14]),
|
||||
isObsolete: reader.readBoolOrNull(offsets[15]),
|
||||
isPinned: reader.readBoolOrNull(offsets[16]),
|
||||
itemType: _SourceitemTypeValueEnumMap[reader.readByteOrNull(offsets[18])] ??
|
||||
isActive: reader.readBoolOrNull(offsets[10]),
|
||||
isAdded: reader.readBoolOrNull(offsets[11]),
|
||||
isFullData: reader.readBoolOrNull(offsets[12]),
|
||||
isLocal: reader.readBoolOrNull(offsets[13]),
|
||||
isManga: reader.readBoolOrNull(offsets[14]),
|
||||
isNsfw: reader.readBoolOrNull(offsets[15]),
|
||||
isObsolete: reader.readBoolOrNull(offsets[16]),
|
||||
isPinned: reader.readBoolOrNull(offsets[17]),
|
||||
itemType: _SourceitemTypeValueEnumMap[reader.readByteOrNull(offsets[19])] ??
|
||||
ItemType.manga,
|
||||
lang: reader.readStringOrNull(offsets[19]),
|
||||
lastUsed: reader.readBoolOrNull(offsets[20]),
|
||||
name: reader.readStringOrNull(offsets[21]),
|
||||
notes: reader.readStringOrNull(offsets[22]),
|
||||
lang: reader.readStringOrNull(offsets[20]),
|
||||
lastUsed: reader.readBoolOrNull(offsets[21]),
|
||||
name: reader.readStringOrNull(offsets[22]),
|
||||
notes: reader.readStringOrNull(offsets[23]),
|
||||
preferenceList: reader.readStringOrNull(offsets[24]),
|
||||
repo: reader.readObjectOrNull<Repo>(
|
||||
offsets[23],
|
||||
offsets[25],
|
||||
RepoSchema.deserialize,
|
||||
allOffsets,
|
||||
),
|
||||
sourceCode: reader.readStringOrNull(offsets[24]),
|
||||
sourceCodeUrl: reader.readStringOrNull(offsets[26]),
|
||||
typeSource: reader.readStringOrNull(offsets[27]),
|
||||
updatedAt: reader.readLongOrNull(offsets[28]),
|
||||
version: reader.readStringOrNull(offsets[29]),
|
||||
versionLast: reader.readStringOrNull(offsets[30]),
|
||||
sourceCode: reader.readStringOrNull(offsets[26]),
|
||||
sourceCodeUrl: reader.readStringOrNull(offsets[28]),
|
||||
supportLatest: reader.readBoolOrNull(offsets[29]),
|
||||
typeSource: reader.readStringOrNull(offsets[30]),
|
||||
updatedAt: reader.readLongOrNull(offsets[31]),
|
||||
version: reader.readStringOrNull(offsets[32]),
|
||||
versionLast: reader.readStringOrNull(offsets[33]),
|
||||
);
|
||||
object.sourceCodeLanguage = _SourcesourceCodeLanguageValueEnumMap[
|
||||
reader.readByteOrNull(offsets[25])] ??
|
||||
reader.readByteOrNull(offsets[27])] ??
|
||||
SourceCodeLanguage.dart;
|
||||
return object;
|
||||
}
|
||||
|
|
@ -415,13 +448,13 @@ P _sourceDeserializeProp<P>(
|
|||
case 5:
|
||||
return (reader.readStringOrNull(offset)) as P;
|
||||
case 6:
|
||||
return (reader.readBoolOrNull(offset)) as P;
|
||||
case 7:
|
||||
return (reader.readStringOrNull(offset)) as P;
|
||||
case 7:
|
||||
return (reader.readBoolOrNull(offset)) as P;
|
||||
case 8:
|
||||
return (reader.readStringOrNull(offset)) as P;
|
||||
case 9:
|
||||
return (reader.readBoolOrNull(offset)) as P;
|
||||
return (reader.readStringOrNull(offset)) as P;
|
||||
case 10:
|
||||
return (reader.readBoolOrNull(offset)) as P;
|
||||
case 11:
|
||||
|
|
@ -437,40 +470,46 @@ P _sourceDeserializeProp<P>(
|
|||
case 16:
|
||||
return (reader.readBoolOrNull(offset)) as P;
|
||||
case 17:
|
||||
return (reader.readBool(offset)) as P;
|
||||
return (reader.readBoolOrNull(offset)) as P;
|
||||
case 18:
|
||||
return (reader.readBool(offset)) as P;
|
||||
case 19:
|
||||
return (_SourceitemTypeValueEnumMap[reader.readByteOrNull(offset)] ??
|
||||
ItemType.manga) as P;
|
||||
case 19:
|
||||
return (reader.readStringOrNull(offset)) as P;
|
||||
case 20:
|
||||
return (reader.readBoolOrNull(offset)) as P;
|
||||
case 21:
|
||||
return (reader.readStringOrNull(offset)) as P;
|
||||
case 21:
|
||||
return (reader.readBoolOrNull(offset)) as P;
|
||||
case 22:
|
||||
return (reader.readStringOrNull(offset)) as P;
|
||||
case 23:
|
||||
return (reader.readStringOrNull(offset)) as P;
|
||||
case 24:
|
||||
return (reader.readStringOrNull(offset)) as P;
|
||||
case 25:
|
||||
return (reader.readObjectOrNull<Repo>(
|
||||
offset,
|
||||
RepoSchema.deserialize,
|
||||
allOffsets,
|
||||
)) as P;
|
||||
case 24:
|
||||
return (reader.readStringOrNull(offset)) as P;
|
||||
case 25:
|
||||
return (_SourcesourceCodeLanguageValueEnumMap[
|
||||
reader.readByteOrNull(offset)] ??
|
||||
SourceCodeLanguage.dart) as P;
|
||||
case 26:
|
||||
return (reader.readStringOrNull(offset)) as P;
|
||||
case 27:
|
||||
return (reader.readStringOrNull(offset)) as P;
|
||||
return (_SourcesourceCodeLanguageValueEnumMap[
|
||||
reader.readByteOrNull(offset)] ??
|
||||
SourceCodeLanguage.dart) as P;
|
||||
case 28:
|
||||
return (reader.readLongOrNull(offset)) as P;
|
||||
case 29:
|
||||
return (reader.readStringOrNull(offset)) as P;
|
||||
case 29:
|
||||
return (reader.readBoolOrNull(offset)) as P;
|
||||
case 30:
|
||||
return (reader.readStringOrNull(offset)) as P;
|
||||
case 31:
|
||||
return (reader.readLongOrNull(offset)) as P;
|
||||
case 32:
|
||||
return (reader.readStringOrNull(offset)) as P;
|
||||
case 33:
|
||||
return (reader.readStringOrNull(offset)) as P;
|
||||
default:
|
||||
throw IsarError('Unknown property with id $propertyId');
|
||||
}
|
||||
|
|
@ -489,10 +528,12 @@ const _SourceitemTypeValueEnumMap = {
|
|||
const _SourcesourceCodeLanguageEnumValueMap = {
|
||||
'dart': 0,
|
||||
'javascript': 1,
|
||||
'mihon': 2,
|
||||
};
|
||||
const _SourcesourceCodeLanguageValueEnumMap = {
|
||||
0: SourceCodeLanguage.dart,
|
||||
1: SourceCodeLanguage.javascript,
|
||||
2: SourceCodeLanguage.mihon,
|
||||
};
|
||||
|
||||
Id _sourceGetId(Source object) {
|
||||
|
|
@ -1469,6 +1510,152 @@ extension SourceQueryFilter on QueryBuilder<Source, Source, QFilterCondition> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QAfterFilterCondition> filterListIsNull() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(const FilterCondition.isNull(
|
||||
property: r'filterList',
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QAfterFilterCondition> filterListIsNotNull() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(const FilterCondition.isNotNull(
|
||||
property: r'filterList',
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QAfterFilterCondition> filterListEqualTo(
|
||||
String? value, {
|
||||
bool caseSensitive = true,
|
||||
}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(FilterCondition.equalTo(
|
||||
property: r'filterList',
|
||||
value: value,
|
||||
caseSensitive: caseSensitive,
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QAfterFilterCondition> filterListGreaterThan(
|
||||
String? value, {
|
||||
bool include = false,
|
||||
bool caseSensitive = true,
|
||||
}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(FilterCondition.greaterThan(
|
||||
include: include,
|
||||
property: r'filterList',
|
||||
value: value,
|
||||
caseSensitive: caseSensitive,
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QAfterFilterCondition> filterListLessThan(
|
||||
String? value, {
|
||||
bool include = false,
|
||||
bool caseSensitive = true,
|
||||
}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(FilterCondition.lessThan(
|
||||
include: include,
|
||||
property: r'filterList',
|
||||
value: value,
|
||||
caseSensitive: caseSensitive,
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QAfterFilterCondition> filterListBetween(
|
||||
String? lower,
|
||||
String? upper, {
|
||||
bool includeLower = true,
|
||||
bool includeUpper = true,
|
||||
bool caseSensitive = true,
|
||||
}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(FilterCondition.between(
|
||||
property: r'filterList',
|
||||
lower: lower,
|
||||
includeLower: includeLower,
|
||||
upper: upper,
|
||||
includeUpper: includeUpper,
|
||||
caseSensitive: caseSensitive,
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QAfterFilterCondition> filterListStartsWith(
|
||||
String value, {
|
||||
bool caseSensitive = true,
|
||||
}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(FilterCondition.startsWith(
|
||||
property: r'filterList',
|
||||
value: value,
|
||||
caseSensitive: caseSensitive,
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QAfterFilterCondition> filterListEndsWith(
|
||||
String value, {
|
||||
bool caseSensitive = true,
|
||||
}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(FilterCondition.endsWith(
|
||||
property: r'filterList',
|
||||
value: value,
|
||||
caseSensitive: caseSensitive,
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QAfterFilterCondition> filterListContains(
|
||||
String value,
|
||||
{bool caseSensitive = true}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(FilterCondition.contains(
|
||||
property: r'filterList',
|
||||
value: value,
|
||||
caseSensitive: caseSensitive,
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QAfterFilterCondition> filterListMatches(
|
||||
String pattern,
|
||||
{bool caseSensitive = true}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(FilterCondition.matches(
|
||||
property: r'filterList',
|
||||
wildcard: pattern,
|
||||
caseSensitive: caseSensitive,
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QAfterFilterCondition> filterListIsEmpty() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(FilterCondition.equalTo(
|
||||
property: r'filterList',
|
||||
value: '',
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QAfterFilterCondition> filterListIsNotEmpty() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(FilterCondition.greaterThan(
|
||||
property: r'filterList',
|
||||
value: '',
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QAfterFilterCondition> hasCloudflareIsNull() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(const FilterCondition.isNull(
|
||||
|
|
@ -2588,6 +2775,154 @@ extension SourceQueryFilter on QueryBuilder<Source, Source, QFilterCondition> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QAfterFilterCondition> preferenceListIsNull() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(const FilterCondition.isNull(
|
||||
property: r'preferenceList',
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QAfterFilterCondition>
|
||||
preferenceListIsNotNull() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(const FilterCondition.isNotNull(
|
||||
property: r'preferenceList',
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QAfterFilterCondition> preferenceListEqualTo(
|
||||
String? value, {
|
||||
bool caseSensitive = true,
|
||||
}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(FilterCondition.equalTo(
|
||||
property: r'preferenceList',
|
||||
value: value,
|
||||
caseSensitive: caseSensitive,
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QAfterFilterCondition> preferenceListGreaterThan(
|
||||
String? value, {
|
||||
bool include = false,
|
||||
bool caseSensitive = true,
|
||||
}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(FilterCondition.greaterThan(
|
||||
include: include,
|
||||
property: r'preferenceList',
|
||||
value: value,
|
||||
caseSensitive: caseSensitive,
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QAfterFilterCondition> preferenceListLessThan(
|
||||
String? value, {
|
||||
bool include = false,
|
||||
bool caseSensitive = true,
|
||||
}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(FilterCondition.lessThan(
|
||||
include: include,
|
||||
property: r'preferenceList',
|
||||
value: value,
|
||||
caseSensitive: caseSensitive,
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QAfterFilterCondition> preferenceListBetween(
|
||||
String? lower,
|
||||
String? upper, {
|
||||
bool includeLower = true,
|
||||
bool includeUpper = true,
|
||||
bool caseSensitive = true,
|
||||
}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(FilterCondition.between(
|
||||
property: r'preferenceList',
|
||||
lower: lower,
|
||||
includeLower: includeLower,
|
||||
upper: upper,
|
||||
includeUpper: includeUpper,
|
||||
caseSensitive: caseSensitive,
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QAfterFilterCondition> preferenceListStartsWith(
|
||||
String value, {
|
||||
bool caseSensitive = true,
|
||||
}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(FilterCondition.startsWith(
|
||||
property: r'preferenceList',
|
||||
value: value,
|
||||
caseSensitive: caseSensitive,
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QAfterFilterCondition> preferenceListEndsWith(
|
||||
String value, {
|
||||
bool caseSensitive = true,
|
||||
}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(FilterCondition.endsWith(
|
||||
property: r'preferenceList',
|
||||
value: value,
|
||||
caseSensitive: caseSensitive,
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QAfterFilterCondition> preferenceListContains(
|
||||
String value,
|
||||
{bool caseSensitive = true}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(FilterCondition.contains(
|
||||
property: r'preferenceList',
|
||||
value: value,
|
||||
caseSensitive: caseSensitive,
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QAfterFilterCondition> preferenceListMatches(
|
||||
String pattern,
|
||||
{bool caseSensitive = true}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(FilterCondition.matches(
|
||||
property: r'preferenceList',
|
||||
wildcard: pattern,
|
||||
caseSensitive: caseSensitive,
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QAfterFilterCondition> preferenceListIsEmpty() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(FilterCondition.equalTo(
|
||||
property: r'preferenceList',
|
||||
value: '',
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QAfterFilterCondition>
|
||||
preferenceListIsNotEmpty() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(FilterCondition.greaterThan(
|
||||
property: r'preferenceList',
|
||||
value: '',
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QAfterFilterCondition> repoIsNull() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(const FilterCondition.isNull(
|
||||
|
|
@ -2952,6 +3287,32 @@ extension SourceQueryFilter on QueryBuilder<Source, Source, QFilterCondition> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QAfterFilterCondition> supportLatestIsNull() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(const FilterCondition.isNull(
|
||||
property: r'supportLatest',
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QAfterFilterCondition> supportLatestIsNotNull() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(const FilterCondition.isNotNull(
|
||||
property: r'supportLatest',
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QAfterFilterCondition> supportLatestEqualTo(
|
||||
bool? value) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(FilterCondition.equalTo(
|
||||
property: r'supportLatest',
|
||||
value: value,
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QAfterFilterCondition> typeSourceIsNull() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(const FilterCondition.isNull(
|
||||
|
|
@ -3544,6 +3905,18 @@ extension SourceQuerySortBy on QueryBuilder<Source, Source, QSortBy> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QAfterSortBy> sortByFilterList() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(r'filterList', Sort.asc);
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QAfterSortBy> sortByFilterListDesc() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(r'filterList', Sort.desc);
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QAfterSortBy> sortByHasCloudflare() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(r'hasCloudflare', Sort.asc);
|
||||
|
|
@ -3748,6 +4121,18 @@ extension SourceQuerySortBy on QueryBuilder<Source, Source, QSortBy> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QAfterSortBy> sortByPreferenceList() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(r'preferenceList', Sort.asc);
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QAfterSortBy> sortByPreferenceListDesc() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(r'preferenceList', Sort.desc);
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QAfterSortBy> sortBySourceCode() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(r'sourceCode', Sort.asc);
|
||||
|
|
@ -3784,6 +4169,18 @@ extension SourceQuerySortBy on QueryBuilder<Source, Source, QSortBy> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QAfterSortBy> sortBySupportLatest() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(r'supportLatest', Sort.asc);
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QAfterSortBy> sortBySupportLatestDesc() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(r'supportLatest', Sort.desc);
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QAfterSortBy> sortByTypeSource() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(r'typeSource', Sort.asc);
|
||||
|
|
@ -3906,6 +4303,18 @@ extension SourceQuerySortThenBy on QueryBuilder<Source, Source, QSortThenBy> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QAfterSortBy> thenByFilterList() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(r'filterList', Sort.asc);
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QAfterSortBy> thenByFilterListDesc() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(r'filterList', Sort.desc);
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QAfterSortBy> thenByHasCloudflare() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(r'hasCloudflare', Sort.asc);
|
||||
|
|
@ -4122,6 +4531,18 @@ extension SourceQuerySortThenBy on QueryBuilder<Source, Source, QSortThenBy> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QAfterSortBy> thenByPreferenceList() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(r'preferenceList', Sort.asc);
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QAfterSortBy> thenByPreferenceListDesc() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(r'preferenceList', Sort.desc);
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QAfterSortBy> thenBySourceCode() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(r'sourceCode', Sort.asc);
|
||||
|
|
@ -4158,6 +4579,18 @@ extension SourceQuerySortThenBy on QueryBuilder<Source, Source, QSortThenBy> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QAfterSortBy> thenBySupportLatest() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(r'supportLatest', Sort.asc);
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QAfterSortBy> thenBySupportLatestDesc() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(r'supportLatest', Sort.desc);
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QAfterSortBy> thenByTypeSource() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(r'typeSource', Sort.asc);
|
||||
|
|
@ -4252,6 +4685,13 @@ extension SourceQueryWhereDistinct on QueryBuilder<Source, Source, QDistinct> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QDistinct> distinctByFilterList(
|
||||
{bool caseSensitive = true}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addDistinctBy(r'filterList', caseSensitive: caseSensitive);
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QDistinct> distinctByHasCloudflare() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addDistinctBy(r'hasCloudflare');
|
||||
|
|
@ -4359,6 +4799,14 @@ extension SourceQueryWhereDistinct on QueryBuilder<Source, Source, QDistinct> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QDistinct> distinctByPreferenceList(
|
||||
{bool caseSensitive = true}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addDistinctBy(r'preferenceList',
|
||||
caseSensitive: caseSensitive);
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QDistinct> distinctBySourceCode(
|
||||
{bool caseSensitive = true}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
|
|
@ -4380,6 +4828,12 @@ extension SourceQueryWhereDistinct on QueryBuilder<Source, Source, QDistinct> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QDistinct> distinctBySupportLatest() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addDistinctBy(r'supportLatest');
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Source, QDistinct> distinctByTypeSource(
|
||||
{bool caseSensitive = true}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
|
|
@ -4451,6 +4905,12 @@ extension SourceQueryProperty on QueryBuilder<Source, Source, QQueryProperty> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, String?, QQueryOperations> filterListProperty() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addPropertyName(r'filterList');
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, bool?, QQueryOperations> hasCloudflareProperty() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addPropertyName(r'hasCloudflare');
|
||||
|
|
@ -4553,6 +5013,12 @@ extension SourceQueryProperty on QueryBuilder<Source, Source, QQueryProperty> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, String?, QQueryOperations> preferenceListProperty() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addPropertyName(r'preferenceList');
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, Repo?, QQueryOperations> repoProperty() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addPropertyName(r'repo');
|
||||
|
|
@ -4578,6 +5044,12 @@ extension SourceQueryProperty on QueryBuilder<Source, Source, QQueryProperty> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, bool?, QQueryOperations> supportLatestProperty() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addPropertyName(r'supportLatest');
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Source, String?, QQueryOperations> typeSourceProperty() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addPropertyName(r'typeSource');
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import 'package:mangayomi/models/manga.dart';
|
|||
import 'package:mangayomi/models/source.dart';
|
||||
import 'package:mangayomi/modules/manga/home/widget/filter_widget.dart';
|
||||
import 'package:mangayomi/modules/more/settings/appearance/providers/app_font_family.dart';
|
||||
import 'package:mangayomi/modules/more/settings/browse/providers/browse_state_provider.dart';
|
||||
import 'package:mangayomi/providers/l10n_providers.dart';
|
||||
import 'package:mangayomi/services/get_detail.dart';
|
||||
import 'package:mangayomi/services/get_filter_list.dart';
|
||||
|
|
@ -314,6 +315,7 @@ class _CodeEditorPageState extends ConsumerState<CodeEditorPage> {
|
|||
if (source != null) {
|
||||
final service = getExtensionService(
|
||||
source!,
|
||||
ref.read(androidProxyServerStateProvider),
|
||||
);
|
||||
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_qjs/quickjs/ffi.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:mangayomi/modules/more/settings/browse/providers/browse_state_provider.dart';
|
||||
import 'package:mangayomi/modules/widgets/custom_sliver_grouped_list_view.dart';
|
||||
import 'package:mangayomi/models/manga.dart';
|
||||
import 'package:mangayomi/models/source.dart';
|
||||
|
|
@ -66,6 +68,9 @@ class _ExtensionScreenState extends ConsumerState<ExtensionScreen> {
|
|||
final streamExtensions = ref.watch(
|
||||
getExtensionsStreamProvider(widget.itemType),
|
||||
);
|
||||
final repositories = ref.watch(
|
||||
extensionsRepoStateProvider(widget.itemType),
|
||||
);
|
||||
|
||||
final l10n = l10nLocalizations(context)!;
|
||||
|
||||
|
|
@ -92,6 +97,12 @@ class _ExtensionScreenState extends ConsumerState<ExtensionScreen> {
|
|||
final notInstalledEntries = <Source>[];
|
||||
|
||||
for (var element in filteredData) {
|
||||
if (repositories
|
||||
.firstWhereOrNull((e) => e == element.repo)
|
||||
?.hidden ??
|
||||
false) {
|
||||
continue;
|
||||
}
|
||||
final isLatestVersion = element.version == element.versionLast;
|
||||
|
||||
if (compareVersions(
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:isar/isar.dart';
|
||||
import 'package:mangayomi/eval/model/source_preference.dart';
|
||||
import 'package:mangayomi/main.dart';
|
||||
|
|
@ -11,6 +13,22 @@ void setPreferenceSetting(SourcePreference sourcePreference, Source source) {
|
|||
.keyEqualTo(sourcePreference.key)
|
||||
.findFirstSync();
|
||||
isar.writeTxnSync(() {
|
||||
if (source.sourceCodeLanguage == SourceCodeLanguage.mihon &&
|
||||
source.preferenceList != null) {
|
||||
final prefs = (jsonDecode(source.preferenceList!) as List)
|
||||
.map((e) => SourcePreference.fromJson(e))
|
||||
.toList();
|
||||
final idx = prefs.indexWhere((e) => e.key == sourcePreference.key);
|
||||
if (idx != -1) {
|
||||
prefs[idx] = sourcePreference..id = null;
|
||||
isar.sources.putSync(
|
||||
source
|
||||
..preferenceList = jsonEncode(
|
||||
prefs.map((e) => e.toJson()).toList(),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
if (sourcePref != null) {
|
||||
isar.sourcePreferences.putSync(sourcePreference);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import 'package:isar/isar.dart';
|
||||
import 'package:mangayomi/main.dart';
|
||||
import 'package:mangayomi/models/manga.dart';
|
||||
import 'package:mangayomi/models/settings.dart';
|
||||
import 'package:mangayomi/models/source.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
|
@ -12,6 +13,7 @@ Stream<List<Source>> getExtensionsStream(Ref ref, ItemType itemType) async* {
|
|||
.filter()
|
||||
.idIsNotNull()
|
||||
.and()
|
||||
.repo((q) => q.hiddenIsNull().or().hiddenEqualTo(false))
|
||||
.isActiveEqualTo(true)
|
||||
.itemTypeEqualTo(itemType)
|
||||
.watch(fireImmediately: true);
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ part of 'extensions_provider.dart';
|
|||
// **************************************************************************
|
||||
|
||||
String _$getExtensionsStreamHash() =>
|
||||
r'3c5d6625c40c222f25fc8141df078dd46bcc762f';
|
||||
r'af34092ebf31c784010110af746e3ee2731297bd';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
|
|
|||
|
|
@ -45,15 +45,15 @@ class _SourcePreferenceWidgetState extends State<SourcePreferenceWidget> {
|
|||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => EditTextDialogWidget(
|
||||
text: pref.value!,
|
||||
text: pref.value ?? "",
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
pref.value = value;
|
||||
});
|
||||
setPreferenceSetting(preference, widget.source);
|
||||
},
|
||||
dialogTitle: pref.dialogTitle!,
|
||||
dialogMessage: pref.dialogMessage!,
|
||||
dialogTitle: pref.dialogTitle ?? "",
|
||||
dialogMessage: pref.dialogMessage ?? "",
|
||||
),
|
||||
);
|
||||
},
|
||||
|
|
|
|||
|
|
@ -119,7 +119,7 @@ class _GlobalSearchScreenState extends ConsumerState<GlobalSearchScreen> {
|
|||
}
|
||||
}
|
||||
|
||||
class SourceSearchScreen extends StatefulWidget {
|
||||
class SourceSearchScreen extends ConsumerStatefulWidget {
|
||||
final String query;
|
||||
|
||||
final Source source;
|
||||
|
|
@ -130,10 +130,10 @@ class SourceSearchScreen extends StatefulWidget {
|
|||
});
|
||||
|
||||
@override
|
||||
State<SourceSearchScreen> createState() => _SourceSearchScreenState();
|
||||
ConsumerState<SourceSearchScreen> createState() => _SourceSearchScreenState();
|
||||
}
|
||||
|
||||
class _SourceSearchScreenState extends State<SourceSearchScreen> {
|
||||
class _SourceSearchScreenState extends ConsumerState<SourceSearchScreen> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
|
@ -146,11 +146,13 @@ class _SourceSearchScreenState extends State<SourceSearchScreen> {
|
|||
_init() async {
|
||||
try {
|
||||
_errorMessage = "";
|
||||
pages = await search(
|
||||
source: widget.source,
|
||||
page: 1,
|
||||
query: widget.query,
|
||||
filterList: [],
|
||||
pages = await ref.read(
|
||||
searchProvider(
|
||||
source: widget.source,
|
||||
page: 1,
|
||||
query: widget.query,
|
||||
filterList: [],
|
||||
).future,
|
||||
);
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ Future<dynamic> updateMangaDetail(
|
|||
final source = getSource(manga.lang!, manga.source!);
|
||||
MManga getManga;
|
||||
|
||||
getManga = await ref.watch(
|
||||
getManga = await ref.read(
|
||||
getDetailProvider(url: manga.link!, source: source!).future,
|
||||
);
|
||||
|
||||
|
|
@ -39,9 +39,11 @@ Future<dynamic> updateMangaDetail(
|
|||
.toSet()
|
||||
.toList() ??
|
||||
[];
|
||||
final tempName = getManga.name?.trim().trimLeft().trimRight();
|
||||
final tempLink = getManga.link?.trim().trimLeft().trimRight();
|
||||
manga
|
||||
..imageUrl = getManga.imageUrl ?? manga.imageUrl
|
||||
..name = getManga.name?.trim().trimLeft().trimRight() ?? manga.name
|
||||
..name = tempName != null && tempName.isNotEmpty ? tempName : manga.name
|
||||
..genre = (genre.isEmpty ? null : genre) ?? manga.genre ?? []
|
||||
..author =
|
||||
getManga.author?.trim().trimLeft().trimRight() ?? manga.author ?? ""
|
||||
|
|
@ -54,7 +56,7 @@ Future<dynamic> updateMangaDetail(
|
|||
getManga.description?.trim().trimLeft().trimRight() ??
|
||||
manga.description ??
|
||||
""
|
||||
..link = getManga.link?.trim().trimLeft().trimRight() ?? manga.link
|
||||
..link = tempLink != null && tempLink.isNotEmpty ? tempLink : manga.link
|
||||
..source = manga.source
|
||||
..lang = manga.lang
|
||||
..itemType = source.itemType
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ part of 'update_manga_detail_providers.dart';
|
|||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$updateMangaDetailHash() => r'85660b206c2bce558760118936758a261519cad8';
|
||||
String _$updateMangaDetailHash() => r'05605c26d058a9176a351ba5a79f811987d4ba1a';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
|
|
|||
|
|
@ -140,7 +140,7 @@ class _MigrationScreenScreenState extends ConsumerState<MigrationScreen> {
|
|||
}
|
||||
}
|
||||
|
||||
class MigrationSourceSearchScreen extends StatefulWidget {
|
||||
class MigrationSourceSearchScreen extends ConsumerStatefulWidget {
|
||||
final String query;
|
||||
final Manga manga;
|
||||
final TrackSearch? trackSearch;
|
||||
|
|
@ -155,12 +155,12 @@ class MigrationSourceSearchScreen extends StatefulWidget {
|
|||
});
|
||||
|
||||
@override
|
||||
State<MigrationSourceSearchScreen> createState() =>
|
||||
ConsumerState<MigrationSourceSearchScreen> createState() =>
|
||||
_MigrationSourceSearchScreenState();
|
||||
}
|
||||
|
||||
class _MigrationSourceSearchScreenState
|
||||
extends State<MigrationSourceSearchScreen> {
|
||||
extends ConsumerState<MigrationSourceSearchScreen> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
|
@ -173,11 +173,13 @@ class _MigrationSourceSearchScreenState
|
|||
_init() async {
|
||||
try {
|
||||
_errorMessage = "";
|
||||
pages = await search(
|
||||
source: widget.source,
|
||||
page: 1,
|
||||
query: widget.query,
|
||||
filterList: [],
|
||||
pages = await ref.read(
|
||||
searchProvider(
|
||||
source: widget.source,
|
||||
page: 1,
|
||||
query: widget.query,
|
||||
filterList: [],
|
||||
).future,
|
||||
);
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ class BrowseSScreen extends ConsumerWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final androidProxyServer = ref.watch(androidProxyServerStateProvider);
|
||||
final onlyIncludePinnedSource = ref.watch(
|
||||
onlyIncludePinnedSourceStateProvider,
|
||||
);
|
||||
|
|
@ -52,6 +53,21 @@ class BrowseSScreen extends ConsumerWidget {
|
|||
],
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
onTap: () => _showAndroidProxyServerDialog(
|
||||
context,
|
||||
ref,
|
||||
androidProxyServer,
|
||||
),
|
||||
title: Text(l10n.android_proxy_server),
|
||||
subtitle: Text(
|
||||
androidProxyServer,
|
||||
style: TextStyle(
|
||||
fontSize: 11,
|
||||
color: context.secondaryColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
onTap: () {
|
||||
context.push(
|
||||
|
|
@ -254,6 +270,82 @@ void _showClearAllSourcesDialog(BuildContext context, dynamic l10n) {
|
|||
);
|
||||
}
|
||||
|
||||
void _showAndroidProxyServerDialog(
|
||||
BuildContext context,
|
||||
WidgetRef ref,
|
||||
String proxyServer,
|
||||
) {
|
||||
final serverController = TextEditingController(text: proxyServer);
|
||||
String server = proxyServer;
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => StatefulBuilder(
|
||||
builder: (context, setState) {
|
||||
return AlertDialog(
|
||||
title: Text(
|
||||
context.l10n.android_proxy_server,
|
||||
style: const TextStyle(fontSize: 30),
|
||||
),
|
||||
content: SizedBox(
|
||||
width: context.width(0.8),
|
||||
height: context.height(0.3),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const SizedBox(height: 10),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 10),
|
||||
child: TextFormField(
|
||||
controller: serverController,
|
||||
autofocus: true,
|
||||
onChanged: (value) => setState(() {
|
||||
server = value;
|
||||
}),
|
||||
decoration: InputDecoration(
|
||||
hintText:
|
||||
"Server IP (e.g., 10.0.0.5 or https://example.com)",
|
||||
filled: false,
|
||||
contentPadding: const EdgeInsets.all(12),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderSide: const BorderSide(width: 0.4),
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderSide: const BorderSide(),
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
),
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
borderSide: const BorderSide(),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 10),
|
||||
child: SizedBox(
|
||||
width: context.width(1),
|
||||
child: ElevatedButton(
|
||||
onPressed: () {
|
||||
ref
|
||||
.read(androidProxyServerStateProvider.notifier)
|
||||
.set(server);
|
||||
Navigator.pop(context);
|
||||
},
|
||||
child: Text(context.l10n.dialog_confirm),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _showCleanNonLibraryDialog(BuildContext context, dynamic l10n) {
|
||||
showDialog(
|
||||
context: context,
|
||||
|
|
|
|||
|
|
@ -10,6 +10,39 @@ import 'package:mangayomi/services/http/m_client.dart';
|
|||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
part 'browse_state_provider.g.dart';
|
||||
|
||||
@riverpod
|
||||
class AndroidProxyServerState extends _$AndroidProxyServerState {
|
||||
@override
|
||||
String build() {
|
||||
String proxyServer =
|
||||
isar.settings.getSync(227)!.androidProxyServer ??
|
||||
"http://127.0.0.1:8080";
|
||||
if (!proxyServer.startsWith("http")) {
|
||||
proxyServer = "http://$proxyServer";
|
||||
}
|
||||
if ((proxyServer.contains("localhost") ||
|
||||
RegExp(
|
||||
r'^((25[0-5]|(2[0-4]|1[0-9]|[1-9]|)[0-9])(\.(?!$)|$)){4}$',
|
||||
).hasMatch(proxyServer.replaceAll("://", ":").split(":")[1])) &&
|
||||
proxyServer.split(":").length < 3) {
|
||||
proxyServer = "$proxyServer:8080";
|
||||
}
|
||||
return proxyServer;
|
||||
}
|
||||
|
||||
void set(String value) {
|
||||
final settings = isar.settings.getSync(227);
|
||||
state = value;
|
||||
isar.writeTxnSync(
|
||||
() => isar.settings.putSync(
|
||||
settings!
|
||||
..androidProxyServer = value
|
||||
..updatedAt = DateTime.now().millisecondsSinceEpoch,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@riverpod
|
||||
class OnlyIncludePinnedSourceState extends _$OnlyIncludePinnedSourceState {
|
||||
@override
|
||||
|
|
@ -43,6 +76,16 @@ class ExtensionsRepoState extends _$ExtensionsRepoState {
|
|||
[];
|
||||
}
|
||||
|
||||
void setVisibility(Repo repo, bool hidden) {
|
||||
final value = state.map((e) {
|
||||
if (e == repo) {
|
||||
e.hidden = hidden;
|
||||
}
|
||||
return e;
|
||||
}).toList();
|
||||
set(value);
|
||||
}
|
||||
|
||||
void set(List<Repo> value) {
|
||||
final settings = isar.settings.getSync(227)!;
|
||||
state = value;
|
||||
|
|
|
|||
|
|
@ -157,6 +157,23 @@ class _GetRepoInfosProviderElement
|
|||
String get jsonUrl => (origin as GetRepoInfosProvider).jsonUrl;
|
||||
}
|
||||
|
||||
String _$androidProxyServerStateHash() =>
|
||||
r'3ac060f8a61added586dcefc889fa44c71263c5b';
|
||||
|
||||
/// See also [AndroidProxyServerState].
|
||||
@ProviderFor(AndroidProxyServerState)
|
||||
final androidProxyServerStateProvider =
|
||||
AutoDisposeNotifierProvider<AndroidProxyServerState, String>.internal(
|
||||
AndroidProxyServerState.new,
|
||||
name: r'androidProxyServerStateProvider',
|
||||
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
|
||||
? null
|
||||
: _$androidProxyServerStateHash,
|
||||
dependencies: null,
|
||||
allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
typedef _$AndroidProxyServerState = AutoDisposeNotifier<String>;
|
||||
String _$onlyIncludePinnedSourceStateHash() =>
|
||||
r'b9f707348d5d0f7abfa8e615c1d2b35c6dbd57f3';
|
||||
|
||||
|
|
@ -175,7 +192,7 @@ final onlyIncludePinnedSourceStateProvider =
|
|||
|
||||
typedef _$OnlyIncludePinnedSourceState = AutoDisposeNotifier<bool>;
|
||||
String _$extensionsRepoStateHash() =>
|
||||
r'5c23b8b7ecf83b253b76a2663a71c0c752e53a40';
|
||||
r'86edc9a3f78d72acda4b20a058031c345ee406eb';
|
||||
|
||||
abstract class _$ExtensionsRepoState
|
||||
extends BuildlessAutoDisposeNotifier<List<Repo>> {
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@ import 'package:mangayomi/models/settings.dart';
|
|||
import 'package:mangayomi/modules/more/settings/browse/providers/browse_state_provider.dart';
|
||||
import 'package:mangayomi/modules/widgets/progress_center.dart';
|
||||
import 'package:mangayomi/providers/l10n_providers.dart';
|
||||
import 'package:mangayomi/services/fetch_item_sources.dart';
|
||||
import 'package:mangayomi/utils/cached_network.dart';
|
||||
import 'package:super_sliver_list/super_sliver_list.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
|
|
@ -19,8 +21,13 @@ class SourceRepositories extends ConsumerStatefulWidget {
|
|||
}
|
||||
|
||||
class _SourceRepositoriesState extends ConsumerState<SourceRepositories> {
|
||||
final urlRegex = RegExp(
|
||||
r'^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$',
|
||||
);
|
||||
List<Repo> _entries = [];
|
||||
String urlInput = "";
|
||||
bool isRefreshing = false;
|
||||
|
||||
Future<void> _launchInBrowser(Uri url) async {
|
||||
if (!await launchUrl(url, mode: LaunchMode.externalApplication)) {
|
||||
throw 'Could not launch $url';
|
||||
|
|
@ -41,6 +48,43 @@ class _SourceRepositoriesState extends ConsumerState<SourceRepositories> {
|
|||
ItemType.anime => Text(l10n.manage_anime_repo_urls),
|
||||
_ => Text(l10n.manage_novel_repo_urls),
|
||||
},
|
||||
actions: [
|
||||
isRefreshing
|
||||
? const Padding(
|
||||
padding: EdgeInsets.all(20.0),
|
||||
child: SizedBox(
|
||||
width: 16,
|
||||
height: 16,
|
||||
child: CircularProgressIndicator(strokeWidth: 3),
|
||||
),
|
||||
)
|
||||
: Padding(
|
||||
padding: EdgeInsets.all(8.0),
|
||||
child: IconButton(
|
||||
splashRadius: 20,
|
||||
onPressed: () async {
|
||||
setState(() {
|
||||
isRefreshing = true;
|
||||
});
|
||||
final result = await ref.refresh(
|
||||
fetchItemSourcesListProvider(
|
||||
id: null,
|
||||
reFresh: true,
|
||||
itemType: widget.itemType,
|
||||
).future,
|
||||
);
|
||||
setState(() {
|
||||
isRefreshing = false;
|
||||
});
|
||||
return result;
|
||||
},
|
||||
icon: Icon(
|
||||
Icons.refresh,
|
||||
color: Theme.of(context).hintColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
body: data.when(
|
||||
data: (data) {
|
||||
|
|
@ -62,6 +106,12 @@ class _SourceRepositoriesState extends ConsumerState<SourceRepositories> {
|
|||
itemCount: _entries.length,
|
||||
itemBuilder: (context, index) {
|
||||
final repo = _entries[index];
|
||||
final isHidden = repo.hidden ?? false;
|
||||
final repoAvatar = urlRegex
|
||||
.firstMatch(repo.jsonUrl ?? "")
|
||||
?.group(4)
|
||||
?.split("/")
|
||||
.elementAtOrNull(1);
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8),
|
||||
child: Card(
|
||||
|
|
@ -69,25 +119,53 @@ class _SourceRepositoriesState extends ConsumerState<SourceRepositories> {
|
|||
padding: const EdgeInsets.symmetric(horizontal: 10),
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 8,
|
||||
vertical: 15,
|
||||
Opacity(
|
||||
opacity: isHidden ? 0.3 : 1,
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
if (repoAvatar != null)
|
||||
Padding(
|
||||
padding: EdgeInsets.all(8.0),
|
||||
child: cachedNetworkImage(
|
||||
imageUrl:
|
||||
"https://github.com/$repoAvatar.png?size=64",
|
||||
fit: BoxFit.contain,
|
||||
width: 64,
|
||||
height: 64,
|
||||
errorWidget: const Padding(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 8,
|
||||
vertical: 15,
|
||||
),
|
||||
child: Icon(Icons.label_outline_rounded),
|
||||
),
|
||||
useCustomNetworkImage: false,
|
||||
),
|
||||
),
|
||||
if (repoAvatar == null)
|
||||
const Padding(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 8,
|
||||
vertical: 15,
|
||||
),
|
||||
child: Icon(Icons.label_outline_rounded),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Expanded(
|
||||
child: Text(
|
||||
repo.name ??
|
||||
repo.jsonUrl ??
|
||||
"Invalid source - remove it",
|
||||
style: TextStyle(
|
||||
decoration: isHidden
|
||||
? TextDecoration.lineThrough
|
||||
: TextDecoration.none,
|
||||
),
|
||||
),
|
||||
),
|
||||
child: const Icon(Icons.label_outline_rounded),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Expanded(
|
||||
child: Text(
|
||||
repo.name ??
|
||||
repo.jsonUrl ??
|
||||
"Invalid source - remove it",
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
|
|
@ -112,72 +190,40 @@ class _SourceRepositoriesState extends ConsumerState<SourceRepositories> {
|
|||
),
|
||||
SizedBox(width: 10),
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return StatefulBuilder(
|
||||
builder: (context, setState) {
|
||||
return AlertDialog(
|
||||
title: Text(
|
||||
l10n.remove_extensions_repo,
|
||||
),
|
||||
content: Text(
|
||||
l10n.remove_extensions_repo,
|
||||
),
|
||||
actions: [
|
||||
Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.end,
|
||||
children: [
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
child: Text(l10n.cancel),
|
||||
),
|
||||
const SizedBox(width: 15),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
final mangaRepos = ref
|
||||
.read(
|
||||
extensionsRepoStateProvider(
|
||||
widget.itemType,
|
||||
),
|
||||
)
|
||||
.toList();
|
||||
mangaRepos.removeWhere(
|
||||
(url) =>
|
||||
url ==
|
||||
_entries[index],
|
||||
);
|
||||
ref
|
||||
.read(
|
||||
extensionsRepoStateProvider(
|
||||
widget.itemType,
|
||||
).notifier,
|
||||
)
|
||||
.set(mangaRepos);
|
||||
ref.watch(
|
||||
extensionsRepoStateProvider(
|
||||
widget.itemType,
|
||||
),
|
||||
);
|
||||
if (context.mounted) {
|
||||
Navigator.pop(context);
|
||||
}
|
||||
},
|
||||
child: Text(l10n.ok),
|
||||
),
|
||||
],
|
||||
onPressed: () => ref
|
||||
.read(
|
||||
extensionsRepoStateProvider(
|
||||
widget.itemType,
|
||||
).notifier,
|
||||
)
|
||||
.setVisibility(repo, !isHidden),
|
||||
icon: Stack(
|
||||
children: [
|
||||
const Icon(Icons.remove_red_eye_outlined),
|
||||
if (!isHidden)
|
||||
Positioned(
|
||||
right: 8,
|
||||
child: Transform.scale(
|
||||
scaleX: 2.5,
|
||||
child: const Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
'\\',
|
||||
style: TextStyle(fontSize: 17),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
IconButton(
|
||||
onPressed: () =>
|
||||
_showRemoveRepoDialog(context, index),
|
||||
icon: const Icon(Icons.delete_outlined),
|
||||
),
|
||||
],
|
||||
|
|
@ -207,144 +253,7 @@ class _SourceRepositoriesState extends ConsumerState<SourceRepositories> {
|
|||
},
|
||||
),
|
||||
floatingActionButton: FloatingActionButton.extended(
|
||||
onPressed: () {
|
||||
bool isLoading = false;
|
||||
final controller = TextEditingController();
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return SizedBox(
|
||||
child: StatefulBuilder(
|
||||
builder: (context, setState) {
|
||||
return AlertDialog(
|
||||
title: Text(l10n.add_extensions_repo),
|
||||
content: TextFormField(
|
||||
controller: controller,
|
||||
autofocus: true,
|
||||
keyboardType: TextInputType.url,
|
||||
onChanged: (value) => setState(() {}),
|
||||
validator: (value) {
|
||||
if (value == null || value.isEmpty) {
|
||||
return l10n.url_cannot_be_empty;
|
||||
}
|
||||
if (!value.endsWith('.json')) {
|
||||
return l10n.url_must_end_with_dot_json;
|
||||
}
|
||||
try {
|
||||
final uri = Uri.parse(value);
|
||||
if (!uri.isAbsolute) {
|
||||
return l10n.invalid_url_format;
|
||||
}
|
||||
return null;
|
||||
} catch (e) {
|
||||
return l10n.invalid_url_format;
|
||||
}
|
||||
},
|
||||
autovalidateMode: AutovalidateMode.onUserInteraction,
|
||||
decoration: InputDecoration(
|
||||
hintText: l10n.url_must_end_with_dot_json,
|
||||
filled: false,
|
||||
contentPadding: const EdgeInsets.all(12),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderSide: const BorderSide(width: 0.4),
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderSide: const BorderSide(),
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
),
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
borderSide: const BorderSide(),
|
||||
),
|
||||
),
|
||||
),
|
||||
actions: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
child: Text(l10n.cancel),
|
||||
),
|
||||
const SizedBox(width: 15),
|
||||
StatefulBuilder(
|
||||
builder: (context, setState) {
|
||||
return TextButton(
|
||||
onPressed:
|
||||
controller.text.isEmpty ||
|
||||
!controller.text.endsWith(".json")
|
||||
? null
|
||||
: () async {
|
||||
setState(() => isLoading = true);
|
||||
try {
|
||||
final mangaRepos = ref
|
||||
.read(
|
||||
extensionsRepoStateProvider(
|
||||
widget.itemType,
|
||||
),
|
||||
)
|
||||
.toList();
|
||||
final repo = await ref.read(
|
||||
getRepoInfosProvider(
|
||||
jsonUrl: controller.text,
|
||||
).future,
|
||||
);
|
||||
if (repo == null) {
|
||||
botToast(l10n.unsupported_repo);
|
||||
return;
|
||||
}
|
||||
mangaRepos.add(repo);
|
||||
ref
|
||||
.read(
|
||||
extensionsRepoStateProvider(
|
||||
widget.itemType,
|
||||
).notifier,
|
||||
)
|
||||
.set(mangaRepos);
|
||||
} catch (e, s) {
|
||||
setState(() => isLoading = false);
|
||||
botToast('$e\n$s');
|
||||
}
|
||||
|
||||
if (context.mounted) {
|
||||
Navigator.pop(context);
|
||||
}
|
||||
},
|
||||
child: isLoading
|
||||
? SizedBox(
|
||||
height: 20,
|
||||
width: 20,
|
||||
child: CircularProgressIndicator(),
|
||||
)
|
||||
: Text(
|
||||
l10n.add,
|
||||
style: TextStyle(
|
||||
color:
|
||||
controller.text.isEmpty ||
|
||||
!controller.text.endsWith(
|
||||
".json",
|
||||
)
|
||||
? Theme.of(context).primaryColor
|
||||
.withValues(alpha: 0.2)
|
||||
: null,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
onPressed: () => _showAddRepoDialog(context),
|
||||
label: Row(
|
||||
children: [
|
||||
const Icon(Icons.add),
|
||||
|
|
@ -355,4 +264,193 @@ class _SourceRepositoriesState extends ConsumerState<SourceRepositories> {
|
|||
),
|
||||
);
|
||||
}
|
||||
|
||||
_showRemoveRepoDialog(BuildContext context, int index) {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return StatefulBuilder(
|
||||
builder: (context, setState) {
|
||||
final l10n = context.l10n;
|
||||
return AlertDialog(
|
||||
title: Text(l10n.remove_extensions_repo),
|
||||
content: Text(l10n.remove_extensions_repo),
|
||||
actions: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
child: Text(l10n.cancel),
|
||||
),
|
||||
const SizedBox(width: 15),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
final mangaRepos = ref
|
||||
.read(extensionsRepoStateProvider(widget.itemType))
|
||||
.toList();
|
||||
mangaRepos.removeWhere((url) => url == _entries[index]);
|
||||
ref
|
||||
.read(
|
||||
extensionsRepoStateProvider(
|
||||
widget.itemType,
|
||||
).notifier,
|
||||
)
|
||||
.set(mangaRepos);
|
||||
ref.watch(extensionsRepoStateProvider(widget.itemType));
|
||||
if (context.mounted) {
|
||||
Navigator.pop(context);
|
||||
}
|
||||
},
|
||||
child: Text(l10n.ok),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
_showAddRepoDialog(BuildContext context) {
|
||||
bool isLoading = false;
|
||||
final controller = TextEditingController();
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return SizedBox(
|
||||
child: StatefulBuilder(
|
||||
builder: (context, setState) {
|
||||
final l10n = context.l10n;
|
||||
return AlertDialog(
|
||||
title: Text(l10n.add_extensions_repo),
|
||||
content: TextFormField(
|
||||
controller: controller,
|
||||
autofocus: true,
|
||||
keyboardType: TextInputType.url,
|
||||
onChanged: (value) => setState(() {}),
|
||||
validator: (value) {
|
||||
if (value == null || value.isEmpty) {
|
||||
return l10n.url_cannot_be_empty;
|
||||
}
|
||||
if (!value.endsWith('.json')) {
|
||||
return l10n.url_must_end_with_dot_json;
|
||||
}
|
||||
try {
|
||||
final uri = Uri.parse(value);
|
||||
if (!uri.isAbsolute) {
|
||||
return l10n.invalid_url_format;
|
||||
}
|
||||
return null;
|
||||
} catch (e) {
|
||||
return l10n.invalid_url_format;
|
||||
}
|
||||
},
|
||||
autovalidateMode: AutovalidateMode.onUserInteraction,
|
||||
decoration: InputDecoration(
|
||||
hintText: l10n.url_must_end_with_dot_json,
|
||||
filled: false,
|
||||
contentPadding: const EdgeInsets.all(12),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderSide: const BorderSide(width: 0.4),
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderSide: const BorderSide(),
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
),
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
borderSide: const BorderSide(),
|
||||
),
|
||||
),
|
||||
),
|
||||
actions: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
child: Text(l10n.cancel),
|
||||
),
|
||||
const SizedBox(width: 15),
|
||||
StatefulBuilder(
|
||||
builder: (context, setState) {
|
||||
return TextButton(
|
||||
onPressed:
|
||||
controller.text.isEmpty ||
|
||||
!controller.text.endsWith(".json")
|
||||
? null
|
||||
: () async {
|
||||
setState(() => isLoading = true);
|
||||
try {
|
||||
final mangaRepos = ref
|
||||
.read(
|
||||
extensionsRepoStateProvider(
|
||||
widget.itemType,
|
||||
),
|
||||
)
|
||||
.toList();
|
||||
final repo = await ref.read(
|
||||
getRepoInfosProvider(
|
||||
jsonUrl: controller.text,
|
||||
).future,
|
||||
);
|
||||
if (repo == null) {
|
||||
botToast(l10n.unsupported_repo);
|
||||
return;
|
||||
}
|
||||
mangaRepos.add(repo);
|
||||
ref
|
||||
.read(
|
||||
extensionsRepoStateProvider(
|
||||
widget.itemType,
|
||||
).notifier,
|
||||
)
|
||||
.set(mangaRepos);
|
||||
} catch (e, s) {
|
||||
setState(() => isLoading = false);
|
||||
botToast('$e\n$s');
|
||||
}
|
||||
|
||||
if (context.mounted) {
|
||||
Navigator.pop(context);
|
||||
}
|
||||
},
|
||||
child: isLoading
|
||||
? SizedBox(
|
||||
height: 20,
|
||||
width: 20,
|
||||
child: CircularProgressIndicator(),
|
||||
)
|
||||
: Text(
|
||||
l10n.add,
|
||||
style: TextStyle(
|
||||
color:
|
||||
controller.text.isEmpty ||
|
||||
!controller.text.endsWith(".json")
|
||||
? Theme.of(context).primaryColor
|
||||
.withValues(alpha: 0.2)
|
||||
: null,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ class _GeneralStateScreen extends ConsumerState<GeneralScreen> {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final l10n = l10nLocalizations(context);
|
||||
final customDns = ref.watch(customDnsStateProvider);
|
||||
final enableDiscordRpc = ref.watch(enableDiscordRpcStateProvider);
|
||||
final hideDiscordRpcInIncognito = ref.watch(
|
||||
hideDiscordRpcInIncognitoStateProvider,
|
||||
|
|
@ -48,6 +49,14 @@ class _GeneralStateScreen extends ConsumerState<GeneralScreen> {
|
|||
body: SingleChildScrollView(
|
||||
child: Column(
|
||||
children: [
|
||||
ListTile(
|
||||
onTap: () => _showCustomDnsDialog(context, ref, customDns),
|
||||
title: Text(l10n.custom_dns),
|
||||
subtitle: Text(
|
||||
customDns,
|
||||
style: TextStyle(fontSize: 11, color: context.secondaryColor),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
margin: const EdgeInsets.all(20.0),
|
||||
padding: const EdgeInsets.all(10.0),
|
||||
|
|
@ -290,4 +299,77 @@ class _GeneralStateScreen extends ConsumerState<GeneralScreen> {
|
|||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _showCustomDnsDialog(
|
||||
BuildContext context,
|
||||
WidgetRef ref,
|
||||
String customDns,
|
||||
) {
|
||||
final dnsController = TextEditingController(text: customDns);
|
||||
String dns = customDns;
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => StatefulBuilder(
|
||||
builder: (context, setState) {
|
||||
return AlertDialog(
|
||||
title: Text(
|
||||
context.l10n.custom_dns,
|
||||
style: const TextStyle(fontSize: 30),
|
||||
),
|
||||
content: SizedBox(
|
||||
width: context.width(0.8),
|
||||
height: context.height(0.3),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const SizedBox(height: 10),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 10),
|
||||
child: TextFormField(
|
||||
controller: dnsController,
|
||||
autofocus: true,
|
||||
onChanged: (value) => setState(() {
|
||||
dns = value;
|
||||
}),
|
||||
decoration: InputDecoration(
|
||||
hintText: "8.8.8.8",
|
||||
filled: false,
|
||||
contentPadding: const EdgeInsets.all(12),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderSide: const BorderSide(width: 0.4),
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderSide: const BorderSide(),
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
),
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
borderSide: const BorderSide(),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 10),
|
||||
child: SizedBox(
|
||||
width: context.width(1),
|
||||
child: ElevatedButton(
|
||||
onPressed: () {
|
||||
ref.read(customDnsStateProvider.notifier).set(dns);
|
||||
Navigator.pop(context);
|
||||
},
|
||||
child: Text(context.l10n.dialog_confirm),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,26 @@ import 'package:mangayomi/models/settings.dart';
|
|||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
part 'general_state_provider.g.dart';
|
||||
|
||||
@riverpod
|
||||
class CustomDnsState extends _$CustomDnsState {
|
||||
@override
|
||||
String build() {
|
||||
return isar.settings.getSync(227)!.customDns ?? "";
|
||||
}
|
||||
|
||||
void set(String value) {
|
||||
final settings = isar.settings.getSync(227);
|
||||
state = value;
|
||||
isar.writeTxnSync(
|
||||
() => isar.settings.putSync(
|
||||
settings!
|
||||
..customDns = value
|
||||
..updatedAt = DateTime.now().millisecondsSinceEpoch,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@riverpod
|
||||
class EnableDiscordRpcState extends _$EnableDiscordRpcState {
|
||||
@override
|
||||
|
|
|
|||
|
|
@ -6,6 +6,22 @@ part of 'general_state_provider.dart';
|
|||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$customDnsStateHash() => r'6061c64d742b3f873e54c1b9ef724b7c0b6350a2';
|
||||
|
||||
/// See also [CustomDnsState].
|
||||
@ProviderFor(CustomDnsState)
|
||||
final customDnsStateProvider =
|
||||
AutoDisposeNotifierProvider<CustomDnsState, String>.internal(
|
||||
CustomDnsState.new,
|
||||
name: r'customDnsStateProvider',
|
||||
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
|
||||
? null
|
||||
: _$customDnsStateHash,
|
||||
dependencies: null,
|
||||
allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
typedef _$CustomDnsState = AutoDisposeNotifier<String>;
|
||||
String _$enableDiscordRpcStateHash() =>
|
||||
r'ab8ce3b29f5d94aedbc88dcb87c7c834648270f5';
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ part of 'aniskip.dart';
|
|||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$aniSkipHash() => r'887869b54e2e151633efd46da83bde845e14f421';
|
||||
String _$aniSkipHash() => r'2e5d19b025a2207ff64da7bf7908450ea9e5ff8c';
|
||||
|
||||
/// See also [AniSkip].
|
||||
@ProviderFor(AniSkip)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,10 @@
|
|||
import 'dart:convert';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:http_interceptor/http_interceptor.dart';
|
||||
import 'package:isar/isar.dart';
|
||||
import 'package:mangayomi/eval/lib.dart';
|
||||
import 'package:mangayomi/eval/model/filter.dart';
|
||||
import 'package:mangayomi/eval/model/source_preference.dart';
|
||||
import 'package:mangayomi/main.dart';
|
||||
import 'package:mangayomi/models/manga.dart';
|
||||
import 'package:mangayomi/models/settings.dart';
|
||||
|
|
@ -25,7 +28,57 @@ Future<void> fetchSourcesList({
|
|||
final info = await PackageInfo.fromPlatform();
|
||||
|
||||
final sourceList = (jsonDecode(req.body) as List)
|
||||
.map((e) => Source.fromJson(e))
|
||||
.expand((e) sync* {
|
||||
if (e['name'] != null &&
|
||||
e['pkg'] != null &&
|
||||
e['version'] != null &&
|
||||
e['code'] != null &&
|
||||
e['lang'] != null &&
|
||||
e['nsfw'] != null &&
|
||||
e['sources'] != null &&
|
||||
e['apk'] != null) {
|
||||
final repoUrl = url.replaceAll("/index.min.json", "");
|
||||
final sources = e['sources'] as List;
|
||||
for (final source in sources) {
|
||||
final src = Source.fromJson(e)
|
||||
..apiUrl = ''
|
||||
..appMinVerReq = ''
|
||||
..dateFormat = ''
|
||||
..dateFormatLocale = ''
|
||||
..hasCloudflare = false
|
||||
..headers = ''
|
||||
..isActive = true
|
||||
..isAdded = false
|
||||
..isFullData = false
|
||||
..isNsfw = e['nsfw'] == 1
|
||||
..isPinned = false
|
||||
..lastUsed = false
|
||||
..sourceCode = ''
|
||||
..typeSource = ''
|
||||
..versionLast = '0.0.1'
|
||||
..isObsolete = false
|
||||
..isLocal = false
|
||||
..name = source['name']
|
||||
..lang = source['lang']
|
||||
..baseUrl = source['baseUrl']
|
||||
..sourceCodeUrl = "$repoUrl/apk/${e['apk']}"
|
||||
..sourceCodeLanguage = SourceCodeLanguage.mihon
|
||||
..itemType =
|
||||
(e['pkg'] as String).startsWith(
|
||||
"eu.kanade.tachiyomi.animeextension",
|
||||
)
|
||||
? ItemType.anime
|
||||
: ItemType.manga
|
||||
..iconUrl = "$repoUrl/icon/${e['pkg']}.png"
|
||||
..notes =
|
||||
"Requires Android Proxy Server (ApkBridge) for installing and using the extensions!";
|
||||
src.id = 'mihon-${source['id']}'.hashCode;
|
||||
yield src;
|
||||
}
|
||||
} else {
|
||||
yield Source.fromJson(e);
|
||||
}
|
||||
})
|
||||
.where(
|
||||
(source) =>
|
||||
source.itemType == itemType &&
|
||||
|
|
@ -74,14 +127,51 @@ Future<void> _updateSource(
|
|||
) async {
|
||||
final http = MClient.init(reqcopyWith: {'useDartHttpClient': true});
|
||||
final req = await http.get(Uri.parse(source.sourceCodeUrl!));
|
||||
final headers = getExtensionService(
|
||||
source..sourceCode = req.body,
|
||||
).getHeaders();
|
||||
final sourceCode = source.sourceCodeLanguage == SourceCodeLanguage.mihon
|
||||
? base64.encode(req.bodyBytes)
|
||||
: req.body;
|
||||
final androidProxyServer = ref.read(androidProxyServerStateProvider);
|
||||
Map<String, String> headers = {};
|
||||
bool? supportLatest;
|
||||
FilterList? filterList;
|
||||
List<SourcePreference>? preferenceList;
|
||||
if (source.sourceCodeLanguage == SourceCodeLanguage.mihon) {
|
||||
headers = await fetchHeadersDalvik(
|
||||
http,
|
||||
source..sourceCode = sourceCode,
|
||||
androidProxyServer,
|
||||
);
|
||||
supportLatest = await fetchSupportLatestDalvik(
|
||||
http,
|
||||
source..sourceCode = sourceCode,
|
||||
androidProxyServer,
|
||||
);
|
||||
filterList = await fetchFilterListDalvik(
|
||||
http,
|
||||
source..sourceCode = sourceCode,
|
||||
androidProxyServer,
|
||||
);
|
||||
preferenceList = await fetchPreferencesDalvik(
|
||||
http,
|
||||
source..sourceCode = sourceCode,
|
||||
androidProxyServer,
|
||||
);
|
||||
} else {
|
||||
headers = getExtensionService(
|
||||
source..sourceCode = sourceCode,
|
||||
androidProxyServer,
|
||||
).getHeaders();
|
||||
}
|
||||
|
||||
final updatedSource = Source()
|
||||
..headers = jsonEncode(headers)
|
||||
..supportLatest = supportLatest
|
||||
..filterList = filterList != null ? jsonEncode(filterList.toJson()) : null
|
||||
..preferenceList = preferenceList != null
|
||||
? jsonEncode(preferenceList.map((e) => e.toJson()).toList())
|
||||
: null
|
||||
..isAdded = true
|
||||
..sourceCode = req.body
|
||||
..sourceCode = sourceCode
|
||||
..sourceCodeUrl = source.sourceCodeUrl
|
||||
..id = source.id
|
||||
..apiUrl = source.apiUrl
|
||||
|
|
@ -200,3 +290,160 @@ int compareVersions(String version1, String version2) {
|
|||
|
||||
return v1Parts.length.compareTo(v2Parts.length);
|
||||
}
|
||||
|
||||
Future<Map<String, String>> fetchHeadersDalvik(
|
||||
InterceptedClient client,
|
||||
Source source,
|
||||
String androidProxyServer,
|
||||
) async {
|
||||
try {
|
||||
final name = source.itemType == ItemType.anime ? "Anime" : "Manga";
|
||||
final res = await client.post(
|
||||
Uri.parse("$androidProxyServer/dalvik"),
|
||||
body: jsonEncode({"method": "headers$name", "data": source.sourceCode}),
|
||||
);
|
||||
final data = jsonDecode(res.body) as List;
|
||||
final Map<String, String> headers = {};
|
||||
for (var i = 0; i + 1 < data.length; i += 2) {
|
||||
headers[data[i]] = data[i + 1];
|
||||
}
|
||||
return headers;
|
||||
} catch (_) {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> fetchSupportLatestDalvik(
|
||||
InterceptedClient client,
|
||||
Source source,
|
||||
String androidProxyServer,
|
||||
) async {
|
||||
try {
|
||||
final name = source.itemType == ItemType.anime ? "Anime" : "Manga";
|
||||
final res = await client.post(
|
||||
Uri.parse("$androidProxyServer/dalvik"),
|
||||
body: jsonEncode({
|
||||
"method": "supportLatest$name",
|
||||
"data": source.sourceCode,
|
||||
}),
|
||||
);
|
||||
return res.body.trim() == "true";
|
||||
} catch (_) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Future<FilterList?> fetchFilterListDalvik(
|
||||
InterceptedClient client,
|
||||
Source source,
|
||||
String androidProxyServer,
|
||||
) async {
|
||||
try {
|
||||
final name = source.itemType == ItemType.anime ? "Anime" : "Manga";
|
||||
final res = await client.post(
|
||||
Uri.parse("$androidProxyServer/dalvik"),
|
||||
body: jsonEncode({"method": "filters$name", "data": source.sourceCode}),
|
||||
);
|
||||
final data = jsonDecode(res.body) as List;
|
||||
final filters = data.expand((e) sync* {
|
||||
if (e['name'] is String &&
|
||||
e['state'] is Map<String, dynamic> &&
|
||||
e['values'] is List) {
|
||||
yield SortFilter(
|
||||
"${e['name']}Filter",
|
||||
e['name'],
|
||||
SortState(e['state']['index'], e['state']['ascending'], null),
|
||||
(e['values'] as List)
|
||||
.map((e) => SelectFilterOption(e, e, null))
|
||||
.toList(),
|
||||
null,
|
||||
);
|
||||
} else if (e['name'] is String &&
|
||||
e['state'] is int &&
|
||||
(e['values'] is List || e['vals'] is List)) {
|
||||
yield SelectFilter(
|
||||
"${e['name']}Filter",
|
||||
e['name'],
|
||||
e['state'],
|
||||
e['vals'] is List
|
||||
? (e['vals'] as List)
|
||||
.map(
|
||||
(e) => SelectFilterOption(e['first'], e['second'], null),
|
||||
)
|
||||
.toList()
|
||||
: e['values'] is List
|
||||
? (e['values'] as List)
|
||||
.map((e) => SelectFilterOption(e, e, null))
|
||||
.toList()
|
||||
: [],
|
||||
"SelectFilter",
|
||||
);
|
||||
} else if (e['name'] is String && e['state'] is List) {
|
||||
yield GroupFilter(
|
||||
"${e['name']}Filter",
|
||||
e['name'],
|
||||
(e['state'] as List).map((e) {
|
||||
if (e['included'] is bool &&
|
||||
e['ignored'] is bool &&
|
||||
e['excluded'] is bool) {
|
||||
return TriStateFilter(
|
||||
null,
|
||||
e['name'],
|
||||
e['id'] ?? e['name'],
|
||||
null,
|
||||
state: e['state'],
|
||||
);
|
||||
}
|
||||
return CheckBoxFilter(
|
||||
null,
|
||||
e['name'],
|
||||
e['id'] ?? e['name'],
|
||||
null,
|
||||
state: e['state'],
|
||||
);
|
||||
}).toList(),
|
||||
"GroupFilter",
|
||||
);
|
||||
} else if (e['name'] is String && e['state'] is String) {
|
||||
yield TextFilter(
|
||||
"${e['name']}Filter",
|
||||
e['name'],
|
||||
null,
|
||||
state: e['state'],
|
||||
);
|
||||
} else if (e['name'] is String && e['state'] is int) {
|
||||
yield HeaderFilter(e['name'], "${e['name']}Filter");
|
||||
}
|
||||
}).toList();
|
||||
return FilterList(filters);
|
||||
} catch (_) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Future<List<SourcePreference>?> fetchPreferencesDalvik(
|
||||
InterceptedClient client,
|
||||
Source source,
|
||||
String androidProxyServer,
|
||||
) async {
|
||||
try {
|
||||
final name = source.itemType == ItemType.anime ? "Anime" : "Manga";
|
||||
final res = await client.post(
|
||||
Uri.parse("$androidProxyServer/dalvik"),
|
||||
body: jsonEncode({
|
||||
"method": "preferences$name",
|
||||
"data": source.sourceCode,
|
||||
}),
|
||||
);
|
||||
final data = jsonDecode(res.body) as List;
|
||||
return data
|
||||
.map(
|
||||
(e) => SourcePreference.fromJson(e)
|
||||
..id = null
|
||||
..sourceId = source.id,
|
||||
)
|
||||
.toList();
|
||||
} catch (_) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import 'dart:convert';
|
|||
import 'dart:io';
|
||||
import 'dart:typed_data';
|
||||
import 'package:mangayomi/modules/manga/reader/u_chap_data_preload.dart';
|
||||
import 'package:mangayomi/modules/more/settings/browse/providers/browse_state_provider.dart';
|
||||
import 'package:path/path.dart' as p;
|
||||
import 'package:mangayomi/eval/lib.dart';
|
||||
import 'package:mangayomi/eval/javascript/http.dart';
|
||||
|
|
@ -74,7 +75,10 @@ Future<GetChapterPagesModel> getChapterPages(
|
|||
pageUrls.add(PageUrl(isarPageUrls.urls![i], headers: headers));
|
||||
}
|
||||
} else {
|
||||
pageUrls = await getExtensionService(source).getPageList(chapter.url!);
|
||||
pageUrls = await getExtensionService(
|
||||
source,
|
||||
ref.read(androidProxyServerStateProvider),
|
||||
).getPageList(chapter.url!);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ part of 'get_chapter_pages.dart';
|
|||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$getChapterPagesHash() => r'08f56022f03c4834c69c50d0020007fa8b26c091';
|
||||
String _$getChapterPagesHash() => r'8f6d2d661593fc5537f4dda83abea8d46d65b027';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import 'package:mangayomi/eval/lib.dart';
|
||||
import 'package:mangayomi/eval/model/m_manga.dart';
|
||||
import 'package:mangayomi/models/source.dart';
|
||||
import 'package:mangayomi/modules/more/settings/browse/providers/browse_state_provider.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
part 'get_detail.g.dart';
|
||||
|
|
@ -11,5 +12,8 @@ Future<MManga> getDetail(
|
|||
required String url,
|
||||
required Source source,
|
||||
}) async {
|
||||
return getExtensionService(source).getDetail(url);
|
||||
return getExtensionService(
|
||||
source,
|
||||
ref.read(androidProxyServerStateProvider),
|
||||
).getDetail(url);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ part of 'get_detail.dart';
|
|||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$getDetailHash() => r'84cc79aa0fd35a2d8efa95f75b85978f521c5daa';
|
||||
String _$getDetailHash() => r'6b758b79281cb00a7df2fe1903d4a67068052bca';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,12 @@
|
|||
import 'package:mangayomi/eval/lib.dart';
|
||||
import 'package:mangayomi/models/source.dart';
|
||||
|
||||
List<dynamic> getFilterList({required Source source}) {
|
||||
return getExtensionService(source).getFilterList().filters;
|
||||
List<dynamic> getFilterList({
|
||||
required Source source,
|
||||
String androidProxyServer = "",
|
||||
}) {
|
||||
return getExtensionService(
|
||||
source,
|
||||
androidProxyServer,
|
||||
).getFilterList().filters;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import 'package:epubx/epubx.dart';
|
|||
import 'package:html/parser.dart';
|
||||
import 'package:mangayomi/eval/lib.dart';
|
||||
import 'package:mangayomi/models/chapter.dart';
|
||||
import 'package:mangayomi/modules/more/settings/browse/providers/browse_state_provider.dart';
|
||||
import 'package:mangayomi/providers/storage_provider.dart';
|
||||
import 'package:mangayomi/utils/utils.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
|
|
@ -48,11 +49,16 @@ Future<(String, EpubBook?)> getHtmlContent(
|
|||
chapter.manga.value!.source!,
|
||||
);
|
||||
String? html;
|
||||
final proxyServer = ref.read(androidProxyServerStateProvider);
|
||||
if (htmlContent != null) {
|
||||
html = await getExtensionService(source!).cleanHtmlContent(htmlContent);
|
||||
html = await getExtensionService(
|
||||
source!,
|
||||
proxyServer,
|
||||
).cleanHtmlContent(htmlContent);
|
||||
} else {
|
||||
html = await getExtensionService(
|
||||
source!,
|
||||
proxyServer,
|
||||
).getHtmlContent(chapter.manga.value!.name!, chapter.url!);
|
||||
}
|
||||
return (_buildHtml(html.substring(1, html.length - 1)), null);
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ part of 'get_html_content.dart';
|
|||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$getHtmlContentHash() => r'19e6959d8fceb065b19c6c6d38cd1b5132a8ba94';
|
||||
String _$getHtmlContentHash() => r'c32670ed25b093761c867f5cf1cb5dfe063edc84';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import 'package:mangayomi/eval/lib.dart';
|
||||
import 'package:mangayomi/eval/model/m_pages.dart';
|
||||
import 'package:mangayomi/models/source.dart';
|
||||
import 'package:mangayomi/modules/more/settings/browse/providers/browse_state_provider.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
part 'get_latest_updates.g.dart';
|
||||
|
|
@ -11,5 +12,8 @@ Future<MPages?> getLatestUpdates(
|
|||
required Source source,
|
||||
required int page,
|
||||
}) async {
|
||||
return getExtensionService(source).getLatestUpdates(page);
|
||||
return getExtensionService(
|
||||
source,
|
||||
ref.read(androidProxyServerStateProvider),
|
||||
).getLatestUpdates(page);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ part of 'get_latest_updates.dart';
|
|||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$getLatestUpdatesHash() => r'93e1ba376d14006110e9a6c06d191ffd12b1fdfb';
|
||||
String _$getLatestUpdatesHash() => r'fd4ece1d796e079a469e5f80f456ee821ff0bc03';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import 'package:mangayomi/eval/lib.dart';
|
||||
import 'package:mangayomi/eval/model/m_pages.dart';
|
||||
import 'package:mangayomi/models/source.dart';
|
||||
import 'package:mangayomi/modules/more/settings/browse/providers/browse_state_provider.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
part 'get_popular.g.dart';
|
||||
|
|
@ -11,5 +12,8 @@ Future<MPages?> getPopular(
|
|||
required Source source,
|
||||
required int page,
|
||||
}) async {
|
||||
return getExtensionService(source).getPopular(page);
|
||||
return getExtensionService(
|
||||
source,
|
||||
ref.read(androidProxyServerStateProvider),
|
||||
).getPopular(page);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ part of 'get_popular.dart';
|
|||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$getPopularHash() => r'02291ff9c3eba594b2344b853c34b2cea7be491b';
|
||||
String _$getPopularHash() => r'5fd933ce7e2b9c2dd113b7642ed54c1a1196f638';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
|
|
|||
|
|
@ -1,11 +1,15 @@
|
|||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:mangayomi/eval/lib.dart';
|
||||
import 'package:mangayomi/models/source.dart';
|
||||
import 'package:mangayomi/modules/more/settings/browse/providers/browse_state_provider.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
|
||||
part 'get_source_baseurl.g.dart';
|
||||
|
||||
@riverpod
|
||||
String sourceBaseUrl(Ref ref, {required Source source}) {
|
||||
return getExtensionService(source).sourceBaseUrl;
|
||||
return getExtensionService(
|
||||
source,
|
||||
ref.read(androidProxyServerStateProvider),
|
||||
).sourceBaseUrl;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ part of 'get_source_baseurl.dart';
|
|||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$sourceBaseUrlHash() => r'2eaf2f441085cec9e2f035763ef2ec64aa00f838';
|
||||
String _$sourceBaseUrlHash() => r'ead3cca719e2530502d97613e3168e0031eecde7';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
|
|
|||
|
|
@ -2,6 +2,9 @@ import 'package:mangayomi/eval/lib.dart';
|
|||
import 'package:mangayomi/eval/model/source_preference.dart';
|
||||
import 'package:mangayomi/models/source.dart';
|
||||
|
||||
List<SourcePreference> getSourcePreference({required Source source}) {
|
||||
return getExtensionService(source).getSourcePreferences();
|
||||
List<SourcePreference> getSourcePreference({
|
||||
required Source source,
|
||||
String androidProxyServer = "",
|
||||
}) {
|
||||
return getExtensionService(source, androidProxyServer).getSourcePreferences();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import 'dart:io';
|
|||
import 'package:mangayomi/eval/lib.dart';
|
||||
import 'package:mangayomi/models/chapter.dart';
|
||||
import 'package:mangayomi/models/video.dart';
|
||||
import 'package:mangayomi/modules/more/settings/browse/providers/browse_state_provider.dart';
|
||||
import 'package:mangayomi/providers/storage_provider.dart';
|
||||
import 'package:mangayomi/services/torrent_server.dart';
|
||||
import 'package:mangayomi/utils/utils.dart';
|
||||
|
|
@ -10,6 +11,8 @@ import 'package:mangayomi/utils/extensions/string_extensions.dart';
|
|||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:path/path.dart' as p;
|
||||
|
||||
import '../models/source.dart';
|
||||
part 'get_video_list.g.dart';
|
||||
|
||||
@riverpod
|
||||
|
|
@ -60,8 +63,14 @@ Future<(List<Video>, bool, List<String>, Directory?)> getVideoList(
|
|||
episode.manga.value!.lang!,
|
||||
episode.manga.value!.source!,
|
||||
);
|
||||
final proxyServer = ref.read(androidProxyServerStateProvider);
|
||||
|
||||
if (source?.isTorrent ?? false || episode.manga.value!.source == "torrent") {
|
||||
final isMihonTorrent =
|
||||
source?.sourceCodeLanguage == SourceCodeLanguage.mihon &&
|
||||
source!.name!.contains("(Torrent");
|
||||
if ((source?.isTorrent ?? false) ||
|
||||
episode.manga.value!.source == "torrent" ||
|
||||
isMihonTorrent) {
|
||||
List<Video> list = [];
|
||||
|
||||
List<Video> torrentList = [];
|
||||
|
|
@ -74,7 +83,10 @@ Future<(List<Video>, bool, List<String>, Directory?)> getVideoList(
|
|||
}
|
||||
|
||||
try {
|
||||
list = await getExtensionService(source!).getVideoList(episode.url!);
|
||||
list = await getExtensionService(
|
||||
source!,
|
||||
proxyServer,
|
||||
).getVideoList(episode.url!);
|
||||
} catch (e) {
|
||||
list = [Video(episode.url!, episode.name!, episode.url!)];
|
||||
}
|
||||
|
|
@ -98,6 +110,7 @@ Future<(List<Video>, bool, List<String>, Directory?)> getVideoList(
|
|||
|
||||
List<Video> list = await getExtensionService(
|
||||
source!,
|
||||
proxyServer,
|
||||
).getVideoList(episode.url!);
|
||||
List<Video> videos = [];
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ part of 'get_video_list.dart';
|
|||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$getVideoListHash() => r'140ac1ca572d6220b7791c4350a0b32e275535a4';
|
||||
String _$getVideoListHash() => r'1fe7493f84a661cb7a3a2f1ce1e0b62e53801096';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
|
|
|||
|
|
@ -54,8 +54,20 @@ class MClient {
|
|||
rhttp.ClientSettings? settings,
|
||||
bool showCloudFlareError = true,
|
||||
}) {
|
||||
final clientSettings = customDns == null || customDns!.trim().isEmpty
|
||||
? settings
|
||||
: settings?.copyWith(
|
||||
dnsSettings: DnsSettings.dynamic(
|
||||
resolver: (host) async => [customDns!],
|
||||
),
|
||||
) ??
|
||||
ClientSettings(
|
||||
dnsSettings: DnsSettings.dynamic(
|
||||
resolver: (host) async => [customDns!],
|
||||
),
|
||||
);
|
||||
return InterceptedClient.build(
|
||||
client: httpClient(settings: settings, reqcopyWith: reqcopyWith),
|
||||
client: httpClient(settings: clientSettings, reqcopyWith: reqcopyWith),
|
||||
retryPolicy: ResolveCloudFlareChallenge(showCloudFlareError),
|
||||
interceptors: [
|
||||
MCookieManager(reqcopyWith),
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import 'package:mangayomi/eval/lib.dart';
|
||||
import 'package:mangayomi/eval/model/m_pages.dart';
|
||||
import 'package:mangayomi/models/source.dart';
|
||||
import 'package:mangayomi/modules/more/settings/browse/providers/browse_state_provider.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
part 'search.g.dart';
|
||||
|
|
@ -13,5 +14,8 @@ Future<MPages?> search(
|
|||
required int page,
|
||||
required List<dynamic> filterList,
|
||||
}) async {
|
||||
return getExtensionService(source).search(query, page, filterList);
|
||||
return getExtensionService(
|
||||
source,
|
||||
ref.read(androidProxyServerStateProvider),
|
||||
).search(query, page, filterList);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ part of 'search.dart';
|
|||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$searchHash() => r'8ef361b28d7a569b9f5babd69eb83efd9d9814d7';
|
||||
String _$searchHash() => r'b08d5a4b6e7d285830af7e5388b06fa61f175ede';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
|
|
|||
|
|
@ -1,12 +1,21 @@
|
|||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:mangayomi/eval/lib.dart';
|
||||
import 'package:mangayomi/eval/model/m_pages.dart';
|
||||
import 'package:mangayomi/models/source.dart';
|
||||
import 'package:mangayomi/modules/more/settings/browse/providers/browse_state_provider.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
part 'search_.g.dart';
|
||||
|
||||
Future<MPages?> search({
|
||||
@riverpod
|
||||
Future<MPages?> search(
|
||||
Ref ref, {
|
||||
required Source source,
|
||||
required String query,
|
||||
required int page,
|
||||
required List<dynamic> filterList,
|
||||
}) async {
|
||||
return getExtensionService(source).search(query, page, filterList);
|
||||
return getExtensionService(
|
||||
source,
|
||||
ref.read(androidProxyServerStateProvider),
|
||||
).search(query, page, filterList);
|
||||
}
|
||||
|
|
|
|||
208
lib/services/search_.g.dart
Normal file
208
lib/services/search_.g.dart
Normal file
|
|
@ -0,0 +1,208 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'search_.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$searchHash() => r'b08d5a4b6e7d285830af7e5388b06fa61f175ede';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
_SystemHash._();
|
||||
|
||||
static int combine(int hash, int value) {
|
||||
// ignore: parameter_assignments
|
||||
hash = 0x1fffffff & (hash + value);
|
||||
// ignore: parameter_assignments
|
||||
hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10));
|
||||
return hash ^ (hash >> 6);
|
||||
}
|
||||
|
||||
static int finish(int hash) {
|
||||
// ignore: parameter_assignments
|
||||
hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3));
|
||||
// ignore: parameter_assignments
|
||||
hash = hash ^ (hash >> 11);
|
||||
return 0x1fffffff & (hash + ((0x00003fff & hash) << 15));
|
||||
}
|
||||
}
|
||||
|
||||
/// See also [search].
|
||||
@ProviderFor(search)
|
||||
const searchProvider = SearchFamily();
|
||||
|
||||
/// See also [search].
|
||||
class SearchFamily extends Family<AsyncValue<MPages?>> {
|
||||
/// See also [search].
|
||||
const SearchFamily();
|
||||
|
||||
/// See also [search].
|
||||
SearchProvider call({
|
||||
required Source source,
|
||||
required String query,
|
||||
required int page,
|
||||
required List<dynamic> filterList,
|
||||
}) {
|
||||
return SearchProvider(
|
||||
source: source,
|
||||
query: query,
|
||||
page: page,
|
||||
filterList: filterList,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
SearchProvider getProviderOverride(
|
||||
covariant SearchProvider provider,
|
||||
) {
|
||||
return call(
|
||||
source: provider.source,
|
||||
query: provider.query,
|
||||
page: provider.page,
|
||||
filterList: provider.filterList,
|
||||
);
|
||||
}
|
||||
|
||||
static const Iterable<ProviderOrFamily>? _dependencies = null;
|
||||
|
||||
@override
|
||||
Iterable<ProviderOrFamily>? get dependencies => _dependencies;
|
||||
|
||||
static const Iterable<ProviderOrFamily>? _allTransitiveDependencies = null;
|
||||
|
||||
@override
|
||||
Iterable<ProviderOrFamily>? get allTransitiveDependencies =>
|
||||
_allTransitiveDependencies;
|
||||
|
||||
@override
|
||||
String? get name => r'searchProvider';
|
||||
}
|
||||
|
||||
/// See also [search].
|
||||
class SearchProvider extends AutoDisposeFutureProvider<MPages?> {
|
||||
/// See also [search].
|
||||
SearchProvider({
|
||||
required Source source,
|
||||
required String query,
|
||||
required int page,
|
||||
required List<dynamic> filterList,
|
||||
}) : this._internal(
|
||||
(ref) => search(
|
||||
ref as SearchRef,
|
||||
source: source,
|
||||
query: query,
|
||||
page: page,
|
||||
filterList: filterList,
|
||||
),
|
||||
from: searchProvider,
|
||||
name: r'searchProvider',
|
||||
debugGetCreateSourceHash:
|
||||
const bool.fromEnvironment('dart.vm.product')
|
||||
? null
|
||||
: _$searchHash,
|
||||
dependencies: SearchFamily._dependencies,
|
||||
allTransitiveDependencies: SearchFamily._allTransitiveDependencies,
|
||||
source: source,
|
||||
query: query,
|
||||
page: page,
|
||||
filterList: filterList,
|
||||
);
|
||||
|
||||
SearchProvider._internal(
|
||||
super._createNotifier, {
|
||||
required super.name,
|
||||
required super.dependencies,
|
||||
required super.allTransitiveDependencies,
|
||||
required super.debugGetCreateSourceHash,
|
||||
required super.from,
|
||||
required this.source,
|
||||
required this.query,
|
||||
required this.page,
|
||||
required this.filterList,
|
||||
}) : super.internal();
|
||||
|
||||
final Source source;
|
||||
final String query;
|
||||
final int page;
|
||||
final List<dynamic> filterList;
|
||||
|
||||
@override
|
||||
Override overrideWith(
|
||||
FutureOr<MPages?> Function(SearchRef provider) create,
|
||||
) {
|
||||
return ProviderOverride(
|
||||
origin: this,
|
||||
override: SearchProvider._internal(
|
||||
(ref) => create(ref as SearchRef),
|
||||
from: from,
|
||||
name: null,
|
||||
dependencies: null,
|
||||
allTransitiveDependencies: null,
|
||||
debugGetCreateSourceHash: null,
|
||||
source: source,
|
||||
query: query,
|
||||
page: page,
|
||||
filterList: filterList,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
AutoDisposeFutureProviderElement<MPages?> createElement() {
|
||||
return _SearchProviderElement(this);
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return other is SearchProvider &&
|
||||
other.source == source &&
|
||||
other.query == query &&
|
||||
other.page == page &&
|
||||
other.filterList == filterList;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
var hash = _SystemHash.combine(0, runtimeType.hashCode);
|
||||
hash = _SystemHash.combine(hash, source.hashCode);
|
||||
hash = _SystemHash.combine(hash, query.hashCode);
|
||||
hash = _SystemHash.combine(hash, page.hashCode);
|
||||
hash = _SystemHash.combine(hash, filterList.hashCode);
|
||||
|
||||
return _SystemHash.finish(hash);
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated('Will be removed in 3.0. Use Ref instead')
|
||||
// ignore: unused_element
|
||||
mixin SearchRef on AutoDisposeFutureProviderRef<MPages?> {
|
||||
/// The parameter `source` of this provider.
|
||||
Source get source;
|
||||
|
||||
/// The parameter `query` of this provider.
|
||||
String get query;
|
||||
|
||||
/// The parameter `page` of this provider.
|
||||
int get page;
|
||||
|
||||
/// The parameter `filterList` of this provider.
|
||||
List<dynamic> get filterList;
|
||||
}
|
||||
|
||||
class _SearchProviderElement extends AutoDisposeFutureProviderElement<MPages?>
|
||||
with SearchRef {
|
||||
_SearchProviderElement(super.provider);
|
||||
|
||||
@override
|
||||
Source get source => (origin as SearchProvider).source;
|
||||
@override
|
||||
String get query => (origin as SearchProvider).query;
|
||||
@override
|
||||
int get page => (origin as SearchProvider).page;
|
||||
@override
|
||||
List<dynamic> get filterList => (origin as SearchProvider).filterList;
|
||||
}
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package
|
||||
|
|
@ -1,10 +1,14 @@
|
|||
import 'package:mangayomi/eval/lib.dart';
|
||||
import 'package:mangayomi/models/source.dart';
|
||||
import 'package:mangayomi/modules/more/settings/browse/providers/browse_state_provider.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
part 'supports_latest.g.dart';
|
||||
|
||||
@riverpod
|
||||
bool supportsLatest(Ref ref, {required Source source}) {
|
||||
return getExtensionService(source).supportsLatest;
|
||||
return getExtensionService(
|
||||
source,
|
||||
ref.read(androidProxyServerStateProvider),
|
||||
).supportsLatest;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ part of 'supports_latest.dart';
|
|||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$supportsLatestHash() => r'71f77f99b86f2f597ec728add2483a5623f4984a';
|
||||
String _$supportsLatestHash() => r'e2d9b73adde86f78f1ab1c97d91ea2d3a59dc78d';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ part of 'sync_server.dart';
|
|||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$syncServerHash() => r'141ba3be28182e05480e06fbf3f1de68f868cb8e';
|
||||
String _$syncServerHash() => r'08225f80e9c249dc62e8e918acecbd593f54541f';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ part of 'anilist.dart';
|
|||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$anilistHash() => r'c786a526fdacc875e4a7e00886b2bda546eafeae';
|
||||
String _$anilistHash() => r'fafb964252b3a5741e981cb8c2f0f2090b3b86ae';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ part of 'kitsu.dart';
|
|||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$kitsuHash() => r'e24e9b57cfea974110d1f7c704c306c3b58e3529';
|
||||
String _$kitsuHash() => r'd46b955c92bc4d7382d32e17827da2e2b3a8434f';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ part of 'myanimelist.dart';
|
|||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$myAnimeListHash() => r'4391ad9446d14b1fb1ffdfbc5323ef04db5140f7';
|
||||
String _$myAnimeListHash() => r'739c836ddbfc7c2c2b7593304f481e8d35074391';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ Map<String, String> headers(
|
|||
Ref ref, {
|
||||
required String source,
|
||||
required String lang,
|
||||
String androidProxyServer = "",
|
||||
}) {
|
||||
final mSource = getSource(lang, source);
|
||||
|
||||
|
|
@ -26,7 +27,9 @@ Map<String, String> headers(
|
|||
headers.addAll((jsonDecode(fromSource) as Map).toMapStringString!);
|
||||
}
|
||||
|
||||
headers.addAll(getExtensionService(mSource).getHeaders());
|
||||
headers.addAll(
|
||||
getExtensionService(mSource, androidProxyServer).getHeaders(),
|
||||
);
|
||||
headers.addAll(MClient.getCookiesPref(mSource.baseUrl!));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ part of 'headers.dart';
|
|||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$headersHash() => r'47499544c2d972da6a0c20f41fe3fc46d1d7c1a0';
|
||||
String _$headersHash() => r'a33ccbf1971e6b5da84f25a852c675a4d8821ea2';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
|
@ -42,10 +42,12 @@ class HeadersFamily extends Family<Map<String, String>> {
|
|||
HeadersProvider call({
|
||||
required String source,
|
||||
required String lang,
|
||||
String androidProxyServer = "",
|
||||
}) {
|
||||
return HeadersProvider(
|
||||
source: source,
|
||||
lang: lang,
|
||||
androidProxyServer: androidProxyServer,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -56,6 +58,7 @@ class HeadersFamily extends Family<Map<String, String>> {
|
|||
return call(
|
||||
source: provider.source,
|
||||
lang: provider.lang,
|
||||
androidProxyServer: provider.androidProxyServer,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -80,11 +83,13 @@ class HeadersProvider extends AutoDisposeProvider<Map<String, String>> {
|
|||
HeadersProvider({
|
||||
required String source,
|
||||
required String lang,
|
||||
String androidProxyServer = "",
|
||||
}) : this._internal(
|
||||
(ref) => headers(
|
||||
ref as HeadersRef,
|
||||
source: source,
|
||||
lang: lang,
|
||||
androidProxyServer: androidProxyServer,
|
||||
),
|
||||
from: headersProvider,
|
||||
name: r'headersProvider',
|
||||
|
|
@ -96,6 +101,7 @@ class HeadersProvider extends AutoDisposeProvider<Map<String, String>> {
|
|||
allTransitiveDependencies: HeadersFamily._allTransitiveDependencies,
|
||||
source: source,
|
||||
lang: lang,
|
||||
androidProxyServer: androidProxyServer,
|
||||
);
|
||||
|
||||
HeadersProvider._internal(
|
||||
|
|
@ -107,10 +113,12 @@ class HeadersProvider extends AutoDisposeProvider<Map<String, String>> {
|
|||
required super.from,
|
||||
required this.source,
|
||||
required this.lang,
|
||||
required this.androidProxyServer,
|
||||
}) : super.internal();
|
||||
|
||||
final String source;
|
||||
final String lang;
|
||||
final String androidProxyServer;
|
||||
|
||||
@override
|
||||
Override overrideWith(
|
||||
|
|
@ -127,6 +135,7 @@ class HeadersProvider extends AutoDisposeProvider<Map<String, String>> {
|
|||
debugGetCreateSourceHash: null,
|
||||
source: source,
|
||||
lang: lang,
|
||||
androidProxyServer: androidProxyServer,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
@ -140,7 +149,8 @@ class HeadersProvider extends AutoDisposeProvider<Map<String, String>> {
|
|||
bool operator ==(Object other) {
|
||||
return other is HeadersProvider &&
|
||||
other.source == source &&
|
||||
other.lang == lang;
|
||||
other.lang == lang &&
|
||||
other.androidProxyServer == androidProxyServer;
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
@ -148,6 +158,7 @@ class HeadersProvider extends AutoDisposeProvider<Map<String, String>> {
|
|||
var hash = _SystemHash.combine(0, runtimeType.hashCode);
|
||||
hash = _SystemHash.combine(hash, source.hashCode);
|
||||
hash = _SystemHash.combine(hash, lang.hashCode);
|
||||
hash = _SystemHash.combine(hash, androidProxyServer.hashCode);
|
||||
|
||||
return _SystemHash.finish(hash);
|
||||
}
|
||||
|
|
@ -161,6 +172,9 @@ mixin HeadersRef on AutoDisposeProviderRef<Map<String, String>> {
|
|||
|
||||
/// The parameter `lang` of this provider.
|
||||
String get lang;
|
||||
|
||||
/// The parameter `androidProxyServer` of this provider.
|
||||
String get androidProxyServer;
|
||||
}
|
||||
|
||||
class _HeadersProviderElement
|
||||
|
|
@ -171,6 +185,9 @@ class _HeadersProviderElement
|
|||
String get source => (origin as HeadersProvider).source;
|
||||
@override
|
||||
String get lang => (origin as HeadersProvider).lang;
|
||||
@override
|
||||
String get androidProxyServer =>
|
||||
(origin as HeadersProvider).androidProxyServer;
|
||||
}
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package
|
||||
|
|
|
|||
Loading…
Reference in a new issue