feature: pinned , last used source + fix

This commit is contained in:
kodjomoustapha 2023-05-27 20:34:05 +01:00
parent bc47bf00f0
commit dfd82b32f6
19 changed files with 586 additions and 214 deletions

View file

@ -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,

View file

@ -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 = "",
}); });
} }

View file

@ -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');

View file

@ -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';

View file

@ -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),
), ),
], ],
), ),

View file

@ -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);
} }
} }

View file

@ -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)

View file

@ -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())),
); );

View file

@ -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,
);
}),
],
),
));
} }
} }

View 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,
)),
);
}
}

View file

@ -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,
); );
} }
} }

View file

@ -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!)
]);
}),
); );
} }
} }

View file

@ -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;");

View file

@ -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",

View file

@ -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';

View file

@ -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"),
]; ];

View file

@ -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();

View file

@ -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'];
} }

View file

@ -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();
} }
} }