diff --git a/lib/eval/m_bridge.dart b/lib/eval/m_bridge.dart index 103e393..9a8ff80 100644 --- a/lib/eval/m_bridge.dart +++ b/lib/eval/m_bridge.dart @@ -8,6 +8,7 @@ import 'package:desktop_webview_window/desktop_webview_window.dart'; import 'package:flutter/material.dart'; import 'package:flutter_inappwebview/flutter_inappwebview.dart'; import 'package:flutter_js/flutter_js.dart'; +import 'package:intl/date_symbol_data_local.dart'; import 'package:intl/intl.dart'; import 'package:json_path/json_path.dart'; import 'package:mangayomi/main.dart'; @@ -403,8 +404,6 @@ class MBridge { for (var date in val) { if (date.toString().isNotEmpty) { valD.add(parseChapterDate(date, dateFormat, dateFormatLocale)); - } else { - valD.add(""); } } return valD; @@ -589,12 +588,94 @@ class MBridge { .toString(); } } catch (e) { + final supportedLocales = DateFormat.allLocalesWithSymbols(); + + for (var locale in supportedLocales) { + for (var dateFormat in _dateFormats) { + try { + initializeDateFormatting(locale); + if (WordSet(["yesterday", "يوم واحد"]).startsWith(date)) { + DateTime cal = DateTime.now().subtract(const Duration(days: 1)); + cal = DateTime(cal.year, cal.month, cal.day); + return cal.millisecondsSinceEpoch.toString(); + } else if (WordSet(["today"]).startsWith(date)) { + DateTime cal = DateTime.now(); + cal = DateTime(cal.year, cal.month, cal.day); + return cal.millisecondsSinceEpoch.toString(); + } else if (WordSet(["يومين"]).startsWith(date)) { + DateTime cal = DateTime.now().subtract(const Duration(days: 2)); + cal = DateTime(cal.year, cal.month, cal.day); + return cal.millisecondsSinceEpoch.toString(); + } else if (WordSet(["ago", "atrás", "önce", "قبل"]) + .endsWith(date)) { + return parseRelativeDate(date).toString(); + } else if (WordSet(["hace"]).startsWith(date)) { + return parseRelativeDate(date).toString(); + } else if (date.contains(RegExp(r"\d(st|nd|rd|th)"))) { + final cleanedDate = date + .split(" ") + .map((it) => it.contains(RegExp(r"\d\D\D")) + ? it.replaceAll(RegExp(r"\D"), "") + : it) + .join(" "); + return DateFormat(dateFormat, locale) + .parse(cleanedDate) + .millisecondsSinceEpoch + .toString(); + } else { + return DateFormat(dateFormat, locale) + .parse(date) + .millisecondsSinceEpoch + .toString(); + } + } catch (_) {} + } + } _botToast(e.toString()); throw Exception(e); } } } +final List _dateFormats = [ + 'dd/MM/yyyy', + 'MM/dd/yyyy', + 'yyyy/MM/dd', + 'dd-MM-yyyy', + 'MM-dd-yyyy', + 'yyyy-MM-dd', + 'dd.MM.yyyy', + 'MM.dd.yyyy', + 'yyyy.MM.dd', + 'dd MMMM yyyy', + 'MMMM dd, yyyy', + 'yyyy MMMM dd', + 'dd MMM yyyy', + 'MMM dd yyyy', + 'yyyy MMM dd', + 'dd MMMM, yyyy', + 'yyyy, MMMM dd', + 'MMMM dd yyyy', + 'MMM dd, yyyy', + 'dd LLLL yyyy', + 'LLLL dd, yyyy', + 'yyyy LLLL dd', + 'LLLL dd yyyy', + "MMMMM dd, yyyy", + "MMM d, yyy", + "MMM d, yyyy", + "dd/mm/yyyy", + "d MMMM yyyy", + "dd 'de' MMMM 'de' yyyy", + "d MMMM'،' yyyy", + "yyyy'年'M'月'd", + "d MMMM, yyyy", + "dd 'de' MMMMM 'de' yyyy", + "dd MMMMM, yyyy", + "MMMM d, yyyy", + "MMM dd,yyyy" +]; + class $MBridge extends MBridge with $Bridge { static const $type = BridgeTypeRef( BridgeTypeSpec('package:bridge_lib/bridge_lib.dart', 'MBridge')); diff --git a/lib/main.dart b/lib/main.dart index a1791db..b110dc7 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -6,6 +6,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:intl/date_symbol_data_local.dart'; +import 'package:intl/intl.dart'; import 'package:isar/isar.dart'; import 'package:mangayomi/providers/storage_provider.dart'; import 'package:mangayomi/router/router.dart'; @@ -40,21 +41,11 @@ void main(List args) async { } _iniDateFormatting() { - initializeDateFormatting("en", null); - initializeDateFormatting("fr", null); - initializeDateFormatting("ar", null); - initializeDateFormatting("es", null); - initializeDateFormatting("pt", null); - initializeDateFormatting("ru", null); - initializeDateFormatting("hi", null); - initializeDateFormatting("id", null); - initializeDateFormatting("it", null); - initializeDateFormatting("de", null); - initializeDateFormatting("ja", null); - initializeDateFormatting("zh", null); - initializeDateFormatting("pl", null); - initializeDateFormatting("tr", null); - initializeDateFormatting("bg", null); + initializeDateFormatting(); + final supportedLocales = DateFormat.allLocalesWithSymbols(); + for (var locale in supportedLocales) { + initializeDateFormatting(locale); + } } class MyApp extends ConsumerStatefulWidget { diff --git a/lib/modules/manga/detail/providers/update_manga_detail_providers.dart b/lib/modules/manga/detail/providers/update_manga_detail_providers.dart index 5202aff..8183a6d 100644 --- a/lib/modules/manga/detail/providers/update_manga_detail_providers.dart +++ b/lib/modules/manga/detail/providers/update_manga_detail_providers.dart @@ -26,20 +26,40 @@ Future updateMangaDetail(UpdateMangaDetailRef ref, dateFormatLocale: source.dateFormatLocale); final getManga = await ref .watch(getMangaDetailProvider(manga: mangaS, source: source).future); + final imageUrl = getManga.imageUrl != null && getManga.imageUrl!.isNotEmpty + ? getManga.imageUrl + : manga.imageUrl ?? ""; + final name = getManga.name != null && getManga.name!.isNotEmpty + ? getManga.name!.trim().trimLeft().trimRight() + : manga.name ?? ""; + final genre = getManga.genre != null && getManga.genre!.isNotEmpty + ? getManga.genre! + .map((e) => e.toString().trim().trimLeft().trimRight()) + .toList() + .toSet() + .toList() + : manga.genre ?? []; + final author = getManga.author != null && getManga.author!.isNotEmpty + ? getManga.author!.trim().trimLeft().trimRight() + : manga.author ?? ""; + final description = + getManga.description != null && getManga.description!.isNotEmpty + ? getManga.description!.trim().trimLeft().trimRight() + : manga.description ?? ""; + final link = getManga.link != null && getManga.link!.isNotEmpty + ? getManga.link!.trim().trimLeft().trimRight() + : manga.link ?? ""; + final sourceA = getManga.source != null && getManga.source!.isNotEmpty + ? getManga.source!.trim().trimLeft().trimRight() + : manga.source ?? ""; + final lang = getManga.lang != null && getManga.lang!.isNotEmpty + ? getManga.lang!.trim().trimLeft().trimRight() + : manga.lang ?? ""; manga - ..imageUrl = - getManga.imageUrl!.isEmpty ? manga.imageUrl ?? "" : getManga.imageUrl - ..name = getManga.name!.isEmpty - ? manga.name ?? "" - : getManga.name!.trim().trimLeft().trimRight() - ..genre = getManga.genre!.isEmpty - ? manga.genre ?? [] - : getManga.genre! - .map((e) => e.toString().trim().trimLeft().trimRight()) - .toList() - ..author = getManga.author!.isEmpty - ? manga.author ?? "" - : getManga.author!.trim().trimLeft().trimRight() + ..imageUrl = imageUrl + ..name = name + ..genre = genre + ..author = author ..status = switch (getManga.status) { 0 => Status.ongoing, 1 => Status.completed, @@ -48,12 +68,10 @@ Future updateMangaDetail(UpdateMangaDetailRef ref, 4 => Status.publishingFinished, _ => Status.unknown, } - ..description = getManga.description!.isEmpty - ? manga.description ?? "" - : getManga.description!.trim().trimLeft().trimRight() - ..link = getManga.link!.isEmpty ? manga.link ?? "" : getManga.link - ..source = getManga.source!.isEmpty ? manga.source ?? "" : getManga.source - ..lang = getManga.lang!.isEmpty ? manga.lang ?? "" : getManga.lang + ..description = description + ..link = link + ..source = sourceA + ..lang = lang ..lastUpdate = DateTime.now().millisecondsSinceEpoch; isar.writeTxnSync(() { diff --git a/lib/modules/widgets/manga_image_card_widget.dart b/lib/modules/widgets/manga_image_card_widget.dart index 0bd6109..3a33f01 100644 --- a/lib/modules/widgets/manga_image_card_widget.dart +++ b/lib/modules/widgets/manga_image_card_widget.dart @@ -32,7 +32,6 @@ class MangaImageCardWidget extends ConsumerWidget { .langEqualTo(lang) .nameEqualTo(getMangaDetail!.name) .sourceEqualTo(getMangaDetail!.source) - .favoriteEqualTo(true) .watch(fireImmediately: true), builder: (context, snapshot) { return CoverViewWidget( @@ -43,7 +42,11 @@ class MangaImageCardWidget extends ConsumerWidget { snapshot.data!.first.customCoverImage as Uint8List) as ImageProvider : CachedNetworkImageProvider( - getMangaDetail!.imageUrl!, + snapshot.hasData && + snapshot.data!.isNotEmpty && + snapshot.data!.first.imageUrl != null + ? snapshot.data!.first.imageUrl! + : getMangaDetail!.imageUrl!, headers: ref.watch(headersProvider( source: getMangaDetail!.source!, lang: getMangaDetail!.lang!)), @@ -54,11 +57,15 @@ class MangaImageCardWidget extends ConsumerWidget { }, children: [ Container( - color: snapshot.hasData && snapshot.data!.isNotEmpty + color: snapshot.hasData && + snapshot.data!.isNotEmpty && + snapshot.data!.first.favorite ? Colors.black.withOpacity(0.7) : null, ), - if (snapshot.hasData && snapshot.data!.isNotEmpty) + if (snapshot.hasData && + snapshot.data!.isNotEmpty && + snapshot.data!.first.favorite) Positioned( top: 0, left: 0, @@ -169,4 +176,3 @@ void pushToMangaReaderDetail( context.push('/manga-reader/detail', extra: mangaId); } - diff --git a/pubspec.yaml b/pubspec.yaml index 7321220..0dfe5bd 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # In Windows, build-name is used as the major, minor, and patch parts # of the product and file versions while build-number is used as the build suffix. -version: 0.0.15+4 +version: 0.0.2+5 environment: sdk: '>=3.0.0 <4.0.0'