feature: pinned , last used source + fix
This commit is contained in:
parent
bc47bf00f0
commit
dfd82b32f6
19 changed files with 586 additions and 214 deletions
|
|
@ -94,7 +94,7 @@ class Settings {
|
||||||
this.dateFormat = "M/d/y",
|
this.dateFormat = "M/d/y",
|
||||||
this.relativeTimesTamps = 2,
|
this.relativeTimesTamps = 2,
|
||||||
this.flexSchemeColorIndex = 2,
|
this.flexSchemeColorIndex = 2,
|
||||||
this.themeIsDark = true,
|
this.themeIsDark = false,
|
||||||
this.incognitoMode = false,
|
this.incognitoMode = false,
|
||||||
this.chapterPageUrlsList,
|
this.chapterPageUrlsList,
|
||||||
this.showPagesNumber = true,
|
this.showPagesNumber = true,
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,8 @@ class Source {
|
||||||
|
|
||||||
bool? isAdded;
|
bool? isAdded;
|
||||||
|
|
||||||
|
bool? isPinned;
|
||||||
|
|
||||||
bool? isNsfw;
|
bool? isNsfw;
|
||||||
|
|
||||||
@enumerated
|
@enumerated
|
||||||
|
|
@ -27,6 +29,8 @@ class Source {
|
||||||
|
|
||||||
bool? isCloudflare;
|
bool? isCloudflare;
|
||||||
|
|
||||||
|
bool? lastUsed;
|
||||||
|
|
||||||
String? dateFormat;
|
String? dateFormat;
|
||||||
|
|
||||||
String? dateFormatLocale;
|
String? dateFormatLocale;
|
||||||
|
|
@ -47,6 +51,8 @@ class Source {
|
||||||
this.isNsfw = false,
|
this.isNsfw = false,
|
||||||
this.isFullData = false,
|
this.isFullData = false,
|
||||||
this.isCloudflare = false,
|
this.isCloudflare = false,
|
||||||
|
this.isPinned = false,
|
||||||
|
this.lastUsed = false,
|
||||||
this.apiUrl = "",
|
this.apiUrl = "",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -62,23 +62,33 @@ const SourceSchema = CollectionSchema(
|
||||||
name: r'isNsfw',
|
name: r'isNsfw',
|
||||||
type: IsarType.bool,
|
type: IsarType.bool,
|
||||||
),
|
),
|
||||||
r'lang': PropertySchema(
|
r'isPinned': PropertySchema(
|
||||||
id: 9,
|
id: 9,
|
||||||
|
name: r'isPinned',
|
||||||
|
type: IsarType.bool,
|
||||||
|
),
|
||||||
|
r'lang': PropertySchema(
|
||||||
|
id: 10,
|
||||||
name: r'lang',
|
name: r'lang',
|
||||||
type: IsarType.string,
|
type: IsarType.string,
|
||||||
),
|
),
|
||||||
|
r'lastUsed': PropertySchema(
|
||||||
|
id: 11,
|
||||||
|
name: r'lastUsed',
|
||||||
|
type: IsarType.bool,
|
||||||
|
),
|
||||||
r'logoUrl': PropertySchema(
|
r'logoUrl': PropertySchema(
|
||||||
id: 10,
|
id: 12,
|
||||||
name: r'logoUrl',
|
name: r'logoUrl',
|
||||||
type: IsarType.string,
|
type: IsarType.string,
|
||||||
),
|
),
|
||||||
r'sourceName': PropertySchema(
|
r'sourceName': PropertySchema(
|
||||||
id: 11,
|
id: 13,
|
||||||
name: r'sourceName',
|
name: r'sourceName',
|
||||||
type: IsarType.string,
|
type: IsarType.string,
|
||||||
),
|
),
|
||||||
r'typeSource': PropertySchema(
|
r'typeSource': PropertySchema(
|
||||||
id: 12,
|
id: 14,
|
||||||
name: r'typeSource',
|
name: r'typeSource',
|
||||||
type: IsarType.byte,
|
type: IsarType.byte,
|
||||||
enumMap: _SourcetypeSourceEnumValueMap,
|
enumMap: _SourcetypeSourceEnumValueMap,
|
||||||
|
|
@ -164,10 +174,12 @@ void _sourceSerialize(
|
||||||
writer.writeBool(offsets[6], object.isCloudflare);
|
writer.writeBool(offsets[6], object.isCloudflare);
|
||||||
writer.writeBool(offsets[7], object.isFullData);
|
writer.writeBool(offsets[7], object.isFullData);
|
||||||
writer.writeBool(offsets[8], object.isNsfw);
|
writer.writeBool(offsets[8], object.isNsfw);
|
||||||
writer.writeString(offsets[9], object.lang);
|
writer.writeBool(offsets[9], object.isPinned);
|
||||||
writer.writeString(offsets[10], object.logoUrl);
|
writer.writeString(offsets[10], object.lang);
|
||||||
writer.writeString(offsets[11], object.sourceName);
|
writer.writeBool(offsets[11], object.lastUsed);
|
||||||
writer.writeByte(offsets[12], object.typeSource.index);
|
writer.writeString(offsets[12], object.logoUrl);
|
||||||
|
writer.writeString(offsets[13], object.sourceName);
|
||||||
|
writer.writeByte(offsets[14], object.typeSource.index);
|
||||||
}
|
}
|
||||||
|
|
||||||
Source _sourceDeserialize(
|
Source _sourceDeserialize(
|
||||||
|
|
@ -187,11 +199,13 @@ Source _sourceDeserialize(
|
||||||
isCloudflare: reader.readBoolOrNull(offsets[6]),
|
isCloudflare: reader.readBoolOrNull(offsets[6]),
|
||||||
isFullData: reader.readBoolOrNull(offsets[7]),
|
isFullData: reader.readBoolOrNull(offsets[7]),
|
||||||
isNsfw: reader.readBoolOrNull(offsets[8]),
|
isNsfw: reader.readBoolOrNull(offsets[8]),
|
||||||
lang: reader.readStringOrNull(offsets[9]),
|
isPinned: reader.readBoolOrNull(offsets[9]),
|
||||||
logoUrl: reader.readStringOrNull(offsets[10]),
|
lang: reader.readStringOrNull(offsets[10]),
|
||||||
sourceName: reader.readStringOrNull(offsets[11]),
|
lastUsed: reader.readBoolOrNull(offsets[11]),
|
||||||
|
logoUrl: reader.readStringOrNull(offsets[12]),
|
||||||
|
sourceName: reader.readStringOrNull(offsets[13]),
|
||||||
typeSource:
|
typeSource:
|
||||||
_SourcetypeSourceValueEnumMap[reader.readByteOrNull(offsets[12])] ??
|
_SourcetypeSourceValueEnumMap[reader.readByteOrNull(offsets[14])] ??
|
||||||
TypeSource.single,
|
TypeSource.single,
|
||||||
);
|
);
|
||||||
return object;
|
return object;
|
||||||
|
|
@ -223,12 +237,16 @@ P _sourceDeserializeProp<P>(
|
||||||
case 8:
|
case 8:
|
||||||
return (reader.readBoolOrNull(offset)) as P;
|
return (reader.readBoolOrNull(offset)) as P;
|
||||||
case 9:
|
case 9:
|
||||||
return (reader.readStringOrNull(offset)) as P;
|
return (reader.readBoolOrNull(offset)) as P;
|
||||||
case 10:
|
case 10:
|
||||||
return (reader.readStringOrNull(offset)) as P;
|
return (reader.readStringOrNull(offset)) as P;
|
||||||
case 11:
|
case 11:
|
||||||
return (reader.readStringOrNull(offset)) as P;
|
return (reader.readBoolOrNull(offset)) as P;
|
||||||
case 12:
|
case 12:
|
||||||
|
return (reader.readStringOrNull(offset)) as P;
|
||||||
|
case 13:
|
||||||
|
return (reader.readStringOrNull(offset)) as P;
|
||||||
|
case 14:
|
||||||
return (_SourcetypeSourceValueEnumMap[reader.readByteOrNull(offset)] ??
|
return (_SourcetypeSourceValueEnumMap[reader.readByteOrNull(offset)] ??
|
||||||
TypeSource.single) as P;
|
TypeSource.single) as P;
|
||||||
default:
|
default:
|
||||||
|
|
@ -1128,6 +1146,32 @@ extension SourceQueryFilter on QueryBuilder<Source, Source, QFilterCondition> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QueryBuilder<Source, Source, QAfterFilterCondition> isPinnedIsNull() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(const FilterCondition.isNull(
|
||||||
|
property: r'isPinned',
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<Source, Source, QAfterFilterCondition> isPinnedIsNotNull() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(const FilterCondition.isNotNull(
|
||||||
|
property: r'isPinned',
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<Source, Source, QAfterFilterCondition> isPinnedEqualTo(
|
||||||
|
bool? value) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.equalTo(
|
||||||
|
property: r'isPinned',
|
||||||
|
value: value,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
QueryBuilder<Source, Source, QAfterFilterCondition> langIsNull() {
|
QueryBuilder<Source, Source, QAfterFilterCondition> langIsNull() {
|
||||||
return QueryBuilder.apply(this, (query) {
|
return QueryBuilder.apply(this, (query) {
|
||||||
return query.addFilterCondition(const FilterCondition.isNull(
|
return query.addFilterCondition(const FilterCondition.isNull(
|
||||||
|
|
@ -1273,6 +1317,32 @@ extension SourceQueryFilter on QueryBuilder<Source, Source, QFilterCondition> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QueryBuilder<Source, Source, QAfterFilterCondition> lastUsedIsNull() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(const FilterCondition.isNull(
|
||||||
|
property: r'lastUsed',
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<Source, Source, QAfterFilterCondition> lastUsedIsNotNull() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(const FilterCondition.isNotNull(
|
||||||
|
property: r'lastUsed',
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<Source, Source, QAfterFilterCondition> lastUsedEqualTo(
|
||||||
|
bool? value) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.equalTo(
|
||||||
|
property: r'lastUsed',
|
||||||
|
value: value,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
QueryBuilder<Source, Source, QAfterFilterCondition> logoUrlIsNull() {
|
QueryBuilder<Source, Source, QAfterFilterCondition> logoUrlIsNull() {
|
||||||
return QueryBuilder.apply(this, (query) {
|
return QueryBuilder.apply(this, (query) {
|
||||||
return query.addFilterCondition(const FilterCondition.isNull(
|
return query.addFilterCondition(const FilterCondition.isNull(
|
||||||
|
|
@ -1732,6 +1802,18 @@ extension SourceQuerySortBy on QueryBuilder<Source, Source, QSortBy> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QueryBuilder<Source, Source, QAfterSortBy> sortByIsPinned() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addSortBy(r'isPinned', Sort.asc);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<Source, Source, QAfterSortBy> sortByIsPinnedDesc() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addSortBy(r'isPinned', Sort.desc);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
QueryBuilder<Source, Source, QAfterSortBy> sortByLang() {
|
QueryBuilder<Source, Source, QAfterSortBy> sortByLang() {
|
||||||
return QueryBuilder.apply(this, (query) {
|
return QueryBuilder.apply(this, (query) {
|
||||||
return query.addSortBy(r'lang', Sort.asc);
|
return query.addSortBy(r'lang', Sort.asc);
|
||||||
|
|
@ -1744,6 +1826,18 @@ extension SourceQuerySortBy on QueryBuilder<Source, Source, QSortBy> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QueryBuilder<Source, Source, QAfterSortBy> sortByLastUsed() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addSortBy(r'lastUsed', Sort.asc);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<Source, Source, QAfterSortBy> sortByLastUsedDesc() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addSortBy(r'lastUsed', Sort.desc);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
QueryBuilder<Source, Source, QAfterSortBy> sortByLogoUrl() {
|
QueryBuilder<Source, Source, QAfterSortBy> sortByLogoUrl() {
|
||||||
return QueryBuilder.apply(this, (query) {
|
return QueryBuilder.apply(this, (query) {
|
||||||
return query.addSortBy(r'logoUrl', Sort.asc);
|
return query.addSortBy(r'logoUrl', Sort.asc);
|
||||||
|
|
@ -1902,6 +1996,18 @@ extension SourceQuerySortThenBy on QueryBuilder<Source, Source, QSortThenBy> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QueryBuilder<Source, Source, QAfterSortBy> thenByIsPinned() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addSortBy(r'isPinned', Sort.asc);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<Source, Source, QAfterSortBy> thenByIsPinnedDesc() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addSortBy(r'isPinned', Sort.desc);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
QueryBuilder<Source, Source, QAfterSortBy> thenByLang() {
|
QueryBuilder<Source, Source, QAfterSortBy> thenByLang() {
|
||||||
return QueryBuilder.apply(this, (query) {
|
return QueryBuilder.apply(this, (query) {
|
||||||
return query.addSortBy(r'lang', Sort.asc);
|
return query.addSortBy(r'lang', Sort.asc);
|
||||||
|
|
@ -1914,6 +2020,18 @@ extension SourceQuerySortThenBy on QueryBuilder<Source, Source, QSortThenBy> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QueryBuilder<Source, Source, QAfterSortBy> thenByLastUsed() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addSortBy(r'lastUsed', Sort.asc);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<Source, Source, QAfterSortBy> thenByLastUsedDesc() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addSortBy(r'lastUsed', Sort.desc);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
QueryBuilder<Source, Source, QAfterSortBy> thenByLogoUrl() {
|
QueryBuilder<Source, Source, QAfterSortBy> thenByLogoUrl() {
|
||||||
return QueryBuilder.apply(this, (query) {
|
return QueryBuilder.apply(this, (query) {
|
||||||
return query.addSortBy(r'logoUrl', Sort.asc);
|
return query.addSortBy(r'logoUrl', Sort.asc);
|
||||||
|
|
@ -2011,6 +2129,12 @@ extension SourceQueryWhereDistinct on QueryBuilder<Source, Source, QDistinct> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QueryBuilder<Source, Source, QDistinct> distinctByIsPinned() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addDistinctBy(r'isPinned');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
QueryBuilder<Source, Source, QDistinct> distinctByLang(
|
QueryBuilder<Source, Source, QDistinct> distinctByLang(
|
||||||
{bool caseSensitive = true}) {
|
{bool caseSensitive = true}) {
|
||||||
return QueryBuilder.apply(this, (query) {
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
|
@ -2018,6 +2142,12 @@ extension SourceQueryWhereDistinct on QueryBuilder<Source, Source, QDistinct> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QueryBuilder<Source, Source, QDistinct> distinctByLastUsed() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addDistinctBy(r'lastUsed');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
QueryBuilder<Source, Source, QDistinct> distinctByLogoUrl(
|
QueryBuilder<Source, Source, QDistinct> distinctByLogoUrl(
|
||||||
{bool caseSensitive = true}) {
|
{bool caseSensitive = true}) {
|
||||||
return QueryBuilder.apply(this, (query) {
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
|
@ -2100,12 +2230,24 @@ extension SourceQueryProperty on QueryBuilder<Source, Source, QQueryProperty> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QueryBuilder<Source, bool?, QQueryOperations> isPinnedProperty() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addPropertyName(r'isPinned');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
QueryBuilder<Source, String?, QQueryOperations> langProperty() {
|
QueryBuilder<Source, String?, QQueryOperations> langProperty() {
|
||||||
return QueryBuilder.apply(this, (query) {
|
return QueryBuilder.apply(this, (query) {
|
||||||
return query.addPropertyName(r'lang');
|
return query.addPropertyName(r'lang');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QueryBuilder<Source, bool?, QQueryOperations> lastUsedProperty() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addPropertyName(r'lastUsed');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
QueryBuilder<Source, String?, QQueryOperations> logoUrlProperty() {
|
QueryBuilder<Source, String?, QQueryOperations> logoUrlProperty() {
|
||||||
return QueryBuilder.apply(this, (query) {
|
return QueryBuilder.apply(this, (query) {
|
||||||
return query.addPropertyName(r'logoUrl');
|
return query.addPropertyName(r'logoUrl');
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
|
import 'package:mangayomi/modules/browse/extension/providers/refresh_source_list_data.dart';
|
||||||
import 'package:mangayomi/providers/storage_provider.dart';
|
import 'package:mangayomi/providers/storage_provider.dart';
|
||||||
import 'package:mangayomi/models/source.dart';
|
import 'package:mangayomi/models/source.dart';
|
||||||
import 'package:mangayomi/modules/browse/extension/extension_screen.dart';
|
import 'package:mangayomi/modules/browse/extension/extension_screen.dart';
|
||||||
import 'package:mangayomi/modules/browse/extension/refresh_source_list_data.dart';
|
|
||||||
import 'package:mangayomi/modules/browse/migrate_screen.dart';
|
import 'package:mangayomi/modules/browse/migrate_screen.dart';
|
||||||
import 'package:mangayomi/modules/browse/sources/sources_screen.dart';
|
import 'package:mangayomi/modules/browse/sources/sources_screen.dart';
|
||||||
import 'package:mangayomi/modules/library/search_text_form_field.dart';
|
import 'package:mangayomi/modules/library/search_text_form_field.dart';
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ class ExtensionScreen extends ConsumerWidget {
|
||||||
Text(
|
Text(
|
||||||
groupByValue,
|
groupByValue,
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
fontWeight: FontWeight.w300, fontSize: 12),
|
fontWeight: FontWeight.bold, fontSize: 13),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ refreshSourceListData(RefreshSourceListDataRef ref) {
|
||||||
..typeSource = source.typeSource
|
..typeSource = source.typeSource
|
||||||
..isFullData = source.isFullData
|
..isFullData = source.isFullData
|
||||||
..lang = source.lang
|
..lang = source.lang
|
||||||
|
..isNsfw = source.isNsfw
|
||||||
..sourceName = source.sourceName);
|
..sourceName = source.sourceName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -7,7 +7,7 @@ part of 'refresh_source_list_data.dart';
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
String _$refreshSourceListDataHash() =>
|
String _$refreshSourceListDataHash() =>
|
||||||
r'f77838cebad50f030d2038d07584199b4509f407';
|
r'c6ab103b0519d79afc8530ab7027a988203de5d3';
|
||||||
|
|
||||||
/// See also [refreshSourceListData].
|
/// See also [refreshSourceListData].
|
||||||
@ProviderFor(refreshSourceListData)
|
@ProviderFor(refreshSourceListData)
|
||||||
|
|
@ -3,12 +3,14 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:isar/isar.dart';
|
import 'package:isar/isar.dart';
|
||||||
import 'package:mangayomi/main.dart';
|
import 'package:mangayomi/main.dart';
|
||||||
|
import 'package:mangayomi/models/manga.dart';
|
||||||
import 'package:mangayomi/services/get_manga_detail.dart';
|
import 'package:mangayomi/services/get_manga_detail.dart';
|
||||||
import 'package:mangayomi/services/search_manga.dart';
|
import 'package:mangayomi/services/search_manga.dart';
|
||||||
import 'package:mangayomi/models/source.dart';
|
import 'package:mangayomi/models/source.dart';
|
||||||
import 'package:mangayomi/sources/service.dart';
|
import 'package:mangayomi/sources/service.dart';
|
||||||
import 'package:mangayomi/sources/source_list.dart';
|
import 'package:mangayomi/sources/source_list.dart';
|
||||||
import 'package:mangayomi/utils/cached_network.dart';
|
import 'package:mangayomi/utils/cached_network.dart';
|
||||||
|
import 'package:mangayomi/utils/colors.dart';
|
||||||
import 'package:mangayomi/utils/headers.dart';
|
import 'package:mangayomi/utils/headers.dart';
|
||||||
import 'package:mangayomi/utils/lang.dart';
|
import 'package:mangayomi/utils/lang.dart';
|
||||||
import 'package:mangayomi/modules/library/search_text_form_field.dart';
|
import 'package:mangayomi/modules/library/search_text_form_field.dart';
|
||||||
|
|
@ -31,7 +33,7 @@ class _GlobalSearchScreenState extends ConsumerState<GlobalSearchScreen> {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final sourceList = ref.watch(onlyIncludePinnedSourceStateProvider)
|
final sourceList = ref.watch(onlyIncludePinnedSourceStateProvider)
|
||||||
? isar.sources.filter().isAddedEqualTo(true).findAllSync()
|
? isar.sources.filter().isPinnedEqualTo(true).findAllSync()
|
||||||
: sourcesList;
|
: sourcesList;
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
|
|
@ -62,7 +64,7 @@ class _GlobalSearchScreenState extends ConsumerState<GlobalSearchScreen> {
|
||||||
children: [
|
children: [
|
||||||
for (var i = 0; i < sourceList.length; i++)
|
for (var i = 0; i < sourceList.length; i++)
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height: 230,
|
height: 260,
|
||||||
child: SourceSearchScreen(
|
child: SourceSearchScreen(
|
||||||
query: query,
|
query: query,
|
||||||
source: sourceList[i],
|
source: sourceList[i],
|
||||||
|
|
@ -91,7 +93,7 @@ class SourceSearchScreen extends ConsumerWidget {
|
||||||
.watch(searchMangaProvider(source: source.sourceName!, query: query));
|
.watch(searchMangaProvider(source: source.sourceName!, query: query));
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
body: SizedBox(
|
body: SizedBox(
|
||||||
height: 240,
|
height: 260,
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
ListTile(
|
ListTile(
|
||||||
|
|
@ -175,43 +177,93 @@ class _MangaGlobalImageCardState extends ConsumerState<MangaGlobalImageCard>
|
||||||
pushToMangaReaderDetail(
|
pushToMangaReaderDetail(
|
||||||
context: context, getManga: data, lang: widget.lang);
|
context: context, getManga: data, lang: widget.lang);
|
||||||
},
|
},
|
||||||
child: SizedBox(
|
child: StreamBuilder(
|
||||||
width: 90,
|
stream: isar.mangas
|
||||||
child: Column(children: [
|
.filter()
|
||||||
cachedNetworkImage(
|
.langEqualTo(widget.lang)
|
||||||
headers: ref.watch(headersProvider(source: data.source!)),
|
.nameEqualTo(data.name)
|
||||||
imageUrl: data.imageUrl!,
|
.sourceEqualTo(data.source)
|
||||||
width: 80,
|
.favoriteEqualTo(true)
|
||||||
height: 120,
|
.watch(fireImmediately: true),
|
||||||
fit: BoxFit.fill),
|
builder: (context, snapshot) {
|
||||||
BottomTextWidget(
|
return Padding(
|
||||||
fontSize: 12.0,
|
padding: const EdgeInsets.only(left: 10),
|
||||||
text: widget.manga.name!,
|
child: Stack(
|
||||||
isLoading: true,
|
children: [
|
||||||
isComfortableGrid: true,
|
SizedBox(
|
||||||
)
|
width: 100,
|
||||||
]),
|
child: Column(children: [
|
||||||
),
|
ClipRRect(
|
||||||
|
borderRadius: BorderRadius.circular(2),
|
||||||
|
child: cachedNetworkImage(
|
||||||
|
headers: ref.watch(
|
||||||
|
headersProvider(source: data.source!)),
|
||||||
|
imageUrl: data.imageUrl!,
|
||||||
|
width: 100,
|
||||||
|
height: 140,
|
||||||
|
fit: BoxFit.fill),
|
||||||
|
),
|
||||||
|
BottomTextWidget(
|
||||||
|
fontSize: 12.0,
|
||||||
|
text: widget.manga.name!,
|
||||||
|
isLoading: true,
|
||||||
|
isComfortableGrid: true,
|
||||||
|
)
|
||||||
|
]),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
width: 100,
|
||||||
|
height: 140,
|
||||||
|
color: snapshot.hasData && snapshot.data!.isNotEmpty
|
||||||
|
? Colors.black.withOpacity(0.7)
|
||||||
|
: null,
|
||||||
|
),
|
||||||
|
if (snapshot.hasData && snapshot.data!.isNotEmpty)
|
||||||
|
Positioned(
|
||||||
|
top: 0,
|
||||||
|
left: 0,
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(4),
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: primaryColor(context),
|
||||||
|
borderRadius: BorderRadius.circular(5)),
|
||||||
|
child: const Padding(
|
||||||
|
padding: EdgeInsets.all(2),
|
||||||
|
child: Text(
|
||||||
|
"In library",
|
||||||
|
style: TextStyle(fontSize: 10),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
loading: () => SizedBox(
|
loading: () => Padding(
|
||||||
width: 60,
|
padding: const EdgeInsets.only(left: 10),
|
||||||
child: Column(children: [
|
child: SizedBox(
|
||||||
ClipRRect(
|
width: 100,
|
||||||
borderRadius: BorderRadius.circular(5),
|
child: Column(children: [
|
||||||
child: Container(
|
ClipRRect(
|
||||||
color: Theme.of(context).cardColor,
|
borderRadius: BorderRadius.circular(5),
|
||||||
width: 80,
|
child: Container(
|
||||||
height: 120,
|
color: Theme.of(context).cardColor,
|
||||||
|
width: 100,
|
||||||
|
height: 140,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
BottomTextWidget(
|
||||||
BottomTextWidget(
|
fontSize: 12.0,
|
||||||
fontSize: 12.0,
|
text: widget.manga.name!,
|
||||||
text: widget.manga.name!,
|
isLoading: true,
|
||||||
isLoading: true,
|
isComfortableGrid: true,
|
||||||
isComfortableGrid: true,
|
)
|
||||||
)
|
]),
|
||||||
]),
|
),
|
||||||
),
|
),
|
||||||
error: (error, stackTrace) => Center(child: Text(error.toString())),
|
error: (error, stackTrace) => Center(child: Text(error.toString())),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,10 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
|
||||||
import 'package:grouped_list/grouped_list.dart';
|
import 'package:grouped_list/grouped_list.dart';
|
||||||
import 'package:isar/isar.dart';
|
import 'package:isar/isar.dart';
|
||||||
import 'package:mangayomi/main.dart';
|
import 'package:mangayomi/main.dart';
|
||||||
import 'package:mangayomi/models/manga_type.dart';
|
|
||||||
import 'package:mangayomi/models/source.dart';
|
import 'package:mangayomi/models/source.dart';
|
||||||
|
import 'package:mangayomi/modules/browse/sources/widgets/source_list_tile.dart';
|
||||||
import 'package:mangayomi/utils/lang.dart';
|
import 'package:mangayomi/utils/lang.dart';
|
||||||
import 'package:mangayomi/modules/more/settings/browse/providers/browse_state_provider.dart';
|
import 'package:mangayomi/modules/more/settings/browse/providers/browse_state_provider.dart';
|
||||||
|
|
||||||
|
|
@ -15,124 +14,156 @@ class SourcesScreen extends ConsumerWidget {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.only(top: 10),
|
padding: const EdgeInsets.only(top: 10),
|
||||||
child: StreamBuilder(
|
child: SingleChildScrollView(
|
||||||
stream: isar.sources
|
child: Column(
|
||||||
.filter()
|
children: [
|
||||||
.idIsNotNull()
|
StreamBuilder(
|
||||||
.isAddedEqualTo(true)
|
stream: isar.sources
|
||||||
.and()
|
.filter()
|
||||||
.isActiveEqualTo(true)
|
.idIsNotNull()
|
||||||
.watch(fireImmediately: true),
|
.isAddedEqualTo(true)
|
||||||
builder: (context, snapshot) {
|
.and()
|
||||||
if (!snapshot.hasData) {
|
.isActiveEqualTo(true)
|
||||||
return const Center(child: Text("Empty"));
|
.and()
|
||||||
}
|
.lastUsedEqualTo(true)
|
||||||
final entries = snapshot.data!
|
.watch(fireImmediately: true),
|
||||||
.where((element) => ref.watch(showNSFWStateProvider)
|
builder: (context, snapshot) {
|
||||||
? true
|
if (!snapshot.hasData) {
|
||||||
: element.isNsfw == false)
|
return const Center(child: Text(""));
|
||||||
.toList();
|
}
|
||||||
return GroupedListView<Source, String>(
|
final entries = snapshot.data!
|
||||||
elements: entries,
|
.where((element) => ref.watch(showNSFWStateProvider)
|
||||||
groupBy: (element) => completeLang(element.lang!.toLowerCase()),
|
? true
|
||||||
groupSeparatorBuilder: (String groupByValue) => Padding(
|
: element.isNsfw == false)
|
||||||
padding: const EdgeInsets.only(left: 12),
|
.toList();
|
||||||
child: Row(
|
return GroupedListView<Source, String>(
|
||||||
children: [
|
elements: entries,
|
||||||
Text(
|
groupBy: (element) => "",
|
||||||
groupByValue,
|
groupSeparatorBuilder: (String groupByValue) =>
|
||||||
style: const TextStyle(
|
const Padding(
|
||||||
fontWeight: FontWeight.w300, fontSize: 12),
|
padding: EdgeInsets.only(left: 12),
|
||||||
),
|
child: Row(
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
itemBuilder: (context, Source element) {
|
|
||||||
return ListTile(
|
|
||||||
onTap: () {
|
|
||||||
context.push('/mangaHome',
|
|
||||||
extra: MangaType(
|
|
||||||
isFullData: element.isFullData,
|
|
||||||
lang: element.lang,
|
|
||||||
source: element.sourceName));
|
|
||||||
},
|
|
||||||
leading: Container(
|
|
||||||
height: 37,
|
|
||||||
width: 37,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Theme.of(context)
|
|
||||||
.secondaryHeaderColor
|
|
||||||
.withOpacity(0.5),
|
|
||||||
borderRadius: BorderRadius.circular(5)),
|
|
||||||
child:
|
|
||||||
// element.logoUrl!.isEmpty
|
|
||||||
// ?
|
|
||||||
const Icon(Icons.source_outlined)
|
|
||||||
// : CachedNetworkImage(
|
|
||||||
// httpHeaders: ref.watch(
|
|
||||||
// headersProvider(source: element.sourceName!)),
|
|
||||||
// imageUrl: element.logoUrl!,
|
|
||||||
// fit: BoxFit.contain,
|
|
||||||
// width: 37,
|
|
||||||
// height: 37,
|
|
||||||
// errorWidget: (context, url, error) {
|
|
||||||
// return const SizedBox(
|
|
||||||
// width: 37,
|
|
||||||
// height: 37,
|
|
||||||
// child: Center(
|
|
||||||
// child: Icon(Icons.source_outlined),
|
|
||||||
// ),
|
|
||||||
// );
|
|
||||||
// },
|
|
||||||
// ),
|
|
||||||
),
|
|
||||||
subtitle: Row(
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
completeLang(element.lang!.toLowerCase()),
|
|
||||||
style: const TextStyle(
|
|
||||||
fontWeight: FontWeight.w300, fontSize: 12),
|
|
||||||
),
|
|
||||||
if (element.isNsfw!)
|
|
||||||
Row(
|
|
||||||
children: [
|
children: [
|
||||||
const SizedBox(
|
|
||||||
width: 2,
|
|
||||||
),
|
|
||||||
Text(
|
Text(
|
||||||
"18+",
|
"Last used",
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontWeight: FontWeight.w300,
|
fontWeight: FontWeight.bold, fontSize: 13),
|
||||||
fontSize: 10,
|
|
||||||
color: Colors.redAccent
|
|
||||||
.withBlue(5)
|
|
||||||
.withOpacity(0.8)),
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
)
|
),
|
||||||
],
|
),
|
||||||
),
|
itemBuilder: (context, Source element) {
|
||||||
title: Text(element.sourceName!),
|
return SourceListTile(
|
||||||
trailing: const SizedBox(
|
source: element,
|
||||||
width: 110,
|
);
|
||||||
child: Row(
|
},
|
||||||
mainAxisAlignment: MainAxisAlignment.end,
|
shrinkWrap: true,
|
||||||
children: [
|
groupComparator: (group1, group2) =>
|
||||||
Icon(
|
group1.compareTo(group2),
|
||||||
Icons.push_pin_outlined,
|
itemComparator: (item1, item2) =>
|
||||||
color: Colors.black,
|
item1.sourceName!.compareTo(item2.sourceName!),
|
||||||
)
|
order: GroupedListOrder.ASC,
|
||||||
],
|
);
|
||||||
)),
|
}),
|
||||||
);
|
StreamBuilder(
|
||||||
},
|
stream: isar.sources
|
||||||
groupComparator: (group1, group2) => group1.compareTo(group2),
|
.filter()
|
||||||
itemComparator: (item1, item2) =>
|
.idIsNotNull()
|
||||||
item1.sourceName!.compareTo(item2.sourceName!),
|
.isAddedEqualTo(true)
|
||||||
order: GroupedListOrder.ASC,
|
.and()
|
||||||
);
|
.isActiveEqualTo(true)
|
||||||
}),
|
.and()
|
||||||
);
|
.isPinnedEqualTo(true)
|
||||||
|
.watch(fireImmediately: true),
|
||||||
|
builder: (context, snapshot) {
|
||||||
|
if (!snapshot.hasData) {
|
||||||
|
return const Center(child: Text(""));
|
||||||
|
}
|
||||||
|
final entries = snapshot.data!
|
||||||
|
.where((element) => ref.watch(showNSFWStateProvider)
|
||||||
|
? true
|
||||||
|
: element.isNsfw == false)
|
||||||
|
.toList();
|
||||||
|
return GroupedListView<Source, String>(
|
||||||
|
elements: entries,
|
||||||
|
groupBy: (element) => "",
|
||||||
|
groupSeparatorBuilder: (String groupByValue) =>
|
||||||
|
const Padding(
|
||||||
|
padding: EdgeInsets.only(left: 12),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
"Pinned",
|
||||||
|
style: TextStyle(
|
||||||
|
fontWeight: FontWeight.bold, fontSize: 13),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
itemBuilder: (context, Source element) {
|
||||||
|
return SourceListTile(
|
||||||
|
source: element,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
shrinkWrap: true,
|
||||||
|
groupComparator: (group1, group2) =>
|
||||||
|
group1.compareTo(group2),
|
||||||
|
itemComparator: (item1, item2) =>
|
||||||
|
item1.sourceName!.compareTo(item2.sourceName!),
|
||||||
|
order: GroupedListOrder.ASC,
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
StreamBuilder(
|
||||||
|
stream: isar.sources
|
||||||
|
.filter()
|
||||||
|
.idIsNotNull()
|
||||||
|
.isAddedEqualTo(true)
|
||||||
|
.and()
|
||||||
|
.isActiveEqualTo(true)
|
||||||
|
.and()
|
||||||
|
.isPinnedEqualTo(false)
|
||||||
|
.watch(fireImmediately: true),
|
||||||
|
builder: (context, snapshot) {
|
||||||
|
if (!snapshot.hasData) {
|
||||||
|
return const Center(child: Text("Empty"));
|
||||||
|
}
|
||||||
|
final entries = snapshot.data!
|
||||||
|
.where((element) => ref.watch(showNSFWStateProvider)
|
||||||
|
? true
|
||||||
|
: element.isNsfw == false)
|
||||||
|
.toList();
|
||||||
|
return GroupedListView<Source, String>(
|
||||||
|
elements: entries,
|
||||||
|
groupBy: (element) =>
|
||||||
|
completeLang(element.lang!.toLowerCase()),
|
||||||
|
groupSeparatorBuilder: (String groupByValue) => Padding(
|
||||||
|
padding: const EdgeInsets.only(left: 12),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
groupByValue,
|
||||||
|
style: const TextStyle(
|
||||||
|
fontWeight: FontWeight.bold, fontSize: 13),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
itemBuilder: (context, Source element) {
|
||||||
|
return SourceListTile(
|
||||||
|
source: element,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
shrinkWrap: true,
|
||||||
|
groupComparator: (group1, group2) =>
|
||||||
|
group1.compareTo(group2),
|
||||||
|
itemComparator: (item1, item2) =>
|
||||||
|
item1.sourceName!.compareTo(item2.sourceName!),
|
||||||
|
order: GroupedListOrder.ASC,
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
95
lib/modules/browse/sources/widgets/source_list_tile.dart
Normal file
95
lib/modules/browse/sources/widgets/source_list_tile.dart
Normal file
|
|
@ -0,0 +1,95 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:go_router/go_router.dart';
|
||||||
|
import 'package:isar/isar.dart';
|
||||||
|
import 'package:mangayomi/main.dart';
|
||||||
|
import 'package:mangayomi/models/manga_type.dart';
|
||||||
|
import 'package:mangayomi/models/source.dart';
|
||||||
|
import 'package:mangayomi/utils/colors.dart';
|
||||||
|
import 'package:mangayomi/utils/lang.dart';
|
||||||
|
|
||||||
|
class SourceListTile extends StatelessWidget {
|
||||||
|
final Source source;
|
||||||
|
const SourceListTile({super.key, required this.source});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return ListTile(
|
||||||
|
onTap: () {
|
||||||
|
final sources = isar.sources.filter().idIsNotNull().findAllSync();
|
||||||
|
isar.writeTxnSync(() {
|
||||||
|
for (var src in sources) {
|
||||||
|
isar.sources
|
||||||
|
.putSync(src..lastUsed = src.id == source.id ? true : false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
context.push('/mangaHome',
|
||||||
|
extra: MangaType(
|
||||||
|
isFullData: source.isFullData,
|
||||||
|
lang: source.lang,
|
||||||
|
source: source.sourceName));
|
||||||
|
},
|
||||||
|
leading: Container(
|
||||||
|
height: 37,
|
||||||
|
width: 37,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Theme.of(context).secondaryHeaderColor.withOpacity(0.5),
|
||||||
|
borderRadius: BorderRadius.circular(5)),
|
||||||
|
child:
|
||||||
|
// source.logoUrl!.isEmpty
|
||||||
|
// ?
|
||||||
|
const Icon(Icons.source_outlined)
|
||||||
|
// : CachedNetworkImage(
|
||||||
|
// httpHeaders: ref.watch(
|
||||||
|
// headersProvider(source: source.sourceName!)),
|
||||||
|
// imageUrl: source.logoUrl!,
|
||||||
|
// fit: BoxFit.contain,
|
||||||
|
// width: 37,
|
||||||
|
// height: 37,
|
||||||
|
// errorWidget: (context, url, error) {
|
||||||
|
// return const SizedBox(
|
||||||
|
// width: 37,
|
||||||
|
// height: 37,
|
||||||
|
// child: Center(
|
||||||
|
// child: Icon(Icons.source_outlined),
|
||||||
|
// ),
|
||||||
|
// );
|
||||||
|
// },
|
||||||
|
// ),
|
||||||
|
),
|
||||||
|
subtitle: Row(
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
completeLang(source.lang!.toLowerCase()),
|
||||||
|
style: const TextStyle(fontWeight: FontWeight.w300, fontSize: 12),
|
||||||
|
),
|
||||||
|
if (source.isNsfw!)
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
const SizedBox(
|
||||||
|
width: 2,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
"18+",
|
||||||
|
style: TextStyle(
|
||||||
|
fontWeight: FontWeight.w300,
|
||||||
|
fontSize: 10,
|
||||||
|
color: Colors.redAccent.withBlue(5).withOpacity(0.8)),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
title: Text(source.sourceName!),
|
||||||
|
trailing: IconButton(
|
||||||
|
onPressed: () {
|
||||||
|
isar.writeTxnSync(() =>
|
||||||
|
isar.sources.putSync(source..isPinned = !source.isPinned!));
|
||||||
|
},
|
||||||
|
icon: Icon(
|
||||||
|
Icons.push_pin_outlined,
|
||||||
|
color: source.isPinned! ? primaryColor(context) : null,
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -16,13 +16,13 @@ class DarkModeButton extends ConsumerStatefulWidget {
|
||||||
class _DarkModeButtonState extends ConsumerState<DarkModeButton> {
|
class _DarkModeButtonState extends ConsumerState<DarkModeButton> {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
bool isLight = ref.watch(themeModeStateProvider);
|
bool isDark = ref.watch(themeModeStateProvider);
|
||||||
return SwitchListTile(
|
return SwitchListTile(
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
if (value) {
|
if (value) {
|
||||||
ref.read(themeModeStateProvider.notifier).setLightTheme();
|
|
||||||
} else {
|
|
||||||
ref.read(themeModeStateProvider.notifier).setDarkTheme();
|
ref.read(themeModeStateProvider.notifier).setDarkTheme();
|
||||||
|
} else {
|
||||||
|
ref.read(themeModeStateProvider.notifier).setLightTheme();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
title: const Text(
|
title: const Text(
|
||||||
|
|
@ -30,10 +30,10 @@ class _DarkModeButtonState extends ConsumerState<DarkModeButton> {
|
||||||
style: TextStyle(fontWeight: FontWeight.bold),
|
style: TextStyle(fontWeight: FontWeight.bold),
|
||||||
),
|
),
|
||||||
subtitle: Text(
|
subtitle: Text(
|
||||||
isLight ? 'Off' : 'On',
|
!isDark ? 'Off' : 'On',
|
||||||
style: TextStyle(fontSize: 11, color: secondaryColor(context)),
|
style: TextStyle(fontSize: 11, color: secondaryColor(context)),
|
||||||
),
|
),
|
||||||
value: isLight,
|
value: !isDark,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import 'package:mangayomi/models/manga.dart';
|
||||||
import 'package:mangayomi/models/settings.dart';
|
import 'package:mangayomi/models/settings.dart';
|
||||||
import 'package:mangayomi/sources/service.dart';
|
import 'package:mangayomi/sources/service.dart';
|
||||||
import 'package:mangayomi/utils/cached_network.dart';
|
import 'package:mangayomi/utils/cached_network.dart';
|
||||||
|
import 'package:mangayomi/utils/colors.dart';
|
||||||
import 'package:mangayomi/utils/headers.dart';
|
import 'package:mangayomi/utils/headers.dart';
|
||||||
import 'package:mangayomi/modules/widgets/bottom_text_widget.dart';
|
import 'package:mangayomi/modules/widgets/bottom_text_widget.dart';
|
||||||
import 'package:mangayomi/modules/widgets/cover_view_widget.dart';
|
import 'package:mangayomi/modules/widgets/cover_view_widget.dart';
|
||||||
|
|
@ -30,16 +31,50 @@ class MangaImageCardWidget extends ConsumerWidget {
|
||||||
pushToMangaReaderDetail(
|
pushToMangaReaderDetail(
|
||||||
context: context, getManga: getMangaDetail!, lang: lang);
|
context: context, getManga: getMangaDetail!, lang: lang);
|
||||||
},
|
},
|
||||||
child: CoverViewWidget(children: [
|
child: StreamBuilder(
|
||||||
cachedNetworkImage(
|
stream: isar.mangas
|
||||||
headers:
|
.filter()
|
||||||
ref.watch(headersProvider(source: getMangaDetail!.source!)),
|
.langEqualTo(lang)
|
||||||
imageUrl: getMangaDetail!.imageUrl!,
|
.nameEqualTo(getMangaDetail!.name)
|
||||||
width: 200,
|
.sourceEqualTo(getMangaDetail!.source)
|
||||||
height: 270,
|
.favoriteEqualTo(true)
|
||||||
fit: BoxFit.cover),
|
.watch(fireImmediately: true),
|
||||||
BottomTextWidget(text: getMangaDetail!.name!)
|
builder: (context, snapshot) {
|
||||||
]),
|
return CoverViewWidget(children: [
|
||||||
|
cachedNetworkImage(
|
||||||
|
headers: ref
|
||||||
|
.watch(headersProvider(source: getMangaDetail!.source!)),
|
||||||
|
imageUrl: getMangaDetail!.imageUrl!,
|
||||||
|
width: 200,
|
||||||
|
height: 270,
|
||||||
|
fit: BoxFit.cover),
|
||||||
|
Container(
|
||||||
|
color: snapshot.hasData && snapshot.data!.isNotEmpty
|
||||||
|
? Colors.black.withOpacity(0.7)
|
||||||
|
: null,
|
||||||
|
),
|
||||||
|
if (snapshot.hasData && snapshot.data!.isNotEmpty)
|
||||||
|
Positioned(
|
||||||
|
top: 0,
|
||||||
|
left: 0,
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(4),
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: primaryColor(context),
|
||||||
|
borderRadius: BorderRadius.circular(5)),
|
||||||
|
child: const Padding(
|
||||||
|
padding: EdgeInsets.all(2),
|
||||||
|
child: Text(
|
||||||
|
"In library",
|
||||||
|
style: TextStyle(fontSize: 12),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)),
|
||||||
|
BottomTextWidget(text: getMangaDetail!.name!)
|
||||||
|
]);
|
||||||
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -151,7 +151,7 @@ Future<String> cloudflareBypassHtml(CloudflareBypassHtmlRef ref,
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
await Future.delayed(Duration(seconds: 10));
|
await Future.delayed(const Duration(seconds: 10));
|
||||||
html = await controller.evaluateJavascript(
|
html = await controller.evaluateJavascript(
|
||||||
source:
|
source:
|
||||||
"window.document.getElementsByTagName('html')[0].outerHTML;");
|
"window.document.getElementsByTagName('html')[0].outerHTML;");
|
||||||
|
|
|
||||||
|
|
@ -84,19 +84,11 @@ List<Source> _madaraSourcesList = [
|
||||||
dateFormat: "MMMM dd, yyyy",
|
dateFormat: "MMMM dd, yyyy",
|
||||||
dateFormatLocale: "tr",
|
dateFormatLocale: "tr",
|
||||||
),
|
),
|
||||||
Source(
|
|
||||||
sourceName: "Comictoon",
|
|
||||||
baseUrl: "https://comictoonthaith-new.com",
|
|
||||||
lang: "th",
|
|
||||||
typeSource: TypeSource.madara,
|
|
||||||
logoUrl: '',
|
|
||||||
dateFormat: "MMMMM dd, yyyy",
|
|
||||||
dateFormatLocale: "th",
|
|
||||||
),
|
|
||||||
Source(
|
Source(
|
||||||
sourceName: "CookieToon",
|
sourceName: "CookieToon",
|
||||||
baseUrl: "https://cookietoon.online",
|
baseUrl: "https://cookietoon.online",
|
||||||
lang: "pt-BR",
|
lang: "pt-br",
|
||||||
typeSource: TypeSource.madara,
|
typeSource: TypeSource.madara,
|
||||||
logoUrl: '',
|
logoUrl: '',
|
||||||
dateFormat: "dd/MM/yyyy",
|
dateFormat: "dd/MM/yyyy",
|
||||||
|
|
@ -105,7 +97,7 @@ List<Source> _madaraSourcesList = [
|
||||||
Source(
|
Source(
|
||||||
sourceName: "Drope Scan",
|
sourceName: "Drope Scan",
|
||||||
baseUrl: "https://dropescan.com",
|
baseUrl: "https://dropescan.com",
|
||||||
lang: "pt-BR",
|
lang: "pt-br",
|
||||||
typeSource: TypeSource.madara,
|
typeSource: TypeSource.madara,
|
||||||
logoUrl: '',
|
logoUrl: '',
|
||||||
dateFormat: "dd/MM/yyyy",
|
dateFormat: "dd/MM/yyyy",
|
||||||
|
|
@ -123,7 +115,7 @@ List<Source> _madaraSourcesList = [
|
||||||
Source(
|
Source(
|
||||||
sourceName: "Final Scans",
|
sourceName: "Final Scans",
|
||||||
baseUrl: "https://finalscans.com",
|
baseUrl: "https://finalscans.com",
|
||||||
lang: "pt-BR",
|
lang: "pt-br",
|
||||||
typeSource: TypeSource.madara,
|
typeSource: TypeSource.madara,
|
||||||
logoUrl: '',
|
logoUrl: '',
|
||||||
isNsfw: true,
|
isNsfw: true,
|
||||||
|
|
@ -190,7 +182,7 @@ List<Source> _madaraSourcesList = [
|
||||||
Source(
|
Source(
|
||||||
sourceName: "Kami Sama Explorer",
|
sourceName: "Kami Sama Explorer",
|
||||||
baseUrl: "https://leitor.kamisama.com.br",
|
baseUrl: "https://leitor.kamisama.com.br",
|
||||||
lang: "pt-BR",
|
lang: "pt-br",
|
||||||
typeSource: TypeSource.madara,
|
typeSource: TypeSource.madara,
|
||||||
logoUrl: '',
|
logoUrl: '',
|
||||||
dateFormat: "dd 'de' MMMM 'de' yyyy",
|
dateFormat: "dd 'de' MMMM 'de' yyyy",
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,4 @@
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:developer';
|
|
||||||
|
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:html/dom.dart';
|
import 'package:html/dom.dart';
|
||||||
import 'package:mangayomi/models/chapter.dart';
|
import 'package:mangayomi/models/chapter.dart';
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ const logoUrl =
|
||||||
'https://comick.app/_next/image?url=%2Fstatic%2Ficons%2Funicorn-64.png&w=144&q=75';
|
'https://comick.app/_next/image?url=%2Fstatic%2Ficons%2Funicorn-64.png&w=144&q=75';
|
||||||
const apiUrl = 'https://api.comick.fun';
|
const apiUrl = 'https://api.comick.fun';
|
||||||
const baseUrl = 'https://comick.app';
|
const baseUrl = 'https://comick.app';
|
||||||
|
const isNsfw = true;
|
||||||
List<Source> get comickSourcesList => _comickSourcesList;
|
List<Source> get comickSourcesList => _comickSourcesList;
|
||||||
List<Source> _comickSourcesList = [
|
List<Source> _comickSourcesList = [
|
||||||
Source(
|
Source(
|
||||||
|
|
@ -15,6 +15,7 @@ List<Source> _comickSourcesList = [
|
||||||
typeSource: TypeSource.comick,
|
typeSource: TypeSource.comick,
|
||||||
logoUrl: logoUrl,
|
logoUrl: logoUrl,
|
||||||
dateFormat: "yyyy-MM-dd'T'HH:mm:ss'Z'",
|
dateFormat: "yyyy-MM-dd'T'HH:mm:ss'Z'",
|
||||||
|
isNsfw: isNsfw,
|
||||||
dateFormatLocale: "en"),
|
dateFormatLocale: "en"),
|
||||||
Source(
|
Source(
|
||||||
sourceName: 'Comick',
|
sourceName: 'Comick',
|
||||||
|
|
@ -24,6 +25,7 @@ List<Source> _comickSourcesList = [
|
||||||
typeSource: TypeSource.comick,
|
typeSource: TypeSource.comick,
|
||||||
logoUrl: logoUrl,
|
logoUrl: logoUrl,
|
||||||
dateFormat: "yyyy-MM-dd'T'HH:mm:ss'Z'",
|
dateFormat: "yyyy-MM-dd'T'HH:mm:ss'Z'",
|
||||||
|
isNsfw: isNsfw,
|
||||||
dateFormatLocale: "en"),
|
dateFormatLocale: "en"),
|
||||||
Source(
|
Source(
|
||||||
sourceName: 'Comick',
|
sourceName: 'Comick',
|
||||||
|
|
@ -33,6 +35,7 @@ List<Source> _comickSourcesList = [
|
||||||
typeSource: TypeSource.comick,
|
typeSource: TypeSource.comick,
|
||||||
logoUrl: logoUrl,
|
logoUrl: logoUrl,
|
||||||
dateFormat: "yyyy-MM-dd'T'HH:mm:ss'Z'",
|
dateFormat: "yyyy-MM-dd'T'HH:mm:ss'Z'",
|
||||||
|
isNsfw: isNsfw,
|
||||||
dateFormatLocale: "en"),
|
dateFormatLocale: "en"),
|
||||||
Source(
|
Source(
|
||||||
sourceName: 'Comick',
|
sourceName: 'Comick',
|
||||||
|
|
@ -42,6 +45,7 @@ List<Source> _comickSourcesList = [
|
||||||
typeSource: TypeSource.comick,
|
typeSource: TypeSource.comick,
|
||||||
logoUrl: logoUrl,
|
logoUrl: logoUrl,
|
||||||
dateFormat: "yyyy-MM-dd'T'HH:mm:ss'Z'",
|
dateFormat: "yyyy-MM-dd'T'HH:mm:ss'Z'",
|
||||||
|
isNsfw: isNsfw,
|
||||||
dateFormatLocale: "en"),
|
dateFormatLocale: "en"),
|
||||||
Source(
|
Source(
|
||||||
sourceName: 'Comick',
|
sourceName: 'Comick',
|
||||||
|
|
@ -51,6 +55,7 @@ List<Source> _comickSourcesList = [
|
||||||
typeSource: TypeSource.comick,
|
typeSource: TypeSource.comick,
|
||||||
logoUrl: logoUrl,
|
logoUrl: logoUrl,
|
||||||
dateFormat: "yyyy-MM-dd'T'HH:mm:ss'Z'",
|
dateFormat: "yyyy-MM-dd'T'HH:mm:ss'Z'",
|
||||||
|
isNsfw: isNsfw,
|
||||||
dateFormatLocale: "en"),
|
dateFormatLocale: "en"),
|
||||||
Source(
|
Source(
|
||||||
sourceName: 'Comick',
|
sourceName: 'Comick',
|
||||||
|
|
@ -60,6 +65,7 @@ List<Source> _comickSourcesList = [
|
||||||
typeSource: TypeSource.comick,
|
typeSource: TypeSource.comick,
|
||||||
logoUrl: logoUrl,
|
logoUrl: logoUrl,
|
||||||
dateFormat: "yyyy-MM-dd'T'HH:mm:ss'Z'",
|
dateFormat: "yyyy-MM-dd'T'HH:mm:ss'Z'",
|
||||||
|
isNsfw: isNsfw,
|
||||||
dateFormatLocale: "en"),
|
dateFormatLocale: "en"),
|
||||||
Source(
|
Source(
|
||||||
sourceName: 'Comick',
|
sourceName: 'Comick',
|
||||||
|
|
@ -69,6 +75,7 @@ List<Source> _comickSourcesList = [
|
||||||
typeSource: TypeSource.comick,
|
typeSource: TypeSource.comick,
|
||||||
logoUrl: logoUrl,
|
logoUrl: logoUrl,
|
||||||
dateFormat: "yyyy-MM-dd'T'HH:mm:ss'Z'",
|
dateFormat: "yyyy-MM-dd'T'HH:mm:ss'Z'",
|
||||||
|
isNsfw: isNsfw,
|
||||||
dateFormatLocale: "en"),
|
dateFormatLocale: "en"),
|
||||||
Source(
|
Source(
|
||||||
sourceName: 'Comick',
|
sourceName: 'Comick',
|
||||||
|
|
@ -78,6 +85,7 @@ List<Source> _comickSourcesList = [
|
||||||
typeSource: TypeSource.comick,
|
typeSource: TypeSource.comick,
|
||||||
logoUrl: logoUrl,
|
logoUrl: logoUrl,
|
||||||
dateFormat: "yyyy-MM-dd'T'HH:mm:ss'Z'",
|
dateFormat: "yyyy-MM-dd'T'HH:mm:ss'Z'",
|
||||||
|
isNsfw: isNsfw,
|
||||||
dateFormatLocale: "en"),
|
dateFormatLocale: "en"),
|
||||||
Source(
|
Source(
|
||||||
sourceName: 'Comick',
|
sourceName: 'Comick',
|
||||||
|
|
@ -87,6 +95,7 @@ List<Source> _comickSourcesList = [
|
||||||
typeSource: TypeSource.comick,
|
typeSource: TypeSource.comick,
|
||||||
logoUrl: logoUrl,
|
logoUrl: logoUrl,
|
||||||
dateFormat: "yyyy-MM-dd'T'HH:mm:ss'Z'",
|
dateFormat: "yyyy-MM-dd'T'HH:mm:ss'Z'",
|
||||||
|
isNsfw: isNsfw,
|
||||||
dateFormatLocale: "en"),
|
dateFormatLocale: "en"),
|
||||||
Source(
|
Source(
|
||||||
sourceName: 'Comick',
|
sourceName: 'Comick',
|
||||||
|
|
@ -96,6 +105,7 @@ List<Source> _comickSourcesList = [
|
||||||
typeSource: TypeSource.comick,
|
typeSource: TypeSource.comick,
|
||||||
logoUrl: logoUrl,
|
logoUrl: logoUrl,
|
||||||
dateFormat: "yyyy-MM-dd'T'HH:mm:ss'Z'",
|
dateFormat: "yyyy-MM-dd'T'HH:mm:ss'Z'",
|
||||||
|
isNsfw: isNsfw,
|
||||||
dateFormatLocale: "en"),
|
dateFormatLocale: "en"),
|
||||||
Source(
|
Source(
|
||||||
sourceName: 'Comick',
|
sourceName: 'Comick',
|
||||||
|
|
@ -105,6 +115,7 @@ List<Source> _comickSourcesList = [
|
||||||
typeSource: TypeSource.comick,
|
typeSource: TypeSource.comick,
|
||||||
logoUrl: logoUrl,
|
logoUrl: logoUrl,
|
||||||
dateFormat: "yyyy-MM-dd'T'HH:mm:ss'Z'",
|
dateFormat: "yyyy-MM-dd'T'HH:mm:ss'Z'",
|
||||||
|
isNsfw: isNsfw,
|
||||||
dateFormatLocale: "en"),
|
dateFormatLocale: "en"),
|
||||||
Source(
|
Source(
|
||||||
sourceName: 'Comick',
|
sourceName: 'Comick',
|
||||||
|
|
@ -114,6 +125,7 @@ List<Source> _comickSourcesList = [
|
||||||
typeSource: TypeSource.comick,
|
typeSource: TypeSource.comick,
|
||||||
logoUrl: logoUrl,
|
logoUrl: logoUrl,
|
||||||
dateFormat: "yyyy-MM-dd'T'HH:mm:ss'Z'",
|
dateFormat: "yyyy-MM-dd'T'HH:mm:ss'Z'",
|
||||||
|
isNsfw: isNsfw,
|
||||||
dateFormatLocale: "en"),
|
dateFormatLocale: "en"),
|
||||||
Source(
|
Source(
|
||||||
sourceName: 'Comick',
|
sourceName: 'Comick',
|
||||||
|
|
@ -123,6 +135,7 @@ List<Source> _comickSourcesList = [
|
||||||
typeSource: TypeSource.comick,
|
typeSource: TypeSource.comick,
|
||||||
logoUrl: logoUrl,
|
logoUrl: logoUrl,
|
||||||
dateFormat: "yyyy-MM-dd'T'HH:mm:ss'Z'",
|
dateFormat: "yyyy-MM-dd'T'HH:mm:ss'Z'",
|
||||||
|
isNsfw: isNsfw,
|
||||||
dateFormatLocale: "en"),
|
dateFormatLocale: "en"),
|
||||||
Source(
|
Source(
|
||||||
sourceName: 'Comick',
|
sourceName: 'Comick',
|
||||||
|
|
@ -132,6 +145,7 @@ List<Source> _comickSourcesList = [
|
||||||
typeSource: TypeSource.comick,
|
typeSource: TypeSource.comick,
|
||||||
logoUrl: logoUrl,
|
logoUrl: logoUrl,
|
||||||
dateFormat: "yyyy-MM-dd'T'HH:mm:ss'Z'",
|
dateFormat: "yyyy-MM-dd'T'HH:mm:ss'Z'",
|
||||||
|
isNsfw: isNsfw,
|
||||||
dateFormatLocale: "en"),
|
dateFormatLocale: "en"),
|
||||||
Source(
|
Source(
|
||||||
sourceName: 'Comick',
|
sourceName: 'Comick',
|
||||||
|
|
@ -141,6 +155,7 @@ List<Source> _comickSourcesList = [
|
||||||
typeSource: TypeSource.comick,
|
typeSource: TypeSource.comick,
|
||||||
logoUrl: logoUrl,
|
logoUrl: logoUrl,
|
||||||
dateFormat: "yyyy-MM-dd'T'HH:mm:ss'Z'",
|
dateFormat: "yyyy-MM-dd'T'HH:mm:ss'Z'",
|
||||||
|
isNsfw: isNsfw,
|
||||||
dateFormatLocale: "en"),
|
dateFormatLocale: "en"),
|
||||||
Source(
|
Source(
|
||||||
sourceName: 'Comick',
|
sourceName: 'Comick',
|
||||||
|
|
@ -150,6 +165,7 @@ List<Source> _comickSourcesList = [
|
||||||
typeSource: TypeSource.comick,
|
typeSource: TypeSource.comick,
|
||||||
logoUrl: logoUrl,
|
logoUrl: logoUrl,
|
||||||
dateFormat: "yyyy-MM-dd'T'HH:mm:ss'Z'",
|
dateFormat: "yyyy-MM-dd'T'HH:mm:ss'Z'",
|
||||||
|
isNsfw: isNsfw,
|
||||||
dateFormatLocale: "en"),
|
dateFormatLocale: "en"),
|
||||||
Source(
|
Source(
|
||||||
sourceName: 'Comick',
|
sourceName: 'Comick',
|
||||||
|
|
@ -159,5 +175,6 @@ List<Source> _comickSourcesList = [
|
||||||
typeSource: TypeSource.comick,
|
typeSource: TypeSource.comick,
|
||||||
logoUrl: logoUrl,
|
logoUrl: logoUrl,
|
||||||
dateFormat: "yyyy-MM-dd'T'HH:mm:ss'Z'",
|
dateFormat: "yyyy-MM-dd'T'HH:mm:ss'Z'",
|
||||||
|
isNsfw: isNsfw,
|
||||||
dateFormatLocale: "en"),
|
dateFormatLocale: "en"),
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -103,18 +103,18 @@ class Comick extends MangaYomiServices {
|
||||||
required AutoDisposeFutureProviderRef ref}) async {
|
required AutoDisposeFutureProviderRef ref}) async {
|
||||||
final response = await ref.watch(httpGetProvider(
|
final response = await ref.watch(httpGetProvider(
|
||||||
url:
|
url:
|
||||||
'https://api.comick.fun/search?q=${query.trim()}&tachiyomi=true&page=1',
|
'${getMangaAPIUrl(source)}/v1.0/search?q=${query.trim()}&tachiyomi=true&limit=50&page=1',
|
||||||
source: source,
|
source: source,
|
||||||
resDom: false)
|
resDom: false)
|
||||||
.future) as String?;
|
.future) as String?;
|
||||||
var popularManga = jsonDecode(response!) as List;
|
var search = jsonDecode(response!) as List;
|
||||||
var popularMangaList =
|
var searchList =
|
||||||
popularManga.map((e) => MangaSearchModelComick.fromJson(e)).toList();
|
search.map((e) => MangaSearchModelComick.fromJson(e)).toList();
|
||||||
|
|
||||||
for (var popular in popularMangaList) {
|
for (var search in searchList) {
|
||||||
url.add("/comic/${popular.slug}");
|
url.add("/comic/${search.hid}#");
|
||||||
name.add(popular.title);
|
name.add(search.title);
|
||||||
image.add(popular.coverUrl);
|
image.add(search.coverUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
return mangaRes();
|
return mangaRes();
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ class MangaSearchModelComick {
|
||||||
title = json['title'];
|
title = json['title'];
|
||||||
|
|
||||||
slug = json['slug'];
|
slug = json['slug'];
|
||||||
|
hid = json['hid'];
|
||||||
|
|
||||||
coverUrl = json['cover_url'];
|
coverUrl = json['cover_url'];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -214,8 +214,10 @@ class MangaKawaii extends MangaYomiServices {
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List<GetManga?>> getLatestUpdatesManga({required String source, required int page, required AutoDisposeFutureProviderRef ref}) {
|
Future<List<GetManga?>> getLatestUpdatesManga(
|
||||||
// TODO: implement getLatestUpdatesManga
|
{required String source,
|
||||||
|
required int page,
|
||||||
|
required AutoDisposeFutureProviderRef ref}) {
|
||||||
throw UnimplementedError();
|
throw UnimplementedError();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue