From 8a046ba8e998332f72f2c32f2aa4db182e6d2a28 Mon Sep 17 00:00:00 2001 From: Ian Parks Date: Sat, 13 Apr 2024 16:20:17 -0400 Subject: [PATCH 1/4] Added an option to hide thumbnails in compact feed --- lib/community/widgets/post_card.dart | 1 + .../widgets/post_card_view_comfortable.dart | 2 + .../widgets/post_card_view_compact.dart | 31 +++++---- lib/core/enums/local_settings.dart | 2 + lib/l10n/app_en.arb | 2 + .../pages/post_appearance_settings_page.dart | 68 ++++++++++++------- lib/thunder/bloc/thunder_bloc.dart | 2 + lib/thunder/bloc/thunder_state.dart | 5 ++ 8 files changed, 76 insertions(+), 37 deletions(-) diff --git a/lib/community/widgets/post_card.dart b/lib/community/widgets/post_card.dart index b17c91d96..232346193 100644 --- a/lib/community/widgets/post_card.dart +++ b/lib/community/widgets/post_card.dart @@ -207,6 +207,7 @@ class _PostCardState extends State { ) : PostCardViewComfortable( postViewMedia: widget.postViewMedia, + hideThumbnails: state.hideThumbnails, showThumbnailPreviewOnRight: state.showThumbnailPreviewOnRight, hideNsfwPreviews: state.hideNsfwPreviews, markPostReadOnMediaView: state.markPostReadOnMediaView, diff --git a/lib/community/widgets/post_card_view_comfortable.dart b/lib/community/widgets/post_card_view_comfortable.dart index b566ad2f5..b2acb1d76 100644 --- a/lib/community/widgets/post_card_view_comfortable.dart +++ b/lib/community/widgets/post_card_view_comfortable.dart @@ -25,6 +25,7 @@ class PostCardViewComfortable extends StatelessWidget { final Function(bool) onSaveAction; final PostViewMedia postViewMedia; + final bool hideThumbnails; final bool showThumbnailPreviewOnRight; final bool hideNsfwPreviews; final bool edgeToEdgeImages; @@ -45,6 +46,7 @@ class PostCardViewComfortable extends StatelessWidget { const PostCardViewComfortable({ super.key, required this.postViewMedia, + required this.hideThumbnails, required this.showThumbnailPreviewOnRight, required this.hideNsfwPreviews, required this.edgeToEdgeImages, diff --git a/lib/community/widgets/post_card_view_compact.dart b/lib/community/widgets/post_card_view_compact.dart index 028f22a6e..596000818 100644 --- a/lib/community/widgets/post_card_view_compact.dart +++ b/lib/community/widgets/post_card_view_compact.dart @@ -42,6 +42,7 @@ class PostCardViewCompact extends StatelessWidget { final theme = Theme.of(context); final ThunderState state = context.watch().state; + bool hideThumbnails = state.hideThumbnails; bool showThumbnailPreviewOnRight = state.showThumbnailPreviewOnRight; bool showTextPostIndicator = state.showTextPostIndicator; bool indicateRead = this.indicateRead ?? state.dimReadPosts; @@ -63,13 +64,14 @@ class PostCardViewCompact extends StatelessWidget { child: Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ - !showThumbnailPreviewOnRight && showMedia && (postViewMedia.media.first.mediaType == MediaType.text ? showTextPostIndicator : true) - ? ThumbnailPreview( - postViewMedia: postViewMedia, - navigateToPost: navigateToPost, - indicateRead: indicateRead, - ) - : const SizedBox(width: 8.0), + if (!hideThumbnails) + !showThumbnailPreviewOnRight && showMedia && (postViewMedia.media.first.mediaType == MediaType.text ? showTextPostIndicator : true) + ? ThumbnailPreview( + postViewMedia: postViewMedia, + navigateToPost: navigateToPost, + indicateRead: indicateRead, + ) + : const SizedBox(width: 8.0), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -167,13 +169,14 @@ class PostCardViewCompact extends StatelessWidget { ], ), ), - showThumbnailPreviewOnRight && showMedia && (postViewMedia.media.first.mediaType == MediaType.text ? showTextPostIndicator : true) - ? ThumbnailPreview( - postViewMedia: postViewMedia, - navigateToPost: navigateToPost, - indicateRead: indicateRead, - ) - : const SizedBox(width: 8.0), + if (!hideThumbnails) + showThumbnailPreviewOnRight && showMedia && (postViewMedia.media.first.mediaType == MediaType.text ? showTextPostIndicator : true) + ? ThumbnailPreview( + postViewMedia: postViewMedia, + navigateToPost: navigateToPost, + indicateRead: indicateRead, + ) + : const SizedBox(width: 8.0), ], ), ); diff --git a/lib/core/enums/local_settings.dart b/lib/core/enums/local_settings.dart index 6167f8b17..7d8add259 100644 --- a/lib/core/enums/local_settings.dart +++ b/lib/core/enums/local_settings.dart @@ -108,6 +108,7 @@ enum LocalSettings { // Compact Related Settings useCompactView(name: 'setting_general_use_compact_view', key: 'compactView', category: LocalSettingsCategories.posts, subCategory: LocalSettingsSubCategories.posts), showPostTitleFirst(name: 'setting_general_show_title_first', key: 'showPostTitleFirst', category: LocalSettingsCategories.posts, subCategory: LocalSettingsSubCategories.posts), + hideThumbnails(name: 'setting_general_hide_thumbnails', key: 'hideThumbnails', category: LocalSettingsCategories.posts, subCategory: LocalSettingsSubCategories.posts), showThumbnailPreviewOnRight( name: 'setting_compact_show_thumbnail_on_right', key: 'showThumbnailPreviewOnRight', category: LocalSettingsCategories.posts, subCategory: LocalSettingsSubCategories.posts), showTextPostIndicator(name: 'setting_compact_show_text_post_indicator', key: 'showTextPostIndicator', category: LocalSettingsCategories.posts, subCategory: LocalSettingsSubCategories.posts), @@ -328,6 +329,7 @@ extension LocalizationExt on AppLocalizations { 'appLanguage': appLanguage, 'compactView': compactView, 'showPostTitleFirst': showPostTitleFirst, + 'hideThumbnails': hideThumbnails, 'showThumbnailPreviewOnRight': showThumbnailPreviewOnRight, 'showTextPostIndicator': showTextPostIndicator, 'tappableAuthorCommunity': tappableAuthorCommunity, diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 8fe44004d..73a4670e0 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -709,6 +709,8 @@ }, "hidePassword": "Hide Password", "@hidePassword": {}, + "hideThumbnails": "Hide thumbnails", + "@hideThumbnails": {}, "hideTopBarOnScroll": "Hide Top Bar on Scroll", "@hideTopBarOnScroll": { "description": "Settings toggle to hide the top bar on scroll" diff --git a/lib/settings/pages/post_appearance_settings_page.dart b/lib/settings/pages/post_appearance_settings_page.dart index 38d9e2f9d..0856a0415 100644 --- a/lib/settings/pages/post_appearance_settings_page.dart +++ b/lib/settings/pages/post_appearance_settings_page.dart @@ -51,6 +51,9 @@ class _PostAppearanceSettingsPageState extends State /// When enabled, posts on the feed will be compacted bool useCompactView = false; + /// When enabled, the thumbnails in compact mode will be hidden + bool hideThumbnails = false; + /// When enabled, the thumbnail previews will be shown on the right. By default, they are shown on the left bool showThumbnailPreviewOnRight = false; @@ -149,6 +152,7 @@ class _PostAppearanceSettingsPageState extends State compactPostCardMetadataItems = prefs.getStringList(LocalSettings.compactPostCardMetadataItems.name)?.map((e) => PostCardMetadataItem.values.byName(e)).toList() ?? DEFAULT_COMPACT_POST_CARD_METADATA; cardPostCardMetadataItems = prefs.getStringList(LocalSettings.cardPostCardMetadataItems.name)?.map((e) => PostCardMetadataItem.values.byName(e)).toList() ?? DEFAULT_CARD_POST_CARD_METADATA; + hideThumbnails = prefs.getBool(LocalSettings.hideThumbnails.name) ?? false; showThumbnailPreviewOnRight = prefs.getBool(LocalSettings.showThumbnailPreviewOnRight.name) ?? false; showTextPostIndicator = prefs.getBool(LocalSettings.showTextPostIndicator.name) ?? false; @@ -218,6 +222,10 @@ class _PostAppearanceSettingsPageState extends State case LocalSettings.compactPostCardMetadataItems: await prefs.setStringList(LocalSettings.compactPostCardMetadataItems.name, value); break; + case LocalSettings.hideThumbnails: + await prefs.setBool(LocalSettings.hideThumbnails.name, value); + setState(() => hideThumbnails = value); + break; case LocalSettings.showThumbnailPreviewOnRight: await prefs.setBool(LocalSettings.showThumbnailPreviewOnRight.name, value); setState(() => showThumbnailPreviewOnRight = value); @@ -296,6 +304,7 @@ class _PostAppearanceSettingsPageState extends State await prefs.remove(LocalSettings.feedCardDividerThickness.name); await prefs.remove(LocalSettings.feedCardDividerColor.name); await prefs.remove(LocalSettings.compactPostCardMetadataItems.name); + await prefs.remove(LocalSettings.hideThumbnails.name); await prefs.remove(LocalSettings.showThumbnailPreviewOnRight.name); await prefs.remove(LocalSettings.showTextPostIndicator.name); await prefs.remove(LocalSettings.cardPostCardMetadataItems.name); @@ -509,6 +518,7 @@ class _PostAppearanceSettingsPageState extends State : IgnorePointer( child: PostCardViewComfortable( postViewMedia: snapshot.data![index]!, + hideThumbnails: hideThumbnails, showThumbnailPreviewOnRight: showThumbnailPreviewOnRight, showPostAuthor: showPostAuthor, hideNsfwPreviews: hideNsfwPreviews, @@ -802,6 +812,16 @@ class _PostAppearanceSettingsPageState extends State ), ), const SliverToBoxAdapter(child: SizedBox(height: 8.0)), + SliverToBoxAdapter( + child: ToggleOption( + description: l10n.hideThumbnails, + value: hideThumbnails, + iconEnabled: Icons.hide_image_outlined, + iconDisabled: Icons.image_outlined, + onToggle: useCompactView == false ? null : (bool value) => setPreferences(LocalSettings.hideThumbnails, value), + highlightKey: settingToHighlight == LocalSettings.hideThumbnails ? settingToHighlightKey : null, + ), + ), SliverToBoxAdapter( child: ToggleOption( description: l10n.showThumbnailPreviewOnRight, @@ -1159,17 +1179,18 @@ class _PostAppearanceSettingsPageState extends State child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ - !showThumbnailPreviewOnRight - ? Container( - width: ViewMode.compact.height, - height: ViewMode.compact.height, - margin: const EdgeInsets.only(right: 8.0), - decoration: BoxDecoration( - color: theme.dividerColor, - borderRadius: BorderRadius.circular((showEdgeToEdgeImages ? 0 : 12)), - ), - ) - : const SizedBox(width: 0), + if (!hideThumbnails) + !showThumbnailPreviewOnRight + ? Container( + width: ViewMode.compact.height, + height: ViewMode.compact.height, + margin: const EdgeInsets.only(right: 8.0), + decoration: BoxDecoration( + color: theme.dividerColor, + borderRadius: BorderRadius.circular((showEdgeToEdgeImages ? 0 : 12)), + ), + ) + : const SizedBox(width: 0), Expanded( child: Padding( padding: EdgeInsets.only(right: showThumbnailPreviewOnRight ? 8.0 : 0), @@ -1212,17 +1233,18 @@ class _PostAppearanceSettingsPageState extends State ), ), ), - showThumbnailPreviewOnRight - ? Container( - width: ViewMode.compact.height, - height: ViewMode.compact.height, - margin: const EdgeInsets.only(right: 8.0), - decoration: BoxDecoration( - color: theme.dividerColor, - borderRadius: BorderRadius.circular((showEdgeToEdgeImages ? 0 : 12)), - ), - ) - : const SizedBox(width: 0), + if (!hideThumbnails) + showThumbnailPreviewOnRight + ? Container( + width: ViewMode.compact.height, + height: ViewMode.compact.height, + margin: const EdgeInsets.only(right: 8.0), + decoration: BoxDecoration( + color: theme.dividerColor, + borderRadius: BorderRadius.circular((showEdgeToEdgeImages ? 0 : 12)), + ), + ) + : const SizedBox(width: 0), ], ), ); @@ -1295,7 +1317,7 @@ class PostCardMetadataDraggableTarget extends StatelessWidget { ), ), onLeave: (data) => HapticFeedback.mediumImpact(), - onWillAccept: (data) { + onWillAcceptWithDetails: (data) { if (!containedPostCardMetadataItems.contains(data)) { return true; } diff --git a/lib/thunder/bloc/thunder_bloc.dart b/lib/thunder/bloc/thunder_bloc.dart index 4b66a1d50..f2db6c818 100644 --- a/lib/thunder/bloc/thunder_bloc.dart +++ b/lib/thunder/bloc/thunder_bloc.dart @@ -140,6 +140,7 @@ class ThunderBloc extends Bloc { // Compact Related Settings bool useCompactView = prefs.getBool(LocalSettings.useCompactView.name) ?? false; bool showTitleFirst = prefs.getBool(LocalSettings.showPostTitleFirst.name) ?? false; + bool hideThumbnails = prefs.getBool(LocalSettings.hideThumbnails.name) ?? false; bool showThumbnailPreviewOnRight = prefs.getBool(LocalSettings.showThumbnailPreviewOnRight.name) ?? false; bool showTextPostIndicator = prefs.getBool(LocalSettings.showTextPostIndicator.name) ?? false; bool tappableAuthorCommunity = prefs.getBool(LocalSettings.tappableAuthorCommunity.name) ?? false; @@ -294,6 +295,7 @@ class ThunderBloc extends Bloc { // Compact Related Settings useCompactView: useCompactView, showTitleFirst: showTitleFirst, + hideThumbnails: hideThumbnails, showThumbnailPreviewOnRight: showThumbnailPreviewOnRight, showTextPostIndicator: showTextPostIndicator, tappableAuthorCommunity: tappableAuthorCommunity, diff --git a/lib/thunder/bloc/thunder_state.dart b/lib/thunder/bloc/thunder_state.dart index e48c1c7bc..17930fa38 100644 --- a/lib/thunder/bloc/thunder_state.dart +++ b/lib/thunder/bloc/thunder_state.dart @@ -52,6 +52,7 @@ class ThunderState extends Equatable { // Compact Related Settings this.useCompactView = false, this.showTitleFirst = false, + this.hideThumbnails = false, this.showThumbnailPreviewOnRight = false, this.showTextPostIndicator = false, this.tappableAuthorCommunity = false, @@ -203,6 +204,7 @@ class ThunderState extends Equatable { /// Compact Related Settings final bool useCompactView; final bool showTitleFirst; + final bool hideThumbnails; final bool showThumbnailPreviewOnRight; final bool showTextPostIndicator; final bool tappableAuthorCommunity; @@ -361,6 +363,7 @@ class ThunderState extends Equatable { /// Compact Related Settings bool? useCompactView, bool? showTitleFirst, + bool? hideThumbnails, bool? showThumbnailPreviewOnRight, bool? showTextPostIndicator, bool? tappableAuthorCommunity, @@ -514,6 +517,7 @@ class ThunderState extends Equatable { // Compact Related Settings useCompactView: useCompactView ?? this.useCompactView, showTitleFirst: showTitleFirst ?? this.showTitleFirst, + hideThumbnails: hideThumbnails ?? this.hideThumbnails, showThumbnailPreviewOnRight: showThumbnailPreviewOnRight ?? this.showThumbnailPreviewOnRight, showTextPostIndicator: showTextPostIndicator ?? this.showTextPostIndicator, tappableAuthorCommunity: tappableAuthorCommunity ?? this.tappableAuthorCommunity, @@ -670,6 +674,7 @@ class ThunderState extends Equatable { /// Compact Related Settings useCompactView, showTitleFirst, + hideThumbnails, showThumbnailPreviewOnRight, showTextPostIndicator, tappableAuthorCommunity, From cb96e26e7d07a12663df2b5a737a547852dade2e Mon Sep 17 00:00:00 2001 From: Ian Parks Date: Fri, 19 Apr 2024 16:09:00 -0400 Subject: [PATCH 2/4] Hide thumbnails option for both compact and card views --- .../widgets/post_card_view_comfortable.dart | 1 + lib/core/enums/local_settings.dart | 2 +- lib/l10n/app_en.arb | 2 +- .../pages/post_appearance_settings_page.dart | 47 ++++---- lib/shared/media_view.dart | 107 +++++++++++++----- 5 files changed, 108 insertions(+), 51 deletions(-) diff --git a/lib/community/widgets/post_card_view_comfortable.dart b/lib/community/widgets/post_card_view_comfortable.dart index b2acb1d76..0477c3202 100644 --- a/lib/community/widgets/post_card_view_comfortable.dart +++ b/lib/community/widgets/post_card_view_comfortable.dart @@ -86,6 +86,7 @@ class PostCardViewComfortable extends StatelessWidget { postViewMedia: postViewMedia, showFullHeightImages: showFullHeightImages, hideNsfwPreviews: hideNsfwPreviews, + hideThumbnails: hideThumbnails, edgeToEdgeImages: edgeToEdgeImages, markPostReadOnMediaView: markPostReadOnMediaView, isUserLoggedIn: isUserLoggedIn, diff --git a/lib/core/enums/local_settings.dart b/lib/core/enums/local_settings.dart index 7d8add259..9e5aef4af 100644 --- a/lib/core/enums/local_settings.dart +++ b/lib/core/enums/local_settings.dart @@ -108,7 +108,7 @@ enum LocalSettings { // Compact Related Settings useCompactView(name: 'setting_general_use_compact_view', key: 'compactView', category: LocalSettingsCategories.posts, subCategory: LocalSettingsSubCategories.posts), showPostTitleFirst(name: 'setting_general_show_title_first', key: 'showPostTitleFirst', category: LocalSettingsCategories.posts, subCategory: LocalSettingsSubCategories.posts), - hideThumbnails(name: 'setting_general_hide_thumbnails', key: 'hideThumbnails', category: LocalSettingsCategories.posts, subCategory: LocalSettingsSubCategories.posts), + hideThumbnails(name: 'setting_general_hide_thumbnails', key: 'hideThumbnails', category: LocalSettingsCategories.posts, subCategory: LocalSettingsSubCategories.feed), showThumbnailPreviewOnRight( name: 'setting_compact_show_thumbnail_on_right', key: 'showThumbnailPreviewOnRight', category: LocalSettingsCategories.posts, subCategory: LocalSettingsSubCategories.posts), showTextPostIndicator(name: 'setting_compact_show_text_post_indicator', key: 'showTextPostIndicator', category: LocalSettingsCategories.posts, subCategory: LocalSettingsSubCategories.posts), diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 73a4670e0..68ea82267 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -709,7 +709,7 @@ }, "hidePassword": "Hide Password", "@hidePassword": {}, - "hideThumbnails": "Hide thumbnails", + "hideThumbnails": "Hide Thumbnails", "@hideThumbnails": {}, "hideTopBarOnScroll": "Hide Top Bar on Scroll", "@hideTopBarOnScroll": { diff --git a/lib/settings/pages/post_appearance_settings_page.dart b/lib/settings/pages/post_appearance_settings_page.dart index 0856a0415..2ea3b4a6d 100644 --- a/lib/settings/pages/post_appearance_settings_page.dart +++ b/lib/settings/pages/post_appearance_settings_page.dart @@ -139,6 +139,7 @@ class _PostAppearanceSettingsPageState extends State // General Settings useCompactView = prefs.getBool(LocalSettings.useCompactView.name) ?? false; hideNsfwPreviews = prefs.getBool(LocalSettings.hideNsfwPreviews.name) ?? true; + hideThumbnails = prefs.getBool(LocalSettings.hideThumbnails.name) ?? false; showPostAuthor = prefs.getBool(LocalSettings.showPostAuthor.name) ?? false; useDisplayNames = prefs.getBool(LocalSettings.useDisplayNamesForUsers.name) ?? true; postShowUserInstance = prefs.getBool(LocalSettings.postShowUserInstance.name) ?? false; @@ -152,7 +153,6 @@ class _PostAppearanceSettingsPageState extends State compactPostCardMetadataItems = prefs.getStringList(LocalSettings.compactPostCardMetadataItems.name)?.map((e) => PostCardMetadataItem.values.byName(e)).toList() ?? DEFAULT_COMPACT_POST_CARD_METADATA; cardPostCardMetadataItems = prefs.getStringList(LocalSettings.cardPostCardMetadataItems.name)?.map((e) => PostCardMetadataItem.values.byName(e)).toList() ?? DEFAULT_CARD_POST_CARD_METADATA; - hideThumbnails = prefs.getBool(LocalSettings.hideThumbnails.name) ?? false; showThumbnailPreviewOnRight = prefs.getBool(LocalSettings.showThumbnailPreviewOnRight.name) ?? false; showTextPostIndicator = prefs.getBool(LocalSettings.showTextPostIndicator.name) ?? false; @@ -186,6 +186,10 @@ class _PostAppearanceSettingsPageState extends State await prefs.setBool(LocalSettings.hideNsfwPreviews.name, value); setState(() => hideNsfwPreviews = value); break; + case LocalSettings.hideThumbnails: + await prefs.setBool(LocalSettings.hideThumbnails.name, value); + setState(() => hideThumbnails = value); + break; case LocalSettings.showPostAuthor: await prefs.setBool(LocalSettings.showPostAuthor.name, value); setState(() => showPostAuthor = value); @@ -222,10 +226,6 @@ class _PostAppearanceSettingsPageState extends State case LocalSettings.compactPostCardMetadataItems: await prefs.setStringList(LocalSettings.compactPostCardMetadataItems.name, value); break; - case LocalSettings.hideThumbnails: - await prefs.setBool(LocalSettings.hideThumbnails.name, value); - setState(() => hideThumbnails = value); - break; case LocalSettings.showThumbnailPreviewOnRight: await prefs.setBool(LocalSettings.showThumbnailPreviewOnRight.name, value); setState(() => showThumbnailPreviewOnRight = value); @@ -295,6 +295,7 @@ class _PostAppearanceSettingsPageState extends State await prefs.remove(LocalSettings.useCompactView.name); await prefs.remove(LocalSettings.hideNsfwPreviews.name); + await prefs.remove(LocalSettings.hideThumbnails.name); await prefs.remove(LocalSettings.showPostAuthor.name); await prefs.remove(LocalSettings.useDisplayNamesForUsers.name); await prefs.remove(LocalSettings.postShowUserInstance.name); @@ -304,7 +305,6 @@ class _PostAppearanceSettingsPageState extends State await prefs.remove(LocalSettings.feedCardDividerThickness.name); await prefs.remove(LocalSettings.feedCardDividerColor.name); await prefs.remove(LocalSettings.compactPostCardMetadataItems.name); - await prefs.remove(LocalSettings.hideThumbnails.name); await prefs.remove(LocalSettings.showThumbnailPreviewOnRight.name); await prefs.remove(LocalSettings.showTextPostIndicator.name); await prefs.remove(LocalSettings.cardPostCardMetadataItems.name); @@ -581,6 +581,16 @@ class _PostAppearanceSettingsPageState extends State highlightKey: settingToHighlight == LocalSettings.hideNsfwPreviews ? settingToHighlightKey : null, ), ), + SliverToBoxAdapter( + child: ToggleOption( + description: l10n.hideThumbnails, + value: hideThumbnails, + iconEnabled: Icons.hide_image_outlined, + iconDisabled: Icons.image_outlined, + onToggle: (bool value) => setPreferences(LocalSettings.hideThumbnails, value), + highlightKey: settingToHighlight == LocalSettings.hideThumbnails ? settingToHighlightKey : null, + ), + ), SliverToBoxAdapter( child: ToggleOption( description: l10n.showPostAuthor, @@ -812,16 +822,6 @@ class _PostAppearanceSettingsPageState extends State ), ), const SliverToBoxAdapter(child: SizedBox(height: 8.0)), - SliverToBoxAdapter( - child: ToggleOption( - description: l10n.hideThumbnails, - value: hideThumbnails, - iconEnabled: Icons.hide_image_outlined, - iconDisabled: Icons.image_outlined, - onToggle: useCompactView == false ? null : (bool value) => setPreferences(LocalSettings.hideThumbnails, value), - highlightKey: settingToHighlight == LocalSettings.hideThumbnails ? settingToHighlightKey : null, - ), - ), SliverToBoxAdapter( child: ToggleOption( description: l10n.showThumbnailPreviewOnRight, @@ -1066,14 +1066,15 @@ class _PostAppearanceSettingsPageState extends State ), // Title const SizedBox(height: 4.0), ], - Container( - height: showFullHeightImages ? 150 : 100, - margin: const EdgeInsets.symmetric(vertical: 8.0), - decoration: BoxDecoration( - color: theme.dividerColor, - borderRadius: BorderRadius.circular((showEdgeToEdgeImages ? 0 : 12)), + if (!hideThumbnails) + Container( + height: showFullHeightImages ? 150 : 100, + margin: const EdgeInsets.symmetric(vertical: 8.0), + decoration: BoxDecoration( + color: theme.dividerColor, + borderRadius: BorderRadius.circular((showEdgeToEdgeImages ? 0 : 12)), + ), ), - ), if (!showTitleFirst) ...[ const SizedBox(height: 4.0), Container( diff --git a/lib/shared/media_view.dart b/lib/shared/media_view.dart index 4cf4b3822..dc6846d8f 100644 --- a/lib/shared/media_view.dart +++ b/lib/shared/media_view.dart @@ -32,6 +32,9 @@ class MediaView extends StatefulWidget { /// Whether to blur NSFW images final bool hideNsfwPreviews; + /// Whether to hide thumbnails + final bool hideThumbnails; + /// Whether to extend the image to the edge of the screen (ViewMode.comfortable) final bool edgeToEdgeImages; @@ -60,6 +63,7 @@ class MediaView extends StatefulWidget { this.allowUnconstrainedImageHeight = false, this.edgeToEdgeImages = false, this.hideNsfwPreviews = true, + this.hideThumbnails = false, this.markPostReadOnMediaView = false, this.isUserLoggedIn = false, this.viewMode = ViewMode.comfortable, @@ -129,6 +133,34 @@ class _MediaViewState extends State with SingleTickerProviderStateMix ); } + /// Overlays the image as an ImageViewer + void showImage() { + if (widget.isUserLoggedIn && widget.markPostReadOnMediaView) { + try { + // Mark post as read when on the feed page + int postId = widget.postViewMedia.postView.post.id; + context.read().add(FeedItemActionedEvent(postAction: PostAction.read, postId: postId, value: true)); + } catch (e) {} + } + Navigator.of(context).push( + PageRouteBuilder( + opaque: false, + transitionDuration: const Duration(milliseconds: 100), + reverseTransitionDuration: const Duration(milliseconds: 100), + transitionsBuilder: (BuildContext context, Animation animation, Animation secondaryAnimation, Widget child) { + return FadeTransition(opacity: animation, child: child); + }, + pageBuilder: (BuildContext context, Animation animation, Animation secondaryAnimation) { + return ImageViewer( + url: widget.postViewMedia.media.first.mediaUrl ?? widget.postViewMedia.media.first.originalUrl!, + postId: widget.postViewMedia.postView.post.id, + navigateToPost: widget.navigateToPost, + ); + }, + ), + ); + } + /// Creates an image preview Widget buildMediaImage() { final theme = Theme.of(context); @@ -139,32 +171,7 @@ class _MediaViewState extends State with SingleTickerProviderStateMix return InkWell( splashColor: theme.colorScheme.primary.withOpacity(0.4), borderRadius: BorderRadius.circular((widget.edgeToEdgeImages ? 0 : 12)), - onTap: () { - if (widget.isUserLoggedIn && widget.markPostReadOnMediaView) { - try { - // Mark post as read when on the feed page - int postId = widget.postViewMedia.postView.post.id; - context.read().add(FeedItemActionedEvent(postAction: PostAction.read, postId: postId, value: true)); - } catch (e) {} - } - Navigator.of(context).push( - PageRouteBuilder( - opaque: false, - transitionDuration: const Duration(milliseconds: 100), - reverseTransitionDuration: const Duration(milliseconds: 100), - transitionsBuilder: (BuildContext context, Animation animation, Animation secondaryAnimation, Widget child) { - return FadeTransition(opacity: animation, child: child); - }, - pageBuilder: (BuildContext context, Animation animation, Animation secondaryAnimation) { - return ImageViewer( - url: widget.postViewMedia.media.first.mediaUrl ?? widget.postViewMedia.media.first.originalUrl!, - postId: widget.postViewMedia.postView.post.id, - navigateToPost: widget.navigateToPost, - ); - }, - ), - ); - }, + onTap: showImage, child: Container( clipBehavior: Clip.hardEdge, decoration: BoxDecoration( @@ -216,6 +223,14 @@ class _MediaViewState extends State with SingleTickerProviderStateMix @override Widget build(BuildContext context) { + if (widget.hideThumbnails) { + return linkInformation( + context, + widget.viewMode, + widget.postViewMedia.media.first.originalUrl, + widget.postViewMedia.media.first.mediaType, + ); + } switch (widget.postViewMedia.media.firstOrNull?.mediaType) { case MediaType.image: return buildMediaImage(); @@ -333,4 +348,44 @@ class _MediaViewState extends State with SingleTickerProviderStateMix }, ); } + + Widget linkInformation(BuildContext context, ViewMode viewMode, String? originURL, MediaType? mediaType) { + final theme = Theme.of(context); + final IconData icon = switch (mediaType) { MediaType.image => Icons.image_outlined, MediaType.video => Icons.play_arrow_rounded, MediaType.text => Icons.wysiwyg_rounded, _ => Icons.link_rounded }; + return Semantics( + excludeSemantics: true, + child: Container( + color: ElevationOverlay.applySurfaceTint( + Theme.of(context).colorScheme.surface.withOpacity(0.8), + Theme.of(context).colorScheme.surfaceTint, + 10, + ), + padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 8.0), + child: InkWell( + onTap: () { + if (mediaType == MediaType.image) showImage(); + }, + child: Row( + children: [ + Padding( + padding: const EdgeInsets.only(right: 8.0), + child: Icon( + icon, + color: theme.colorScheme.onSecondaryContainer, + ), + ), + if (viewMode != ViewMode.compact) + Expanded( + child: Text( + originURL!, + overflow: TextOverflow.ellipsis, + style: theme.textTheme.bodyMedium, + ), + ), + ], + ), + ), + ), + ); + } } From 9774a770c111fcd572776e40a34d489778ccd9ad Mon Sep 17 00:00:00 2001 From: Ian Parks Date: Fri, 19 Apr 2024 16:58:22 -0400 Subject: [PATCH 3/4] Link information widget; code refactoring --- lib/l10n/app_en.arb | 4 +- lib/shared/link_information.dart | 68 +++++++++++++++++++++++++++++++ lib/shared/link_preview_card.dart | 43 +++---------------- lib/shared/media_view.dart | 51 +++-------------------- 4 files changed, 82 insertions(+), 84 deletions(-) create mode 100644 lib/shared/link_information.dart diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 68ea82267..1ac5f2ec2 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -710,7 +710,9 @@ "hidePassword": "Hide Password", "@hidePassword": {}, "hideThumbnails": "Hide Thumbnails", - "@hideThumbnails": {}, + "@hideThumbnails": { + "description": "Option to hide thumbnails in feed" + }, "hideTopBarOnScroll": "Hide Top Bar on Scroll", "@hideTopBarOnScroll": { "description": "Settings toggle to hide the top bar on scroll" diff --git a/lib/shared/link_information.dart b/lib/shared/link_information.dart new file mode 100644 index 000000000..117fd72f2 --- /dev/null +++ b/lib/shared/link_information.dart @@ -0,0 +1,68 @@ +import 'package:flutter/material.dart'; +import 'package:thunder/core/enums/media_type.dart'; +import 'package:thunder/core/enums/view_mode.dart'; + +class LinkInformation extends StatefulWidget { + final ViewMode viewMode; + + final String? originURL; + + final MediaType? mediaType; + + final Function? handleTapImage; + + const LinkInformation({ + super.key, + required this.viewMode, + this.originURL, + this.mediaType, + this.handleTapImage, + }); + + @override + State createState() => _LinkInformationState(); +} + +class _LinkInformationState extends State { + @override + Widget build(BuildContext context) { + final theme = Theme.of(context); + final IconData icon = + switch (widget.mediaType) { MediaType.image => Icons.image_outlined, MediaType.video => Icons.play_arrow_rounded, MediaType.text => Icons.wysiwyg_rounded, _ => Icons.link_rounded }; + return Semantics( + excludeSemantics: true, + child: Container( + color: ElevationOverlay.applySurfaceTint( + Theme.of(context).colorScheme.surface.withOpacity(0.8), + Theme.of(context).colorScheme.surfaceTint, + 10, + ), + padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 8.0), + child: InkWell( + onTap: () { + if (widget.mediaType == MediaType.image && widget.handleTapImage != null) widget.handleTapImage!(); + }, + child: Row( + children: [ + Padding( + padding: const EdgeInsets.only(right: 8.0), + child: Icon( + icon, + color: theme.colorScheme.onSecondaryContainer, + ), + ), + if (widget.viewMode != ViewMode.compact) + Expanded( + child: Text( + widget.originURL!, + overflow: TextOverflow.ellipsis, + style: theme.textTheme.bodyMedium, + ), + ), + ], + ), + ), + ), + ); + } +} diff --git a/lib/shared/link_preview_card.dart b/lib/shared/link_preview_card.dart index 8949727c1..b847aeb88 100644 --- a/lib/shared/link_preview_card.dart +++ b/lib/shared/link_preview_card.dart @@ -6,14 +6,12 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:link_preview_generator/link_preview_generator.dart'; import 'package:thunder/feed/bloc/feed_bloc.dart'; -import 'package:thunder/feed/utils/utils.dart'; -import 'package:thunder/feed/view/feed_page.dart'; import 'package:thunder/post/enums/post_action.dart'; +import 'package:thunder/shared/link_information.dart'; import 'package:thunder/utils/links.dart'; import 'package:thunder/core/enums/view_mode.dart'; import 'package:thunder/thunder/bloc/thunder_bloc.dart'; -import 'package:thunder/utils/instance.dart'; import 'package:thunder/shared/image_preview.dart'; class LinkPreviewCard extends StatelessWidget { @@ -130,7 +128,10 @@ class LinkPreviewCard extends StatelessWidget { ], ), ), - linkInformation(context), + LinkInformation( + viewMode: viewMode, + originURL: originURL, + ), Positioned.fill( child: Material( color: Colors.transparent, @@ -271,38 +272,4 @@ class LinkPreviewCard extends StatelessWidget { handleLink(context, url: originURL!); } } - - Widget linkInformation(BuildContext context) { - final theme = Theme.of(context); - return Semantics( - excludeSemantics: true, - child: Container( - color: ElevationOverlay.applySurfaceTint( - Theme.of(context).colorScheme.surface.withOpacity(0.8), - Theme.of(context).colorScheme.surfaceTint, - 10, - ), - padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 8.0), - child: Row( - children: [ - Padding( - padding: const EdgeInsets.only(right: 8.0), - child: Icon( - Icons.link, - color: theme.colorScheme.onSecondaryContainer, - ), - ), - if (viewMode != ViewMode.compact) - Expanded( - child: Text( - originURL!, - overflow: TextOverflow.ellipsis, - style: theme.textTheme.bodyMedium, - ), - ), - ], - ), - ), - ); - } } diff --git a/lib/shared/media_view.dart b/lib/shared/media_view.dart index dc6846d8f..e23ccf909 100644 --- a/lib/shared/media_view.dart +++ b/lib/shared/media_view.dart @@ -7,6 +7,7 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:extended_image/extended_image.dart'; import 'package:flex_color_scheme/flex_color_scheme.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'package:thunder/shared/link_information.dart'; import 'package:thunder/utils/links.dart'; import 'package:thunder/feed/bloc/feed_bloc.dart'; @@ -224,11 +225,11 @@ class _MediaViewState extends State with SingleTickerProviderStateMix @override Widget build(BuildContext context) { if (widget.hideThumbnails) { - return linkInformation( - context, - widget.viewMode, - widget.postViewMedia.media.first.originalUrl, - widget.postViewMedia.media.first.mediaType, + return LinkInformation( + viewMode: widget.viewMode, + originURL: widget.postViewMedia.media.first.originalUrl, + mediaType: widget.postViewMedia.media.first.mediaType, + handleTapImage: showImage, ); } switch (widget.postViewMedia.media.firstOrNull?.mediaType) { @@ -348,44 +349,4 @@ class _MediaViewState extends State with SingleTickerProviderStateMix }, ); } - - Widget linkInformation(BuildContext context, ViewMode viewMode, String? originURL, MediaType? mediaType) { - final theme = Theme.of(context); - final IconData icon = switch (mediaType) { MediaType.image => Icons.image_outlined, MediaType.video => Icons.play_arrow_rounded, MediaType.text => Icons.wysiwyg_rounded, _ => Icons.link_rounded }; - return Semantics( - excludeSemantics: true, - child: Container( - color: ElevationOverlay.applySurfaceTint( - Theme.of(context).colorScheme.surface.withOpacity(0.8), - Theme.of(context).colorScheme.surfaceTint, - 10, - ), - padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 8.0), - child: InkWell( - onTap: () { - if (mediaType == MediaType.image) showImage(); - }, - child: Row( - children: [ - Padding( - padding: const EdgeInsets.only(right: 8.0), - child: Icon( - icon, - color: theme.colorScheme.onSecondaryContainer, - ), - ), - if (viewMode != ViewMode.compact) - Expanded( - child: Text( - originURL!, - overflow: TextOverflow.ellipsis, - style: theme.textTheme.bodyMedium, - ), - ), - ], - ), - ), - ), - ); - } } From 11a09a0a5da51c80ec3af013d25dd97bb1eee8e0 Mon Sep 17 00:00:00 2001 From: Ian Parks Date: Wed, 24 Apr 2024 03:51:26 -0400 Subject: [PATCH 4/4] Added minor documentation --- lib/settings/pages/post_appearance_settings_page.dart | 2 +- lib/shared/link_information.dart | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/settings/pages/post_appearance_settings_page.dart b/lib/settings/pages/post_appearance_settings_page.dart index 2ea3b4a6d..9aa97fdb8 100644 --- a/lib/settings/pages/post_appearance_settings_page.dart +++ b/lib/settings/pages/post_appearance_settings_page.dart @@ -51,7 +51,7 @@ class _PostAppearanceSettingsPageState extends State /// When enabled, posts on the feed will be compacted bool useCompactView = false; - /// When enabled, the thumbnails in compact mode will be hidden + /// When enabled, the thumbnails in compact/card mode will be hidden bool hideThumbnails = false; /// When enabled, the thumbnail previews will be shown on the right. By default, they are shown on the left diff --git a/lib/shared/link_information.dart b/lib/shared/link_information.dart index 117fd72f2..467f71bad 100644 --- a/lib/shared/link_information.dart +++ b/lib/shared/link_information.dart @@ -3,12 +3,16 @@ import 'package:thunder/core/enums/media_type.dart'; import 'package:thunder/core/enums/view_mode.dart'; class LinkInformation extends StatefulWidget { + /// The view mode of the media final ViewMode viewMode; + /// URL of the media final String? originURL; + /// Type of media (image, link, text, etc.) final MediaType? mediaType; + /// Callback for when an image is tapped final Function? handleTapImage; const LinkInformation({