diff --git a/lib/constants/shared_preferences_keys.dart b/lib/constants/shared_preferences_keys.dart index 43a1075..9355ea4 100644 --- a/lib/constants/shared_preferences_keys.dart +++ b/lib/constants/shared_preferences_keys.dart @@ -4,4 +4,5 @@ class SharedPreferencesKeys { static const useDynamicTheme = "useDynamicTheme"; static const selectedColor = "selectedColor"; static const useInAppBrowser = "useInAppBrowser"; + static const showFavicon = "showFavicon"; } diff --git a/lib/i18n/strings.g.dart b/lib/i18n/strings.g.dart index 03ab0d8..35e4a0a 100644 --- a/lib/i18n/strings.g.dart +++ b/lib/i18n/strings.g.dart @@ -4,9 +4,9 @@ /// To regenerate, run: `dart run slang` /// /// Locales: 2 -/// Strings: 218 (109 per locale) +/// Strings: 224 (112 per locale) /// -/// Built on 2024-02-24 at 12:45 UTC +/// Built on 2024-02-24 at 15:14 UTC // coverage:ignore-file // ignore_for_file: type=lint @@ -382,6 +382,9 @@ class _StringsSettingsGeneralSettingsEn { // Translations String get generalSettings => 'General settings'; String get generalSettingsDescription => 'General tweaks for the application.'; + String get bookmarks => 'Bookmarks'; + String get showFavicon => 'Show favicon'; + String get showFaviconDescription => 'Show the website\'s favicon on each bookmark.'; String get disconnectFromServer => 'Disconnect from server'; late final _StringsSettingsGeneralSettingsDisconnectModalEn disconnectModal = _StringsSettingsGeneralSettingsDisconnectModalEn._(_root); String get useInAppBrowser => 'Use in app browser'; @@ -657,6 +660,9 @@ class _StringsSettingsGeneralSettingsEs implements _StringsSettingsGeneralSettin // Translations @override String get generalSettings => 'Ajustes generales'; @override String get generalSettingsDescription => 'Ajustes generales para la aplicación.'; + @override String get bookmarks => 'Marcadores'; + @override String get showFavicon => 'Mostrar favicon'; + @override String get showFaviconDescription => 'Mostrar el favicon del sitio web en cada marcador.'; @override String get disconnectFromServer => 'Desconectar del servidor'; @override late final _StringsSettingsGeneralSettingsDisconnectModalEs disconnectModal = _StringsSettingsGeneralSettingsDisconnectModalEs._(_root); @override String get useInAppBrowser => 'Usar navegador de la aplicación'; @@ -766,6 +772,9 @@ extension on Translations { case 'settings.customization.useDynamicTheme': return 'Use dynamic theme'; case 'settings.generalSettings.generalSettings': return 'General settings'; case 'settings.generalSettings.generalSettingsDescription': return 'General tweaks for the application.'; + case 'settings.generalSettings.bookmarks': return 'Bookmarks'; + case 'settings.generalSettings.showFavicon': return 'Show favicon'; + case 'settings.generalSettings.showFaviconDescription': return 'Show the website\'s favicon on each bookmark.'; case 'settings.generalSettings.disconnectFromServer': return 'Disconnect from server'; case 'settings.generalSettings.disconnectModal.title': return 'Disconnect'; case 'settings.generalSettings.disconnectModal.description': return 'Are you sure you want to disconnect from the server?\nYou will be redirected to the initial setup.'; @@ -883,6 +892,9 @@ extension on _StringsEs { case 'settings.customization.useDynamicTheme': return 'Usar tema dinámico'; case 'settings.generalSettings.generalSettings': return 'Ajustes generales'; case 'settings.generalSettings.generalSettingsDescription': return 'Ajustes generales para la aplicación.'; + case 'settings.generalSettings.bookmarks': return 'Marcadores'; + case 'settings.generalSettings.showFavicon': return 'Mostrar favicon'; + case 'settings.generalSettings.showFaviconDescription': return 'Mostrar el favicon del sitio web en cada marcador.'; case 'settings.generalSettings.disconnectFromServer': return 'Desconectar del servidor'; case 'settings.generalSettings.disconnectModal.title': return 'Desconectar'; case 'settings.generalSettings.disconnectModal.description': return '¿Estás seguro que deseas desconectarte del servidor?\nSerás redirigido a la configuración inicial.'; diff --git a/lib/i18n/strings_en.i18n.json b/lib/i18n/strings_en.i18n.json index ca75105..aa1c8ee 100644 --- a/lib/i18n/strings_en.i18n.json +++ b/lib/i18n/strings_en.i18n.json @@ -105,6 +105,9 @@ "generalSettings": { "generalSettings": "General settings", "generalSettingsDescription": "General tweaks for the application.", + "bookmarks": "Bookmarks", + "showFavicon": "Show favicon", + "showFaviconDescription": "Show the website's favicon on each bookmark.", "disconnectFromServer": "Disconnect from server", "disconnectModal": { "title": "Disconnect", diff --git a/lib/i18n/strings_es.i18n.json b/lib/i18n/strings_es.i18n.json index e598b15..bcacba7 100644 --- a/lib/i18n/strings_es.i18n.json +++ b/lib/i18n/strings_es.i18n.json @@ -105,6 +105,9 @@ "generalSettings": { "generalSettings": "Ajustes generales", "generalSettingsDescription": "Ajustes generales para la aplicación.", + "bookmarks": "Marcadores", + "showFavicon": "Mostrar favicon", + "showFaviconDescription": "Mostrar el favicon del sitio web en cada marcador.", "disconnectFromServer": "Desconectar del servidor", "disconnectModal": { "title": "Desconectar", diff --git a/lib/models/app_status.dart b/lib/models/app_status.dart index 4958854..60c3c1a 100644 --- a/lib/models/app_status.dart +++ b/lib/models/app_status.dart @@ -6,6 +6,7 @@ class AppStatusModel { bool useDynamicTheme; int selectedColor; bool useInAppBrowser; + bool showFavicon; AppStatusModel({ this.selectedTheme = SelectedTheme.system, @@ -13,5 +14,6 @@ class AppStatusModel { this.useDynamicTheme = true, this.selectedColor = 0, this.useInAppBrowser = true, + this.showFavicon = true, }); } diff --git a/lib/providers/app_status_provider.dart b/lib/providers/app_status_provider.dart index 9bf8d5c..e3c31d8 100644 --- a/lib/providers/app_status_provider.dart +++ b/lib/providers/app_status_provider.dart @@ -19,6 +19,7 @@ class AppStatus extends _$AppStatus { selectedTheme: SelectedTheme.values[sharedPreferences.getInt(SharedPreferencesKeys.selectedTheme) ?? 0], useDynamicTheme: sharedPreferences.getBool(SharedPreferencesKeys.useDynamicTheme) ?? true, useInAppBrowser: sharedPreferences.getBool(SharedPreferencesKeys.useInAppBrowser) ?? true, + showFavicon: sharedPreferences.getBool(SharedPreferencesKeys.showFavicon) ?? true, ); } @@ -49,6 +50,12 @@ class AppStatus extends _$AppStatus { ref.read(sharedPreferencesProvider).setBool(SharedPreferencesKeys.useInAppBrowser, value); ref.notifyListeners(); } + + void setShowFavicon(bool value) { + state.showFavicon = value; + ref.read(sharedPreferencesProvider).setBool(SharedPreferencesKeys.showFavicon, value); + ref.notifyListeners(); + } } @riverpod diff --git a/lib/screens/bookmarks/ui/bookmark_item.dart b/lib/screens/bookmarks/ui/bookmark_item.dart index 72585cb..d1eccaa 100644 --- a/lib/screens/bookmarks/ui/bookmark_item.dart +++ b/lib/screens/bookmarks/ui/bookmark_item.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:favicon/favicon.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:skeletonizer/skeletonizer.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:linkdy/models/data/bookmarks.dart'; @@ -39,29 +40,46 @@ class BookmarkItem extends ConsumerWidget { padding: const EdgeInsets.only(bottom: 4), child: Row( children: [ - FutureBuilder( - future: FaviconFinder.getBest(bookmark.url!), - builder: (context, snapshot) { - if (snapshot.data == null) return const SizedBox(); - return Row( - children: [ - if (snapshot.data!.url.contains("svg")) - SvgPicture.network( - snapshot.data!.url, - width: 16, - height: 16, + if (ref.watch(appStatusProvider).showFavicon == true) + FutureBuilder( + future: FaviconFinder.getBest(bookmark.url!), + builder: (context, snapshot) { + if (snapshot.hasData == false) { + return Padding( + padding: const EdgeInsets.only(right: 8), + child: ClipRRect( + borderRadius: BorderRadius.circular(4), + child: Skeletonizer( + enabled: true, + ignoreContainers: true, + child: Container( + width: 16, + height: 16, + color: Colors.black, + ), + ), ), - if (!snapshot.data!.url.contains("svg")) - Image.network( - snapshot.data!.url, - width: 16, - height: 16, - ), - const SizedBox(width: 8), - ], - ); - }, - ), + ); + } + return Row( + children: [ + if (snapshot.data!.url.contains("svg")) + SvgPicture.network( + snapshot.data!.url, + width: 16, + height: 16, + ), + if (!snapshot.data!.url.contains("svg")) + Image.network( + snapshot.data!.url, + width: 16, + height: 16, + ), + const SizedBox(width: 8), + ], + ); + }, + ), Expanded( child: Text( validateStrings(bookmark.title, bookmark.websiteTitle), diff --git a/lib/screens/settings/ui/general_settings/general_settings.dart b/lib/screens/settings/ui/general_settings/general_settings.dart index d05b40d..5adb026 100644 --- a/lib/screens/settings/ui/general_settings/general_settings.dart +++ b/lib/screens/settings/ui/general_settings/general_settings.dart @@ -5,6 +5,7 @@ import 'package:linkdy/i18n/strings.g.dart'; import 'package:linkdy/screens/settings/ui/general_settings/disconnect_modal.dart'; import 'package:linkdy/providers/app_status_provider.dart'; +import 'package:linkdy/widgets/section_label.dart'; class GeneralSettings extends ConsumerWidget { const GeneralSettings({Key? key}) : super(key: key); @@ -17,13 +18,23 @@ class GeneralSettings extends ConsumerWidget { ), body: ListView( children: [ + SectionLabel(label: t.settings.generalSettings.bookmarks), + SwitchListTile( + title: Text(t.settings.generalSettings.showFavicon), + subtitle: Text(t.settings.generalSettings.showFaviconDescription), + value: ref.watch(appStatusProvider).showFavicon, + onChanged: ref.read(appStatusProvider.notifier).setShowFavicon, + ), SwitchListTile( title: Text(t.settings.generalSettings.useInAppBrowser), subtitle: Text(t.settings.generalSettings.useInAppBrowserDescription), value: ref.watch(appStatusProvider).useInAppBrowser, onChanged: ref.read(appStatusProvider.notifier).setUseInAppBrowser, ), - const SizedBox(height: 16), + const Padding( + padding: EdgeInsets.symmetric(vertical: 16), + child: Divider(), + ), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ diff --git a/pubspec.lock b/pubspec.lock index 84d9b57..7a4fe10 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -989,6 +989,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.4" + skeletonizer: + dependency: "direct main" + description: + name: skeletonizer + sha256: "86f373126d9a887a2d63f2463a9913a973ce7f282efa7f0d9d06a17e3f19838c" + url: "https://pub.dev" + source: hosted + version: "1.0.1" sky_engine: dependency: transitive description: flutter diff --git a/pubspec.yaml b/pubspec.yaml index 1fd7ef2..3e0cf8b 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -55,6 +55,7 @@ dependencies: sentry_flutter: ^7.16.1 flutter_dotenv: ^5.1.0 favicon: ^1.1.2 + skeletonizer: ^1.0.1 dev_dependencies: build_runner: ^2.4.8