Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix jank when using full height images, and other misc media preview imrpovements #1250

Merged
merged 6 commits into from
Mar 31, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion lib/core/enums/view_mode.dart
Original file line number Diff line number Diff line change
@@ -1 +1,9 @@
enum ViewMode { compact, comfortable }
enum ViewMode {
compact(75.0),
comfortable(150.0);

/// The height of media previews for the given view mode
final double height;

const ViewMode(this.height);
}
7 changes: 5 additions & 2 deletions lib/post/utils/post.dart
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,9 @@ Future<PostViewMedia> parsePostView(PostView postView, bool fetchImageDimensions
if (thumbnailUrl != null && thumbnailUrl.isNotEmpty) {
// Now check to see if there is a thumbnail image. If there is, we'll use that for the image
media.mediaUrl = thumbnailUrl;
} else if (isImage) {
// If there is no thumbnail image, but the url is an image, we'll use that for the mediaUrl
media.mediaUrl = url;
} else if (scrapeMissingPreviews) {
// If there is no thumbnail image, we'll see if we should try to fetch the link metadata
LinkInfo linkInfo = await getLinkInfo(url);
Expand All @@ -313,9 +316,9 @@ Future<PostViewMedia> parsePostView(PostView postView, bool fetchImageDimensions
Size result = Size(MediaQuery.of(GlobalContext.context).size.width, 200);

try {
result = await retrieveImageDimensions(imageUrl: media.mediaUrl);
result = await retrieveImageDimensions(imageUrl: media.mediaUrl ?? media.originalUrl).timeout(const Duration(seconds: 2));
} catch (e) {
debugPrint('$e: Falling back to default image size');
debugPrint('${media.mediaUrl ?? media.originalUrl} - $e: Falling back to default image size');
}

Size size = MediaExtension.getScaledMediaSize(width: result.width, height: result.height, offset: edgeToEdgeImages ? 0 : 24, tabletMode: tabletMode);
Expand Down
9 changes: 5 additions & 4 deletions lib/settings/pages/post_appearance_settings_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import 'package:thunder/core/enums/custom_theme_type.dart';
import 'package:thunder/core/enums/feed_card_divider_thickness.dart';
import 'package:thunder/core/enums/local_settings.dart';
import 'package:thunder/core/enums/post_body_view_type.dart';
import 'package:thunder/core/enums/view_mode.dart';
import 'package:thunder/core/models/post_view_media.dart';
import 'package:thunder/core/singletons/preferences.dart';
import 'package:thunder/feed/feed.dart';
Expand Down Expand Up @@ -1159,8 +1160,8 @@ class _PostAppearanceSettingsPageState extends State<PostAppearanceSettingsPage>
children: [
!showThumbnailPreviewOnRight
? Container(
width: 75,
height: 75,
width: ViewMode.compact.height,
height: ViewMode.compact.height,
margin: const EdgeInsets.only(right: 8.0),
decoration: BoxDecoration(
color: theme.dividerColor,
Expand Down Expand Up @@ -1212,8 +1213,8 @@ class _PostAppearanceSettingsPageState extends State<PostAppearanceSettingsPage>
),
showThumbnailPreviewOnRight
? Container(
width: 75,
height: 75,
width: ViewMode.compact.height,
height: ViewMode.compact.height,
margin: const EdgeInsets.only(right: 8.0),
decoration: BoxDecoration(
color: theme.dividerColor,
Expand Down
22 changes: 11 additions & 11 deletions lib/shared/link_preview_card.dart
Original file line number Diff line number Diff line change
Expand Up @@ -80,21 +80,21 @@ class LinkPreviewCard extends StatelessWidget {
child: ImagePreview(
read: read,
url: mediaURL ?? originURL!,
height: showFullHeightImages ? mediaHeight : 150,
height: showFullHeightImages ? mediaHeight : ViewMode.comfortable.height,
width: mediaWidth ?? MediaQuery.of(context).size.width - (edgeToEdgeImages ? 0 : 24),
isExpandable: false,
),
)
: ImagePreview(
read: read,
url: mediaURL ?? originURL!,
height: showFullHeightImages ? mediaHeight : 150,
height: showFullHeightImages ? mediaHeight : ViewMode.comfortable.height,
width: mediaWidth ?? MediaQuery.of(context).size.width - (edgeToEdgeImages ? 0 : 24),
isExpandable: false,
)
] else if (scrapeMissingPreviews)
SizedBox(
height: 150,
height: ViewMode.comfortable.height,
// This is used for external links when Lemmy does not provide a preview thumbnail
// and when the user has enabled external scraping.
// This is only used in comfortable mode.
Expand Down Expand Up @@ -161,22 +161,22 @@ class LinkPreviewCard extends StatelessWidget {
child: ImagePreview(
read: read,
url: mediaURL!,
height: 75,
width: 75,
height: ViewMode.compact.height,
width: ViewMode.compact.height,
isExpandable: false,
),
)
: ImagePreview(
read: read,
url: mediaURL!,
height: 75,
width: 75,
height: ViewMode.compact.height,
width: ViewMode.compact.height,
isExpandable: false,
)
: scrapeMissingPreviews
? SizedBox(
height: 75,
width: 75,
height: ViewMode.compact.height,
width: ViewMode.compact.height,
// This is used for external links when Lemmy does not provide a preview thumbnail
// and when the user has enabled external scraping.
// This is only used in compact mode.
Expand All @@ -201,8 +201,8 @@ class LinkPreviewCard extends StatelessWidget {
// This is used for link previews when no thumbnail comes from Lemmy
// and the user has disabled scraping. This is only in compact mode.
: Container(
height: 75,
width: 75,
height: ViewMode.compact.height,
width: ViewMode.compact.height,
color: theme.cardColor.darken(5),
child: Icon(
hideNsfw ? null : Icons.language,
Expand Down
50 changes: 40 additions & 10 deletions lib/shared/media_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,8 @@ class _MediaViewState extends State<MediaView> with SingleTickerProviderStateMix
color: theme.cardColor.darken(5),
child: widget.postViewMedia.postView.post.body?.isNotEmpty == true
? SizedBox(
height: 75.0,
width: 75.0,
height: ViewMode.compact.height,
width: ViewMode.compact.height,
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Align(
Expand All @@ -113,8 +113,8 @@ class _MediaViewState extends State<MediaView> with SingleTickerProviderStateMix
),
)
: Container(
height: 75,
width: 75,
height: ViewMode.compact.height,
width: ViewMode.compact.height,
color: theme.cardColor.darken(5),
child: Icon(
Icons.text_fields_rounded,
Expand Down Expand Up @@ -163,8 +163,29 @@ class _MediaViewState extends State<MediaView> with SingleTickerProviderStateMix
},
child: Container(
clipBehavior: Clip.hardEdge,
decoration: BoxDecoration(borderRadius: BorderRadius.circular((widget.edgeToEdgeImages ? 0 : 12))),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular((widget.edgeToEdgeImages ? 0 : 12)),
color: theme.colorScheme.primary.withOpacity(0.2),
),
constraints: BoxConstraints(
maxHeight: switch (widget.viewMode) {
ViewMode.compact => ViewMode.compact.height,
ViewMode.comfortable => widget.showFullHeightImages ? widget.postViewMedia.media.first.height ?? ViewMode.comfortable.height : ViewMode.comfortable.height,
},
minHeight: switch (widget.viewMode) {
ViewMode.compact => ViewMode.compact.height,
ViewMode.comfortable => widget.showFullHeightImages ? widget.postViewMedia.media.first.height ?? ViewMode.comfortable.height : ViewMode.comfortable.height,
},
maxWidth: switch (widget.viewMode) {
ViewMode.compact => ViewMode.compact.height,
ViewMode.comfortable => widget.edgeToEdgeImages ? double.infinity : MediaQuery.of(context).size.width,
},
minWidth: switch (widget.viewMode) {
ViewMode.compact => ViewMode.compact.height,
ViewMode.comfortable => widget.edgeToEdgeImages ? double.infinity : MediaQuery.of(context).size.width,
}),
child: Stack(
fit: StackFit.expand,
alignment: Alignment.center,
children: [
ImageFiltered(
Expand Down Expand Up @@ -218,8 +239,18 @@ class _MediaViewState extends State<MediaView> with SingleTickerProviderStateMix
final theme = Theme.of(context);
final state = context.read<ThunderBloc>().state;

double? height = widget.viewMode == ViewMode.compact ? 75 : (widget.showFullHeightImages ? widget.postViewMedia.media.first.height : 150);
double width = widget.viewMode == ViewMode.compact ? 75 : MediaQuery.of(context).size.width - (widget.edgeToEdgeImages ? 0 : 24);
double? width;
double? height;

switch (widget.viewMode) {
case ViewMode.compact:
width = null; // Setting this to null will use the image's width. This will allow the image to not be stretched or squished.
height = ViewMode.compact.height;
break;
case ViewMode.comfortable:
width = MediaQuery.of(context).size.width - (widget.edgeToEdgeImages ? 0 : 24);
height = widget.showFullHeightImages ? widget.postViewMedia.media.first.height : null;
}

return ExtendedImage.network(
color: widget.read == true ? const Color.fromRGBO(255, 255, 255, 0.5) : null,
Expand All @@ -230,9 +261,8 @@ class _MediaViewState extends State<MediaView> with SingleTickerProviderStateMix
fit: widget.viewMode == ViewMode.compact ? BoxFit.cover : BoxFit.fitWidth,
cache: true,
clearMemoryCacheWhenDispose: state.imageCachingMode == ImageCachingMode.relaxed,
cacheWidth: widget.viewMode == ViewMode.compact
? (75 * View.of(context).devicePixelRatio.ceil())
: ((MediaQuery.of(context).size.width - (widget.edgeToEdgeImages ? 0 : 24)) * View.of(context).devicePixelRatio.ceil()).toInt(),
cacheWidth: width != null ? (width * View.of(context).devicePixelRatio.ceil()).toInt() : null,
cacheHeight: height != null ? (height * View.of(context).devicePixelRatio.ceil()).toInt() : null,
loadStateChanged: (ExtendedImageState state) {
switch (state.extendedImageLoadState) {
case LoadState.loading:
Expand Down
8 changes: 5 additions & 3 deletions lib/shared/preview_image.dart
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ class _PreviewImageState extends State<PreviewImage> with SingleTickerProviderSt
final ThunderState state = context.read<ThunderBloc>().state;
final useDarkTheme = state.themeType == 'dark';

double? height = widget.viewMode == ViewMode.compact ? 75 : (widget.showFullHeightImages ? widget.height : 150);
double width = widget.viewMode == ViewMode.compact ? 75 : MediaQuery.of(context).size.width - 24;
double? height = widget.viewMode == ViewMode.compact ? ViewMode.compact.height : (widget.showFullHeightImages ? widget.height : ViewMode.comfortable.height);
double width = widget.viewMode == ViewMode.compact ? ViewMode.compact.height : MediaQuery.of(context).size.width - 24;

return ExtendedImage.network(
widget.mediaUrl,
Expand All @@ -57,7 +57,9 @@ class _PreviewImageState extends State<PreviewImage> with SingleTickerProviderSt
fit: widget.viewMode == ViewMode.compact ? BoxFit.cover : BoxFit.fitWidth,
cache: true,
clearMemoryCacheWhenDispose: state.imageCachingMode == ImageCachingMode.relaxed,
cacheWidth: widget.viewMode == ViewMode.compact ? (75 * View.of(context).devicePixelRatio.ceil()) : ((MediaQuery.of(context).size.width - 24) * View.of(context).devicePixelRatio.ceil()).toInt(),
cacheWidth: widget.viewMode == ViewMode.compact
? (ViewMode.compact.height * View.of(context).devicePixelRatio.ceil()).toInt()
: ((MediaQuery.of(context).size.width - 24) * View.of(context).devicePixelRatio.ceil()).toInt(),
loadStateChanged: (ExtendedImageState state) {
switch (state.extendedImageLoadState) {
case LoadState.loading:
Expand Down
Loading