diff --git a/lib/constant.dart b/lib/constant.dart index bdedd661..571595dd 100644 --- a/lib/constant.dart +++ b/lib/constant.dart @@ -2,4 +2,6 @@ class HiveConstant { static String get hiveBoxManga => "manga_box"; static String get hiveBoxMangaInfo => "manga_box_info"; static String get hiveBoxMangaHistory => "_manga_box_history_"; + static String get hiveBoxMangaSource => "_manga_box_source_"; + static String get hiveBoxMangaFilter => "_manga_box_filter_"; } diff --git a/lib/main.dart b/lib/main.dart index 67fe442b..1e288df1 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -6,16 +6,19 @@ import 'package:mangayomi/constant.dart'; import 'package:mangayomi/models/manga_history.dart'; import 'package:mangayomi/models/model_manga.dart'; import 'package:mangayomi/router/router.dart'; +import 'package:mangayomi/source/source_model.dart'; void main() async { await Hive.initFlutter(); Hive.registerAdapter(ModelMangaAdapter()); Hive.registerAdapter(MangaHistoryModelAdapter()); - await Hive.openBox( - HiveConstant.hiveBoxManga, - ); + Hive.registerAdapter(SourceModelAdapter()); + Hive.registerAdapter(TypeSourceAdapter()); + await Hive.openBox(HiveConstant.hiveBoxManga); await Hive.openBox(HiveConstant.hiveBoxMangaHistory); + await Hive.openBox(HiveConstant.hiveBoxMangaSource); await Hive.openBox(HiveConstant.hiveBoxMangaInfo); + await Hive.openBox(HiveConstant.hiveBoxMangaFilter); runApp(const ProviderScope(child: MyApp())); } diff --git a/lib/providers/hive_provider.dart b/lib/providers/hive_provider.dart index 53cf5a3e..7754f3f7 100644 --- a/lib/providers/hive_provider.dart +++ b/lib/providers/hive_provider.dart @@ -3,6 +3,7 @@ import 'package:hive_flutter/hive_flutter.dart'; import 'package:mangayomi/constant.dart'; import 'package:mangayomi/models/manga_history.dart'; import 'package:mangayomi/models/model_manga.dart'; +import 'package:mangayomi/source/source_model.dart'; final hiveBoxManga = Provider>((ref) { return Hive.box(HiveConstant.hiveBoxManga); @@ -14,3 +15,11 @@ final hiveBoxMangaInfo = Provider((ref) { final hiveBoxMangaHistory = Provider>((ref) { return Hive.box(HiveConstant.hiveBoxMangaHistory); }); + +final hiveBoxMangaFilterProvider = Provider((ref) { + return Hive.box(HiveConstant.hiveBoxMangaFilter); +}); + +final hiveBoxMangaSourceProvider = Provider>((ref) { + return Hive.box(HiveConstant.hiveBoxMangaSource); +}); diff --git a/lib/router/router.dart b/lib/router/router.dart index 5fe84b86..7f1da154 100644 --- a/lib/router/router.dart +++ b/lib/router/router.dart @@ -5,6 +5,7 @@ import 'package:mangayomi/models/manga_reader.dart'; import 'package:mangayomi/models/manga_type.dart'; import 'package:mangayomi/models/model_manga.dart'; import 'package:mangayomi/views/browse/browse_screen.dart'; +import 'package:mangayomi/views/browse/extension/extension_lang.dart'; import 'package:mangayomi/views/general/general_screen.dart'; import 'package:mangayomi/views/history/history_screen.dart'; import 'package:mangayomi/views/library/library_screen.dart'; @@ -135,6 +136,19 @@ class AsyncRouterNotifier extends ChangeNotifier { ); }, ), + GoRoute( + path: "/extensionLang", + name: "extensionLang", + builder: (context, state) { + return const ExtensionsLang(); + }, + pageBuilder: (context, state) { + return CustomTransition( + key: state.pageKey, + child: const ExtensionsLang(), + ); + }, + ), ]; } diff --git a/lib/services/get_manga_chapter_url.dart b/lib/services/get_manga_chapter_url.dart index 35643e80..2d1da5f2 100644 --- a/lib/services/get_manga_chapter_url.dart +++ b/lib/services/get_manga_chapter_url.dart @@ -38,8 +38,9 @@ Future getMangaChapterUrl( if (hiveUrl.isNotEmpty) { urll = hiveUrl; } - - //mangahere + /***********/ + /*mangahere*/ + /***********/ else if (source == 'mangahere') { JavascriptRuntime? flutterJs; flutterJs = getJavascriptRuntime(); diff --git a/lib/services/get_manga_chapter_url.g.dart b/lib/services/get_manga_chapter_url.g.dart index 48d5ddee..5ba9182a 100644 --- a/lib/services/get_manga_chapter_url.g.dart +++ b/lib/services/get_manga_chapter_url.g.dart @@ -7,7 +7,7 @@ part of 'get_manga_chapter_url.dart'; // ************************************************************************** String _$getMangaChapterUrlHash() => - r'acdd4b5eacb246441b55d1c19614032b789b0828'; + r'bd696a5ff424b0396cd67d08325945f6ac00093b'; /// Copied from Dart SDK class _SystemHash { diff --git a/lib/source/source_list.dart b/lib/source/source_list.dart new file mode 100644 index 00000000..5108f7ab --- /dev/null +++ b/lib/source/source_list.dart @@ -0,0 +1,383 @@ +import 'package:mangayomi/source/source_model.dart'; + +List sourcesList = [ + SourceModel( + sourceName: "MangaHere", + url: "http://www.mangahere.cc", + lang: "en", + typeSource: TypeSource.single), + SourceModel( + sourceName: "MangaSee", + url: "https://mangasee123.com", + lang: "en", + typeSource: TypeSource.single), + SourceModel( + sourceName: "ManngaKawaii", + url: "https://www.mangakawaii.io", + lang: "fr", + typeSource: TypeSource.single), + SourceModel( + sourceName: 'Comick', + url: 'https://api.comick.fun/', + lang: 'en', + typeSource: TypeSource.comick), + SourceModel( + sourceName: 'Comick', + url: 'https://api.comick.fun/', + lang: 'ar', + typeSource: TypeSource.comick), + SourceModel( + sourceName: 'Comick', + url: 'https://api.comick.fun/', + lang: 'pt', + typeSource: TypeSource.comick), + SourceModel( + sourceName: 'Comick', + url: 'https://api.comick.fun/', + lang: 'pt-br', + typeSource: TypeSource.comick), + SourceModel( + sourceName: 'Comick', + url: 'https://api.comick.fun/', + lang: 'it', + typeSource: TypeSource.comick), + SourceModel( + sourceName: 'Comick', + url: 'https://api.comick.fun/', + lang: 'ru', + typeSource: TypeSource.comick), + SourceModel( + sourceName: 'Comick', + url: 'https://api.comick.fun/', + lang: 'es', + typeSource: TypeSource.comick), + SourceModel( + sourceName: 'Comick', + url: 'https://api.comick.fun/', + lang: 'es-419', + typeSource: TypeSource.comick), + SourceModel( + sourceName: 'Comick', + url: 'https://api.comick.fun/', + lang: 'id', + typeSource: TypeSource.comick), + SourceModel( + sourceName: 'Comick', + url: 'https://api.comick.fun/', + lang: 'hi', + typeSource: TypeSource.comick), + SourceModel( + sourceName: 'Comick', + url: 'https://api.comick.fun/', + lang: 'de', + typeSource: TypeSource.comick), + SourceModel( + sourceName: 'Comick', + url: 'https://api.comick.fun/', + lang: 'ja', + typeSource: TypeSource.comick), + SourceModel( + sourceName: 'Comick', + url: 'https://api.comick.fun/', + lang: 'tr', + typeSource: TypeSource.comick), + SourceModel( + sourceName: 'Comick', + url: 'https://api.comick.fun/', + lang: 'pl', + typeSource: TypeSource.comick), + SourceModel( + sourceName: 'Comick', + url: 'https://api.comick.fun/', + lang: 'zh', + typeSource: TypeSource.comick), + SourceModel( + sourceName: 'Comick', + url: 'https://api.comick.fun/', + lang: 'zh-hk', + typeSource: TypeSource.comick), + SourceModel( + sourceName: 'Comick', + url: 'https://api.comick.fun/', + lang: 'fr', + typeSource: TypeSource.comick), + SourceModel( + sourceName: "KomikLab", + url: "https://komiklab.com", + lang: "en", + typeSource: TypeSource.mangathemesia), + SourceModel( + sourceName: "AnimatedGlitchedScans", + url: "https://anigliscans.com", + lang: "en", + typeSource: TypeSource.mangathemesia), + SourceModel( + sourceName: "ArenaScans", + url: "https://arenascans.net", + lang: "en", + typeSource: TypeSource.mangathemesia), + SourceModel( + sourceName: "AzureScans", + url: "https://azuremanga.com", + lang: "en", + typeSource: TypeSource.mangathemesia), + SourceModel( + sourceName: "Boosei", + url: "https://boosei.net", + lang: "id", + typeSource: TypeSource.mangathemesia), + SourceModel( + sourceName: "Clayrer", + url: "https://clayrer.net", + lang: "es", + typeSource: TypeSource.mangathemesia), + SourceModel( + sourceName: "CosmicScans", + url: "https://cosmicscans.com", + lang: "en", + typeSource: TypeSource.mangathemesia), + SourceModel( + sourceName: "DiskusScan", + url: "https://diskusscan.com", + lang: "pt-BR", + typeSource: TypeSource.mangathemesia), + SourceModel( + sourceName: "DuniaKomik", + url: "https://duniakomik.id", + lang: "id", + typeSource: TypeSource.mangathemesia), + SourceModel( + sourceName: "FlameScans", + url: "https://flamescans.fr", + lang: "fr", + typeSource: TypeSource.mangathemesia), + SourceModel( + sourceName: "GremoryMangas", + url: "https://gremorymangas.com", + lang: "es", + typeSource: TypeSource.mangathemesia), + SourceModel( + sourceName: "InfernalVoidScans", + url: "https://void-scans.com", + lang: "en", + typeSource: TypeSource.mangathemesia), + SourceModel( + sourceName: "Kiryuu", + url: "https://kiryuu.id", + lang: "id", + typeSource: TypeSource.mangathemesia), + SourceModel( + sourceName: "KomikIndo", + url: "https://komikindo.co", + lang: "id", + typeSource: TypeSource.mangathemesia), + SourceModel( + sourceName: "KomikMama", + url: "https://komikmama.co", + lang: "id", + typeSource: TypeSource.mangathemesia), + SourceModel( + sourceName: "Komiku", + url: "https://komiku.com", + lang: "id", + typeSource: TypeSource.mangathemesia), + SourceModel( + sourceName: "KumaScans (Kuma Translation)", + url: "https://kumascans.com", + lang: "en", + typeSource: TypeSource.mangathemesia), + SourceModel( + sourceName: "MangaKita", + url: "https://mangakita.net", + lang: "id", + typeSource: TypeSource.mangathemesia), + SourceModel( + sourceName: "MangaTale", + url: "https://mangatale.co", + lang: "id", + typeSource: TypeSource.mangathemesia), + SourceModel( + sourceName: "MangaYaro", + url: "https://mangayaro.net", + lang: "id", + typeSource: TypeSource.mangathemesia), + SourceModel( + sourceName: "MangKomik", + url: "https://mangkomik.net", + lang: "id", + typeSource: TypeSource.mangathemesia), + SourceModel( + sourceName: "MangásChan", + url: "https://mangaschan.com", + lang: "pt-BR", + typeSource: TypeSource.mangathemesia), + SourceModel( + sourceName: "ManhwaFreak", + url: "https://manhwafreak.com", + lang: "en", + typeSource: TypeSource.mangathemesia), + SourceModel( + sourceName: "ManhwaList", + url: "https://manhwalist.in", + lang: "id", + typeSource: TypeSource.mangathemesia), + SourceModel( + sourceName: "MasterKomik", + url: "https://masterkomik.com", + lang: "id", + typeSource: TypeSource.mangathemesia), + SourceModel( + sourceName: "Nekomik", + url: "https://nekomik.com", + lang: "id", + typeSource: TypeSource.mangathemesia), + SourceModel( + sourceName: "PhantomScans", + url: "https://phantomscans.com", + lang: "en", + typeSource: TypeSource.mangathemesia), + SourceModel( + sourceName: "PhoenixFansub", + url: "https://phoenixfansub.com", + lang: "es", + typeSource: TypeSource.mangathemesia), + SourceModel( + sourceName: "PiScans", + url: "https://piscans.in", + lang: "id", + typeSource: TypeSource.mangathemesia), + SourceModel( + sourceName: "Rawkuma", + url: "https://rawkuma.com/", + lang: "ja", + typeSource: TypeSource.mangathemesia), + SourceModel( + sourceName: "Readkomik", + url: "https://readkomik.com", + lang: "en", + typeSource: TypeSource.mangathemesia), + SourceModel( + sourceName: "SuryaScans", + url: "https://suryascans.com", + lang: "en", + typeSource: TypeSource.mangathemesia), + SourceModel( + sourceName: "SushiScan", + url: "https://sushiscan.ru", + lang: "fr", + typeSource: TypeSource.mangathemesia), + SourceModel( + sourceName: "TsundokuTraduções", + url: "https://tsundoku.com.br", + lang: "pt-BR", + typeSource: TypeSource.mangathemesia), + SourceModel( + sourceName: "TukangKomik", + url: "https://tukangkomik.id", + lang: "id", + typeSource: TypeSource.mangathemesia), + SourceModel( + sourceName: "WestManga", + url: "https://westmanga.info", + lang: "id", + typeSource: TypeSource.mangathemesia), + SourceModel( + sourceName: "xCaliBRScans", + url: "https://xcalibrscans.com", + lang: "en", + typeSource: TypeSource.mangathemesia), +]; + + + +// List sourcesList = [ +// SourceModel(Source("MangaHere", "http://www.mangahere.cc", "en", TypeSource.single)), +// SourceModel(Source("MangaSee", "https://mangasee123.com", "en", typeSource:TypeSource.single)), +// SourceModel(Source( +// "ManngaKawaii", "https://www.mangakawaii.io", "fr", typeSource:TypeSource.single)), +// SourceModel(Source('Comick', 'https://api.comick.fun/', 'en', TypeSource.comick)), +// SourceModel(Source('Comick', 'https://api.comick.fun/', 'ar', TypeSource.comick)), +// SourceModel(Source('Comick', 'https://api.comick.fun/', 'pt', TypeSource.comick)), +// SourceModel(Source('Comick', 'https://api.comick.fun/', 'pt-br', TypeSource.comick)), +// SourceModel(Source('Comick', 'https://api.comick.fun/', 'it', TypeSource.comick)), +// SourceModel(Source('Comick', 'https://api.comick.fun/', 'ru', TypeSource.comick)), +// SourceModel(Source('Comick', 'https://api.comick.fun/', 'es', TypeSource.comick)), +// SourceModel(Source('Comick', 'https://api.comick.fun/', 'es-419', TypeSource.comick)), +// SourceModel(Source('Comick', 'https://api.comick.fun/', 'id', TypeSource.comick)), +// SourceModel(Source('Comick', 'https://api.comick.fun/', 'hi', TypeSource.comick)), +// SourceModel(Source('Comick', 'https://api.comick.fun/', 'de', TypeSource.comick)), +// SourceModel(Source('Comick', 'https://api.comick.fun/', 'ja', TypeSource.comick)), +// SourceModel(Source('Comick', 'https://api.comick.fun/', 'tr', TypeSource.comick)), +// SourceModel(Source('Comick', 'https://api.comick.fun/', 'pl', TypeSource.comick)), +// SourceModel(Source('Comick', 'https://api.comick.fun/', 'zh', TypeSource.comick)), +// SourceModel(Source('Comick', 'https://api.comick.fun/', 'zh-hk', TypeSource.comick)), +// SourceModel(Source('Comick', 'https://api.comick.fun/', 'fr', TypeSource.comick)), +// SourceModel(Source( +// "KomikLab", "https://komiklab.com", "en", TypeSource.mangathemesia)), +// SourceModel(Source("AnimatedGlitchedScans", "https://anigliscans.com", "en", +// TypeSource.mangathemesia)), +// SourceModel(Source( +// "ArenaScans", "https://arenascans.net", "en", TypeSource.mangathemesia)), +// SourceModel(Source( +// "AzureScans", "https://azuremanga.com", "en", TypeSource.mangathemesia)), +// SourceModel(Source("Boosei", "https://boosei.net", "id", TypeSource.mangathemesia)), +// SourceModel(Source("Clayrer", "https://clayrer.net", "es", TypeSource.mangathemesia)), +// SourceModel(Source( +// "CosmicScans", "https://cosmicscans.com", "en", TypeSource.mangathemesia)), +// SourceModel(Source("DiskusScan", "https://diskusscan.com", "pt-BR", +// TypeSource.mangathemesia)), +// SourceModel(Source( +// "DuniaKomik", "https://duniakomik.id", "id", TypeSource.mangathemesia)), +// SourceModel(Source( +// "FlameScans", "https://flamescans.fr", "fr", TypeSource.mangathemesia)), +// SourceModel(Source("GremoryMangas", "https://gremorymangas.com", "es", +// TypeSource.mangathemesia)), +// SourceModel(Source("InfernalVoidScans", "https://void-scans.com", "en", +// TypeSource.mangathemesia)), +// SourceModel(Source("Kiryuu", "https://kiryuu.id", "id", TypeSource.mangathemesia)), +// SourceModel(Source( +// "KomikIndo", "https://komikindo.co", "id", TypeSource.mangathemesia)), +// SourceModel(Source( +// "KomikMama", "https://komikmama.co", "id", TypeSource.mangathemesia)), +// SourceModel(Source("Komiku", "https://komiku.com", "id", TypeSource.mangathemesia)), +// SourceModel(Source("KumaScans (Kuma Translation)", "https://kumascans.com", "en", +// TypeSource.mangathemesia)), +// SourceModel(Source( +// "MangaKita", "https://mangakita.net", "id", TypeSource.mangathemesia)), +// SourceModel(Source( +// "MangaTale", "https://mangatale.co", "id", TypeSource.mangathemesia)), +// SourceModel(Source( +// "MangaYaro", "https://mangayaro.net", "id", TypeSource.mangathemesia)), +// SourceModel(Source( +// "MangKomik", "https://mangkomik.net", "id", TypeSource.mangathemesia)), +// SourceModel(Source("MangásChan", "https://mangaschan.com", "pt-BR", +// TypeSource.mangathemesia)), +// SourceModel(Source( +// "ManhwaFreak", "https://manhwafreak.com", "en", TypeSource.mangathemesia)), +// SourceModel(Source( +// "ManhwaList", "https://manhwalist.in", "id", TypeSource.mangathemesia)), +// SourceModel(Source( +// "MasterKomik", "https://masterkomik.com", "id", TypeSource.mangathemesia)), +// SourceModel(Source("Nekomik", "https://nekomik.com", "id", TypeSource.mangathemesia)), +// SourceModel(Source("PhantomScans", "https://phantomscans.com", "en", +// TypeSource.mangathemesia)), +// SourceModel(Source("PhoenixFansub", "https://phoenixfansub.com", "es", +// TypeSource.mangathemesia)), +// SourceModel(Source("PiScans", "https://piscans.in", "id", TypeSource.mangathemesia)), +// SourceModel(Source( +// "Rawkuma", "https://rawkuma.com/", "ja", TypeSource.mangathemesia)), +// SourceModel(Source( +// "Readkomik", "https://readkomik.com", "en", TypeSource.mangathemesia)), +// SourceModel(Source( +// "SuryaScans", "https://suryascans.com", "en", TypeSource.mangathemesia)), +// SourceModel(Source( +// "SushiScan", "https://sushiscan.ru", "fr", TypeSource.mangathemesia)), +// SourceModel(Source("TsundokuTraduções", "https://tsundoku.com.br", "pt-BR", +// TypeSource.mangathemesia)), +// SourceModel(Source( +// "TukangKomik", "https://tukangkomik.id", "id", TypeSource.mangathemesia)), +// SourceModel(Source( +// "WestManga", "https://westmanga.info", "id", TypeSource.mangathemesia)), +// SourceModel(Source("xCaliBRScans", "https://xcalibrscans.com", "en", +// TypeSource.mangathemesia)), +// ]; diff --git a/lib/source/source_model.dart b/lib/source/source_model.dart new file mode 100644 index 00000000..1d61d370 --- /dev/null +++ b/lib/source/source_model.dart @@ -0,0 +1,78 @@ +import 'package:hive/hive.dart'; +part 'source_model.g.dart'; + +@HiveType(typeId: 3) +class SourceModel extends HiveObject { + @HiveField(0) + final String sourceName; + @HiveField(1) + final String url; + @HiveField(2) + final String lang; + @HiveField(3, defaultValue: true) + final bool isActive; + @HiveField(4, defaultValue: false) + final bool isAdded; + @HiveField(5, defaultValue: false) + final bool isNsfw; + @HiveField(6) + final TypeSource typeSource; + SourceModel({ + required this.sourceName, + required this.url, + required this.lang, + required this.typeSource, + this.isActive = true, + this.isAdded = false, + this.isNsfw = false, + }); +} + +@HiveType(typeId: 4) +enum TypeSource { + @HiveField(1) + single, + @HiveField(2) + mangathemesia, + @HiveField(3) + comick +} + +// @HiveType(typeId: 3) +// class SourceModel { +// @HiveField(0, defaultValue: true) +// final bool isActive; +// @HiveField(1) +// final Source source; +// @HiveField(2) +// SourceModel( +// this.source, { +// this.isActive = true, +// }); +// } + +// @HiveType(typeId: 4) +// class Source { +// @HiveField(0) +// final String sourceName; +// @HiveField(1) +// final String url; +// @HiveField(2) +// final String lang; +// @HiveField(3, defaultValue: true) +// final bool isActive; +// @HiveField(4, defaultValue: false) +// final bool isAdded; +// @HiveField(5, defaultValue: false) +// final bool isNsfw; +// final TypeSource typeSource; +// Source( +// this.sourceName, +// this.url, +// this.lang, +// this.typeSource, { +// this.isActive = true, +// this.isAdded = false, +// this.isNsfw = false, +// }); +// } diff --git a/lib/source/source_model.g.dart b/lib/source/source_model.g.dart new file mode 100644 index 00000000..57506e0d --- /dev/null +++ b/lib/source/source_model.g.dart @@ -0,0 +1,103 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'source_model.dart'; + +// ************************************************************************** +// TypeAdapterGenerator +// ************************************************************************** + +class SourceModelAdapter extends TypeAdapter { + @override + final int typeId = 3; + + @override + SourceModel read(BinaryReader reader) { + final numOfFields = reader.readByte(); + final fields = { + for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(), + }; + return SourceModel( + sourceName: fields[0] as String, + url: fields[1] as String, + lang: fields[2] as String, + typeSource: fields[6] as TypeSource, + isActive: fields[3] == null ? true : fields[3] as bool, + isAdded: fields[4] == null ? false : fields[4] as bool, + isNsfw: fields[5] == null ? false : fields[5] as bool, + ); + } + + @override + void write(BinaryWriter writer, SourceModel obj) { + writer + ..writeByte(7) + ..writeByte(0) + ..write(obj.sourceName) + ..writeByte(1) + ..write(obj.url) + ..writeByte(2) + ..write(obj.lang) + ..writeByte(3) + ..write(obj.isActive) + ..writeByte(4) + ..write(obj.isAdded) + ..writeByte(5) + ..write(obj.isNsfw) + ..writeByte(6) + ..write(obj.typeSource); + } + + @override + int get hashCode => typeId.hashCode; + + @override + bool operator ==(Object other) => + identical(this, other) || + other is SourceModelAdapter && + runtimeType == other.runtimeType && + typeId == other.typeId; +} + +class TypeSourceAdapter extends TypeAdapter { + @override + final int typeId = 4; + + @override + TypeSource read(BinaryReader reader) { + switch (reader.readByte()) { + case 1: + return TypeSource.single; + case 2: + return TypeSource.mangathemesia; + case 3: + return TypeSource.comick; + default: + return TypeSource.single; + } + } + + @override + void write(BinaryWriter writer, TypeSource obj) { + switch (obj) { + case TypeSource.single: + writer.writeByte(1); + break; + case TypeSource.mangathemesia: + writer.writeByte(2); + break; + case TypeSource.comick: + writer.writeByte(3); + break; + } + } + + @override + int get hashCode => typeId.hashCode; + + @override + bool operator ==(Object other) => + identical(this, other) || + other is TypeSourceAdapter && + runtimeType == other.runtimeType && + typeId == other.typeId; +} diff --git a/lib/utils/lang.dart b/lib/utils/lang.dart new file mode 100644 index 00000000..9aad0124 --- /dev/null +++ b/lib/utils/lang.dart @@ -0,0 +1,93 @@ +lang(String lang) { + if (lang == 'Français') { + return 'fr'; + } else if (lang == 'English') { + return 'en'; + } else if (lang == 'العربية') { + return 'ar'; + } else if (lang == 'Português') { + return 'pt'; + } else if (lang == 'Português do brasil') { + return 'pt-br'; + } else if (lang == 'Italiano') { + return 'it'; + } else if (lang == 'Pусский язык') { + return 'ru'; + } else if (lang == 'Español') { + return 'es'; + } else if (lang == 'Español latinoamericano') { + return 'es-419'; + } else if (lang == 'Bahasa Indonesia') { + return 'id'; + } else if (lang == 'हिन्दी, हिंदी') { + return 'hi'; + } else if (lang == 'Deutsch') { + return 'de'; + } else if (lang == '日本語') { + return 'ja'; + } else if (lang == 'Türkçe') { + return 'tr'; + } else if (lang == 'Polski') { + return 'pl'; + } else if (lang == '中文') { + return 'zh'; + } else if (lang == '(Hong Kong) 繁體中文') { + return 'zh-hk'; + } +} + +completeLang(String lang) { + if (lang == 'fr') { + return 'Français'; + } else if (lang == 'en') { + return 'English'; + } else if (lang == 'ar') { + return 'العربية'; + } else if (lang == 'pt') { + return 'Português'; + } else if (lang == 'pt-br') { + return 'Português do brasil'; + } else if (lang == 'it') { + return 'Italiano'; + } else if (lang == 'ru') { + return 'Pусский язык'; + } else if (lang == 'es') { + return 'Español'; + } else if (lang == 'es-419') { + return 'Español latinoamericano'; + } else if (lang == 'id') { + return 'Bahasa Indonesia'; + } else if (lang == 'hi') { + return 'हिन्दी, हिंदी'; + } else if (lang == 'de') { + return 'Deutsch'; + } else if (lang == 'ja') { + return '日本語'; + } else if (lang == 'tr') { + return 'Türkçe'; + } else if (lang == 'pl') { + return 'Polski'; + } else if (lang == 'zh') { + return '中文'; + } else if (lang == 'zh-hk') { + return '(Hong Kong) 繁體中文'; + } +} + + final List language = [ + "Français", + "English", + "العربية", + 'Português', + 'Português do brasil', + 'Italiano', + 'Pусский язык', + 'Español', + 'Español latinoamericano', + 'Bahasa Indonesia', + 'हिन्दी, हिंदी', + '日本語', + 'Deutsch', + '中文', + '(Hong Kong) 繁體中文' + ]; \ No newline at end of file diff --git a/lib/views/browse/browse_screen.dart b/lib/views/browse/browse_screen.dart index 54a8774e..e2d2671b 100644 --- a/lib/views/browse/browse_screen.dart +++ b/lib/views/browse/browse_screen.dart @@ -1,12 +1,30 @@ -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:mangayomi/views/browse/extension.dart'; +import 'package:go_router/go_router.dart'; +import 'package:mangayomi/views/browse/extension/extension.dart'; import 'package:mangayomi/views/browse/migrate.dart'; import 'package:mangayomi/views/browse/sources.dart'; -class BrowseScreen extends StatelessWidget { +class BrowseScreen extends StatefulWidget { const BrowseScreen({super.key}); + @override + State createState() => _BrowseScreenState(); +} + +class _BrowseScreenState extends State + with TickerProviderStateMixin { + late TabController _tabBarController; + + @override + void initState() { + _tabBarController = TabController(length: 3, vsync: this); + _tabBarController.animateTo(0); + _tabBarController.addListener(() { + setState(() {}); + }); + super.initState(); + } + @override Widget build(BuildContext context) { return DefaultTabController( @@ -20,19 +38,33 @@ class BrowseScreen extends StatelessWidget { style: TextStyle(color: Theme.of(context).hintColor), ), actions: [ + if (_tabBarController.index != 2) + IconButton( + splashRadius: 20, + onPressed: () {}, + icon: Icon( + _tabBarController.index == 0 + ? Icons.travel_explore_rounded + : Icons.search_rounded, + color: Theme.of(context).hintColor)), IconButton( splashRadius: 20, - onPressed: () {}, - icon: Icon(Icons.travel_explore, - color: Theme.of(context).hintColor)), - IconButton( - splashRadius: 20, - onPressed: () {}, - icon: Icon(Icons.filter_list_sharp, + onPressed: () { + if (_tabBarController.index == 0) { + } else if (_tabBarController.index == 1) { + context.push('/extensionLang'); + } else {} + }, + icon: Icon( + _tabBarController.index == 0 + ? Icons.filter_list_sharp + : _tabBarController.index == 1 + ? Icons.translate_rounded + : Icons.help_outline_outlined, color: Theme.of(context).hintColor)), ], bottom: TabBar( - labelColor: Theme.of(context).hintColor, + controller: _tabBarController, isScrollable: true, tabs: const [ Tab(text: "Sources"), @@ -41,8 +73,11 @@ class BrowseScreen extends StatelessWidget { ], ), ), - body: const TabBarView( - children: [SourcesScreen(), ExtensionScreen(), MigrateScreen()]), + body: TabBarView(controller: _tabBarController, children: [ + SourcesScreen(), + ExtensionScreen(), + MigrateScreen() + ]), ), ); } diff --git a/lib/views/browse/extension.dart b/lib/views/browse/extension.dart deleted file mode 100644 index 5fb783da..00000000 --- a/lib/views/browse/extension.dart +++ /dev/null @@ -1,30 +0,0 @@ -import 'package:flutter/material.dart'; - -class ExtensionScreen extends StatefulWidget { - const ExtensionScreen({super.key}); - - @override - State createState() => _ExtensionScreenState(); -} - -class _ExtensionScreenState extends State { - @override - Widget build(BuildContext context) { - return Column( - children: [ - ListTile( - onTap: () {}, - leading: Container( - height: 37, - width: 37, - decoration: BoxDecoration( - color: Colors.grey, borderRadius: BorderRadius.circular(5)), - ), - subtitle: const Text('English'), - title: const Text('MangaHere'), - trailing: TextButton(onPressed: () {}, child: Text("Update")), - ) - ], - ); - } -} diff --git a/lib/views/browse/extension/extension.dart b/lib/views/browse/extension/extension.dart new file mode 100644 index 00000000..b4c550f8 --- /dev/null +++ b/lib/views/browse/extension/extension.dart @@ -0,0 +1,82 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:grouped_list/grouped_list.dart'; +import 'package:hive_flutter/hive_flutter.dart'; +import 'package:mangayomi/providers/hive_provider.dart'; +import 'package:mangayomi/source/source_list.dart'; +import 'package:mangayomi/source/source_model.dart'; +import 'package:mangayomi/utils/lang.dart'; +import 'package:mangayomi/views/browse/extension/widgets/extension_list_tile_widget.dart'; + +class ExtensionScreen extends ConsumerStatefulWidget { + const ExtensionScreen({super.key}); + + @override + ConsumerState createState() => _ExtensionScreenState(); +} + +class _ExtensionScreenState extends ConsumerState { + _init() { + for (var element in sourcesList) { + if (!ref + .watch(hiveBoxMangaSourceProvider) + .containsKey("${element.sourceName}${element.lang}")) { + ref + .watch(hiveBoxMangaSourceProvider) + .put("${element.sourceName}${element.lang}", element); + } + } + _isLoading = false; + } + + bool _isLoading = true; + @override + Widget build( + BuildContext context, + ) { + _init(); + return _isLoading + ? Container() + : ValueListenableBuilder>( + valueListenable: ref.watch(hiveBoxMangaSourceProvider).listenable(), + builder: (context, value, child) { + final entries = value.values.toList(); + return GroupedListView( + elements: entries, + groupBy: (element) => element.lang, + groupSeparatorBuilder: (String groupByValue) => Padding( + padding: const EdgeInsets.only(bottom: 8, left: 8), + child: Row( + children: [ + Text( + completeLang(groupByValue.toLowerCase()), + style: const TextStyle(fontWeight: FontWeight.bold), + ), + ], + ), + ), + itemBuilder: (context, SourceModel element) { + final source = + value.get("${element.sourceName}${element.lang}")!; + return ExtensionListTileWidget( + lang: + value.get("${element.sourceName}${element.lang}")!.lang, + onChanged: (val) { + value.put( + "${element.sourceName}${element.lang}", + SourceModel( + sourceName: element.sourceName, + url: element.url, + lang: element.lang, + typeSource: element.typeSource, + isAdded: val)); + }, + sourceName: source.sourceName, + value: source.isAdded, + ); + }, + order: GroupedListOrder.ASC, + ); + }); + } +} diff --git a/lib/views/browse/extension/extension_lang.dart b/lib/views/browse/extension/extension_lang.dart new file mode 100644 index 00000000..c1cb0535 --- /dev/null +++ b/lib/views/browse/extension/extension_lang.dart @@ -0,0 +1,44 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:hive_flutter/hive_flutter.dart'; +import 'package:mangayomi/providers/hive_provider.dart'; +import 'package:mangayomi/utils/lang.dart'; +import 'package:mangayomi/views/browse/extension/widgets/extension_lang_list_tile_widget.dart'; + +class ExtensionsLang extends ConsumerWidget { + const ExtensionsLang({super.key}); + + @override + Widget build(BuildContext context, WidgetRef ref) { + return Scaffold( + appBar: AppBar( + title: const Text("Extensions"), + ), + body: ValueListenableBuilder>( + valueListenable: ref.watch(hiveBoxMangaFilterProvider).listenable(), + builder: (context, value, child) { + List entries = + value.get("language_filter", defaultValue: []); + + return ListView.builder( + itemCount: language.length, + itemBuilder: (context, index) { + return ExtensionLangListTileWidget( + lang: lang(language[index]), + onChanged: (val) { + if (val == true) { + entries.add("${lang(language[index])}_"); + value.put("language_filter", entries); + } else { + entries.remove("${lang(language[index])}_"); + value.put("language_filter", entries); + } + }, + value: entries.contains("${lang(language[index])}_"), + ); + }, + ); + })); + ; + } +} diff --git a/lib/views/browse/extension/widgets/extension_lang_list_tile_widget.dart b/lib/views/browse/extension/widgets/extension_lang_list_tile_widget.dart new file mode 100644 index 00000000..040cb985 --- /dev/null +++ b/lib/views/browse/extension/widgets/extension_lang_list_tile_widget.dart @@ -0,0 +1,27 @@ +import 'package:flutter/material.dart'; +import 'package:mangayomi/utils/lang.dart'; + +class ExtensionLangListTileWidget extends StatelessWidget { + final String lang; + final bool value; + final Function(bool) onChanged; + const ExtensionLangListTileWidget( + {super.key, + required this.lang, + required this.value, + required this.onChanged}); + + @override + Widget build(BuildContext context) { + return ListTile( + onTap: () { + onChanged(!value); + }, + title: Text(completeLang(lang.toLowerCase())), + trailing: Switch( + value: value, + onChanged: (value) { + onChanged(value); + })); + } +} diff --git a/lib/views/browse/extension/widgets/extension_list_tile_widget.dart b/lib/views/browse/extension/widgets/extension_list_tile_widget.dart new file mode 100644 index 00000000..4a1bf7da --- /dev/null +++ b/lib/views/browse/extension/widgets/extension_list_tile_widget.dart @@ -0,0 +1,39 @@ +import 'package:flutter/material.dart'; +import 'package:mangayomi/utils/lang.dart'; + +class ExtensionListTileWidget extends StatelessWidget { + final String sourceName; + final String lang; + final bool value; + final Function(bool) onChanged; + const ExtensionListTileWidget( + {super.key, + required this.sourceName, + required this.lang, + required this.value, + required this.onChanged}); + + @override + Widget build(BuildContext context) { + return ListTile( + onTap: () { + onChanged(!value); + }, + leading: Container( + height: 37, + width: 37, + decoration: BoxDecoration( + color: Theme.of(context).secondaryHeaderColor, + borderRadius: BorderRadius.circular(5)), + child: const Icon(Icons.source_outlined), + ), + title: Text(sourceName), + subtitle: Text(completeLang(lang.toLowerCase())), + trailing: Switch( + value: value, + onChanged: (value) { + onChanged(value); + })); + ; + } +} diff --git a/lib/views/browse/sources.dart b/lib/views/browse/sources.dart index 27beb4fb..519e394b 100644 --- a/lib/views/browse/sources.dart +++ b/lib/views/browse/sources.dart @@ -1,50 +1,131 @@ import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; +import 'package:grouped_list/grouped_list.dart'; +import 'package:hive_flutter/hive_flutter.dart'; import 'package:mangayomi/models/manga_type.dart'; +import 'package:mangayomi/providers/hive_provider.dart'; +import 'package:mangayomi/source/source_list.dart'; +import 'package:mangayomi/source/source_model.dart'; +import 'package:mangayomi/utils/lang.dart'; -class SourcesScreen extends StatefulWidget { +// class SourcesScreen extends StatefulWidget { +// const SourcesScreen({super.key}); + +// @override +// State createState() => _SourcesScreenState(); +// } + +// class _SourcesScreenState extends State { +// @override +// Widget build(BuildContext context) { +// return Column( +// children: [ +// ListTile( +// onTap: () { +// context.push('/mangaHome', +// extra: MangaType( +// isFullData: true, lang: 'en', source: 'MangaHere')); +// }, +// leading: Container( +// height: 37, +// width: 37, +// decoration: BoxDecoration( +// color: Colors.grey, borderRadius: BorderRadius.circular(5)), +// ), +// subtitle: const Text('English'), +// title: const Text('MangaHere'), +// trailing: SizedBox( +// width: 110, +// child: Row( +// mainAxisAlignment: MainAxisAlignment.spaceAround, +// children: const [ +// Text( +// "Latest", +// style: TextStyle(fontWeight: FontWeight.bold), +// ), +// Icon( +// Icons.push_pin_outlined, +// color: Colors.black, +// ) +// ], +// )), +// ) +// ], +// ); +// } +// } + +class SourcesScreen extends ConsumerStatefulWidget { const SourcesScreen({super.key}); @override - State createState() => _SourcesScreenState(); + ConsumerState createState() => _SourcesScreenState(); } -class _SourcesScreenState extends State { +class _SourcesScreenState extends ConsumerState { @override - Widget build(BuildContext context) { - return Column( - children: [ - ListTile( - onTap: () { - context.push('/mangaHome', - extra: MangaType( - isFullData: true, lang: 'en', source: 'MangaHere')); - }, - leading: Container( - height: 37, - width: 37, - decoration: BoxDecoration( - color: Colors.grey, borderRadius: BorderRadius.circular(5)), - ), - subtitle: const Text('English'), - title: const Text('MangaHere'), - trailing: SizedBox( - width: 110, + Widget build( + BuildContext context, + ) { + return ValueListenableBuilder>( + valueListenable: ref.watch(hiveBoxMangaSourceProvider).listenable(), + builder: (context, value, child) { + final entries = + value.values.where((element) => element.isAdded == true).toList(); + if (entries.isEmpty) { + return const Center(child: Text("Empty")); + } + return GroupedListView( + elements: entries, + groupBy: (element) => element.lang, + groupSeparatorBuilder: (String groupByValue) => Padding( + padding: const EdgeInsets.only(bottom: 8, left: 8), child: Row( - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: const [ + children: [ Text( - "Latest", - style: TextStyle(fontWeight: FontWeight.bold), + completeLang(groupByValue.toLowerCase()), + style: const TextStyle(fontWeight: FontWeight.bold), ), - Icon( - Icons.push_pin_outlined, - color: Colors.black, - ) ], - )), - ) - ], - ); + ), + ), + itemBuilder: (context, SourceModel element) { + final source = value.get("${element.sourceName}${element.lang}")!; + return ListTile( + onTap: () { + if (source.sourceName == 'MangaHere') { + context.push('/mangaHome', + extra: MangaType( + isFullData: true, lang: 'en', source: 'MangaHere')); + } + }, + leading: Container( + height: 37, + width: 37, + decoration: BoxDecoration( + color: Theme.of(context).secondaryHeaderColor, + borderRadius: BorderRadius.circular(5)), + child: const Icon(Icons.source_outlined), + ), + subtitle: Text(completeLang(source.lang)), + title: Text(source.sourceName), + trailing: SizedBox( + width: 110, + child: Row( + mainAxisAlignment: MainAxisAlignment.end, + children: const [ + Icon( + Icons.push_pin_outlined, + color: Colors.black, + ) + ], + )), + ); + }, + sort: true, + order: GroupedListOrder.ASC, + ); + }); } } diff --git a/lib/views/general/general_screen.dart b/lib/views/general/general_screen.dart index da54f9e3..76563a27 100644 --- a/lib/views/general/general_screen.dart +++ b/lib/views/general/general_screen.dart @@ -1,8 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; -import 'package:hidable/hidable.dart'; -import 'package:mangayomi/views/general/scroll_controller_provider.dart'; import 'package:mangayomi/utils/media_query.dart'; class GeneralScreen extends ConsumerStatefulWidget { diff --git a/lib/views/general/scroll_controller_provider.dart b/lib/views/general/scroll_controller_provider.dart deleted file mode 100644 index 69c45277..00000000 --- a/lib/views/general/scroll_controller_provider.dart +++ /dev/null @@ -1,5 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; - -final scrollControllerProvider = - Provider((ref) => ScrollController()); diff --git a/lib/views/library/library_screen.dart b/lib/views/library/library_screen.dart index 7558f8e9..1cabecc6 100644 --- a/lib/views/library/library_screen.dart +++ b/lib/views/library/library_screen.dart @@ -5,7 +5,6 @@ import 'package:hive_flutter/hive_flutter.dart'; import 'package:mangayomi/models/model_manga.dart'; import 'package:mangayomi/providers/hive_provider.dart'; import 'package:mangayomi/utils/cached_network.dart'; -import 'package:mangayomi/views/general/scroll_controller_provider.dart'; import 'package:mangayomi/views/widgets/bottom_text_widget.dart'; import 'package:mangayomi/views/widgets/cover_view_widget.dart'; import 'package:mangayomi/views/widgets/gridview_widget.dart'; @@ -24,7 +23,6 @@ class _LibraryScreenState extends ConsumerState { final _textEditingController = TextEditingController(); @override Widget build(BuildContext context) { - final scrollController = ref.watch(scrollControllerProvider); return Scaffold( appBar: AppBar( elevation: 0, @@ -108,90 +106,52 @@ class _LibraryScreenState extends ConsumerState { }), ], ), - body: _textEditingController.text.isNotEmpty - ? GridViewWidget( - controller: scrollController, - itemCount: entriesFilter.length, + body: ValueListenableBuilder>( + valueListenable: ref.watch(hiveBoxManga).listenable(), + builder: (context, value, child) { + entries = value.values.where((element) => element.favorite).toList(); + final entriesManga = + _textEditingController.text.isNotEmpty ? entriesFilter : entries; + if (entries.isNotEmpty || entriesFilter.isNotEmpty) { + return GridViewWidget( + itemCount: entriesManga.length, itemBuilder: (context, index) { return GestureDetector( onTap: () { final model = ModelManga( - imageUrl: entriesFilter[index].imageUrl, - name: entriesFilter[index].name, - genre: entriesFilter[index].genre, - author: entriesFilter[index].author, - status: entriesFilter[index].status, - chapterDate: entriesFilter[index].chapterDate, - chapterTitle: entriesFilter[index].chapterTitle, - chapterUrl: entriesFilter[index].chapterUrl, - description: entriesFilter[index].description, - favorite: entriesFilter[index].favorite, - link: entriesFilter[index].link, - source: entriesFilter[index].source, - lang: entriesFilter[index].lang); + imageUrl: entriesManga[index].imageUrl, + name: entriesManga[index].name, + genre: entriesManga[index].genre, + author: entriesManga[index].author, + status: entriesManga[index].status, + chapterDate: entriesManga[index].chapterDate, + chapterTitle: entriesManga[index].chapterTitle, + chapterUrl: entriesManga[index].chapterUrl, + description: entriesManga[index].description, + favorite: entriesManga[index].favorite, + link: entriesManga[index].link, + source: entriesManga[index].source, + lang: entriesManga[index].lang); context.push('/manga-reader/detail', extra: model); }, child: CoverViewWidget( children: [ cachedNetworkImage( - imageUrl: entriesFilter[index].imageUrl!, + imageUrl: entriesManga[index].imageUrl!, width: 200, height: 270, fit: BoxFit.cover), - BottomTextWidget(text: entriesFilter[index].name!) + BottomTextWidget(text: entriesManga[index].name!) ], ), ); }, - ) - : ValueListenableBuilder>( - valueListenable: ref.watch(hiveBoxManga).listenable(), - builder: (context, value, child) { - entries = - value.values.where((element) => element.favorite).toList(); - - if (entries.isNotEmpty) { - return GridViewWidget( - controller: scrollController, - itemCount: entries.length, - itemBuilder: (context, index) { - return GestureDetector( - onTap: () { - final model = ModelManga( - imageUrl: entries[index].imageUrl, - name: entries[index].name, - genre: entries[index].genre, - author: entries[index].author, - status: entries[index].status, - chapterDate: entries[index].chapterDate, - chapterTitle: entries[index].chapterTitle, - chapterUrl: entries[index].chapterUrl, - description: entries[index].description, - favorite: entries[index].favorite, - link: entries[index].link, - source: entries[index].source, - lang: entries[index].lang); - - context.push('/manga-reader/detail', extra: model); - }, - child: CoverViewWidget( - children: [ - cachedNetworkImage( - imageUrl: entries[index].imageUrl!, - width: 200, - height: 270, - fit: BoxFit.cover), - BottomTextWidget(text: entries[index].name!) - ], - ), - ); - }, - ); - } - return const Center(child: Text("Empty Library")); - }, - ), + ); + } + return const Center(child: Text("Empty Library")); + }, + ), ); } } diff --git a/lib/views/manga/detail/manga_detail_view.dart b/lib/views/manga/detail/manga_detail_view.dart index f7b29d59..395fb965 100644 --- a/lib/views/manga/detail/manga_detail_view.dart +++ b/lib/views/manga/detail/manga_detail_view.dart @@ -116,6 +116,7 @@ class _MangaDetailViewState extends ConsumerState { _listView() { return DraggableScrollbar.rrect( + alwaysVisibleScrollThumb: true, controller: _scrollController, child: ListView.builder( controller: _scrollController, @@ -135,14 +136,17 @@ class _MangaDetailViewState extends ConsumerState { modelManga: widget.modelManga!, index: finalIndex); }, - trailing: const Icon(FontAwesomeIcons.circleDown), + trailing: const Icon( + FontAwesomeIcons.circleDown, + size: 20, + ), subtitle: Text( widget.modelManga!.chapterDate![finalIndex], - style: const TextStyle(fontSize: 13), + style: const TextStyle(fontSize: 12), ), title: Text( widget.modelManga!.chapterTitle![finalIndex], - style: const TextStyle(fontSize: 15), + style: const TextStyle(fontSize: 13), ), ); })); @@ -170,7 +174,7 @@ class _MangaDetailViewState extends ConsumerState { Column( children: [ SizedBox( - height: AppBar().preferredSize.height, + height: AppBar().preferredSize.height * 1.5, ), SizedBox( height: 180, @@ -236,7 +240,7 @@ class _MangaDetailViewState extends ConsumerState { padding: const EdgeInsets.symmetric(horizontal: 8), child: Text( - '${widget.modelManga!.chapterTitle!.length.toString()} chapter(s)', + '${widget.modelManga!.chapterTitle!.length.toString()} chapters', style: const TextStyle( fontWeight: FontWeight.bold), ), diff --git a/lib/views/more/more_screen.dart b/lib/views/more/more_screen.dart index aa33b8ba..07ac5a25 100644 --- a/lib/views/more/more_screen.dart +++ b/lib/views/more/more_screen.dart @@ -14,9 +14,10 @@ class MoreScreen extends StatelessWidget { flex: 3, child: Column( children: [ - const Divider(), + const Divider( + color: Colors.grey, + ), ListTile( - dense: true, onTap: () {}, leading: const SizedBox(height: 40, child: Icon(Icons.cloud_off)), @@ -28,7 +29,6 @@ class MoreScreen extends StatelessWidget { ), ), ListTile( - dense: true, onTap: () {}, leading: const SizedBox( height: 40, child: Icon(CupertinoIcons.eyeglasses)), @@ -39,16 +39,16 @@ class MoreScreen extends StatelessWidget { onChanged: (value) {}, ), ), - const Divider(), + const Divider( + color: Colors.grey, + ), ListTile( - dense: true, onTap: () {}, leading: const SizedBox( height: 40, child: Icon(Icons.download_outlined)), title: const Text('Donwload queue'), ), ListTile( - dense: true, onTap: () {}, leading: Container( height: 20, @@ -58,7 +58,6 @@ class MoreScreen extends StatelessWidget { title: const Text('Categories'), ), ListTile( - dense: true, onTap: () {}, leading: Container( height: 20, @@ -68,30 +67,28 @@ class MoreScreen extends StatelessWidget { title: const Text('Statistics'), ), ListTile( - dense: true, onTap: () {}, leading: const SizedBox( height: 40, child: Icon(Icons.settings_backup_restore_sharp)), title: const Text('Backup and restore'), ), - const Divider(), + const Divider( + color: Colors.grey, + ), ListTile( - dense: true, onTap: () {}, leading: const SizedBox( height: 40, child: Icon(Icons.settings_outlined)), title: const Text('Backup and restore'), ), ListTile( - dense: true, onTap: () {}, leading: const SizedBox( height: 40, child: Icon(Icons.info_outline)), title: const Text('About'), ), ListTile( - dense: true, onTap: () {}, leading: const SizedBox( height: 40, child: Icon(Icons.help_outline)), diff --git a/lib/views/widgets/bottom_text_widget.dart b/lib/views/widgets/bottom_text_widget.dart index 83dde598..15bf8778 100644 --- a/lib/views/widgets/bottom_text_widget.dart +++ b/lib/views/widgets/bottom_text_widget.dart @@ -12,12 +12,13 @@ class BottomTextWidget extends StatelessWidget { right: 0, child: Container( decoration: BoxDecoration( - boxShadow: [ - BoxShadow( - color: Colors.black.withOpacity(0.3), //New - offset: const Offset(0.5, 0.9), - blurRadius: 3.0) - ], + color: Theme.of(context).scaffoldBackgroundColor, + gradient: LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: [Colors.transparent, Colors.black.withOpacity(0.4)], + stops: const [0, 1], + ), ), child: Text( text, diff --git a/pubspec.lock b/pubspec.lock index ef651206..2eca6a09 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -432,14 +432,6 @@ packages: url: "https://pub.dev" source: hosted version: "5.1.2" - hidable: - dependency: "direct main" - description: - name: hidable - sha256: abe6f3ce1037a8de18e996d1e6417306949217010daea56799d6203a9d8f1c48 - url: "https://pub.dev" - source: hosted - version: "1.0.3" hive: dependency: "direct main" description: