Skip to content

Commit

Permalink
Merge Release 2.18.5
Browse files Browse the repository at this point in the history
  • Loading branch information
sharunkumar committed Nov 8, 2024
2 parents 2960796 + a868fef commit 901d405
Show file tree
Hide file tree
Showing 16 changed files with 100 additions and 43 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ on:
push:
branches:
- main
- release/*
pull_request:
branches:
- main
- release/*
workflow_dispatch: {}

jobs:
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ on:
push:
branches:
- main
- release/*
tags:
- "*"
pull_request:
branches:
- main
- release/*
jobs:
docker:
runs-on: ubuntu-latest
Expand Down
4 changes: 2 additions & 2 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ android {
applicationId "app.vger.voyager"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 266
versionName "2.18.4"
versionCode 269
versionName "2.18.5"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
aaptOptions {
// Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps.
Expand Down
4 changes: 2 additions & 2 deletions ios/App/App/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>2.18.4</string>
<string>2.18.5</string>
<key>CFBundleURLTypes</key>
<array>
<dict>
Expand All @@ -32,7 +32,7 @@
</dict>
</array>
<key>CFBundleVersion</key>
<string>266</string>
<string>269</string>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>LSRequiresIPhoneOS</key>
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "voyager",
"description": "A progressive webapp Lemmy client",
"private": true,
"version": "2.18.4",
"version": "2.18.5",
"type": "module",
"packageManager": "pnpm@9.6.0+sha512.38dc6fba8dba35b39340b9700112c2fe1e12f10b17134715a4aa98ccf7bb035e76fd981cf0bb384dfa98f8d6af5481c2bef2f4266a24bfa20c34eb7147ce0b5e",
"scripts": {
Expand Down
6 changes: 4 additions & 2 deletions src/features/media/gallery/GalleryMedia.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,10 @@ export default forwardRef<
ref,
) {
const isGif = useMemo(
() => props.src && isUrlPotentialAnimatedImage(props.src),
[props.src],
() =>
props.src &&
isUrlPotentialAnimatedImage(props.src, post?.post.url_content_type),
[props.src, post],
);
const shouldAutoplay = useShouldAutoplay();

Expand Down
5 changes: 4 additions & 1 deletion src/features/media/gallery/Media.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ const Media = forwardRef<
ComponentRef<typeof Video> | ComponentRef<typeof GalleryMedia>,
PostGalleryImgProps
>(function Media({ nativeControls, src, ...props }, ref) {
const isVideo = useMemo(() => src && isUrlVideo(src), [src]);
const isVideo = useMemo(
() => src && isUrlVideo(src, props.post?.post.url_content_type),
[src, props.post],
);

if (isVideo)
return (
Expand Down
2 changes: 1 addition & 1 deletion src/features/post/inFeed/compact/CompactPost.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ export default function CompactPost({ post }: PostProps) {

const [domain] = useMemo(
() =>
post.post.url && !isUrlImage(post.post.url)
post.post.url && !isUrlImage(post.post.url, post.post.url_content_type)
? parseUrlForDisplay(post.post.url)
: [],
[post],
Expand Down
5 changes: 3 additions & 2 deletions src/features/post/inFeed/compact/Thumbnail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,11 @@ export default function Thumbnail({ post }: ImgProps) {
);

const postImageSrc = useMemo(() => {
if (post.post.url && isUrlImage(post.post.url)) return post.post.url;
if (post.post.url && isUrlImage(post.post.url, post.post.url_content_type))
return post.post.url;

if (markdownLoneImage) return markdownLoneImage.url;
}, [markdownLoneImage, post.post.url]);
}, [markdownLoneImage, post.post]);

const blurNsfw = useAppSelector(
(state) => state.settings.appearance.posts.blurNsfw,
Expand Down
40 changes: 24 additions & 16 deletions src/features/post/inFeed/usePostSrc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,15 @@ import { useAppSelector } from "../../../store";
import { IMAGE_FAILED } from "./large/imageSlice";
import { findUrlMediaType } from "../../../helpers/url";
import { findLoneImage } from "../../../helpers/markdown";
import useSupported from "../../../helpers/useSupported";

export default function usePostSrc(post: PostView): string | undefined {
const src = useMemo(() => getPostMedia(post), [post]);
const thumbnailIsFullsize = useSupported("Fullsize thumbnails");

const src = useMemo(
() => getPostMedia(post, thumbnailIsFullsize),
[post, thumbnailIsFullsize],
);
const primaryFailed = useAppSelector(
(state) => src && state.image.loadedBySrc[src[0]] === IMAGE_FAILED,
);
Expand All @@ -18,24 +24,26 @@ export default function usePostSrc(post: PostView): string | undefined {
return src[0];
}

export function getPostMedia(
function getPostMedia(
post: PostView,
thumbnailIsFullsize: boolean,
): [string] | [string, string] | undefined {
const urlType = post.post.url && findUrlMediaType(post.post.url);

if (post.post.url && urlType) {
const thumbnailType =
post.post.thumbnail_url && findUrlMediaType(post.post.thumbnail_url);

if (post.post.thumbnail_url) {
// Sometimes Lemmy will cache the video, sometimes the thumbnail will be a still frame of the video
if (urlType === "video" && thumbnailType === "image")
return [post.post.url];

return [post.post.thumbnail_url, post.post.url];
if (post.post.url) {
const isUrlMedia = findUrlMediaType(
post.post.url,
post.post.url_content_type,
);

if (isUrlMedia) {
if (post.post.thumbnail_url) {
if (thumbnailIsFullsize)
return [post.post.thumbnail_url, post.post.url];
}

// no fallback now for newer lemmy versions
// in the future might unwrap lemmy proxy_image param here
return [post.post.url];
}

return [post.post.url];
}

if (post.post.thumbnail_url) return [post.post.thumbnail_url];
Expand Down
2 changes: 1 addition & 1 deletion src/features/post/link/Link.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ export default function Link({
() => determineObjectTypeFromUrl(url) ?? determineTypeFromUrl(url),
[url, determineObjectTypeFromUrl],
);
const isImage = useMemo(() => isUrlImage(url), [url]);
const isImage = useMemo(() => isUrlImage(url, undefined), [url]);

const handleLinkClick = (e: MouseEvent) => {
e.stopPropagation();
Expand Down
4 changes: 3 additions & 1 deletion src/features/post/new/PostEditorRoot.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,9 @@ export default function PostEditorRoot({
const existingPost = "existingPost" in props ? props.existingPost : undefined;

const isImage = useMemo(
() => existingPost?.post.url && isUrlImage(existingPost.post.url),
() =>
existingPost?.post.url &&
isUrlImage(existingPost.post.url, existingPost.post.url_content_type),
[existingPost],
);

Expand Down
2 changes: 1 addition & 1 deletion src/features/post/useIsPostUrlMedia.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export default function useIsPostUrlMedia() {
if (isRedgif(url)) return true;
}

return !!findUrlMediaType(url);
return !!findUrlMediaType(url, post.post.url_content_type);
},
[embedExternalMedia],
);
Expand Down
2 changes: 1 addition & 1 deletion src/features/shared/markdown/MarkdownImg.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ interface MarkdownImgProps extends GalleryMediaProps {
export default function MarkdownImg({ small, ...props }: MarkdownImgProps) {
const sharedStyles = small ? smallStyles : undefined;
const isVideo = useMemo(
() => props.src && isUrlVideo(props.src),
() => props.src && isUrlVideo(props.src, undefined),
[props.src],
);

Expand Down
37 changes: 29 additions & 8 deletions src/helpers/url.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,12 @@ export function getPotentialImageProxyPathname(

const imageExtensions = ["jpeg", "png", "gif", "jpg", "webp", "jxl", "avif"];

export function isUrlImage(url: string): boolean {
export function isUrlImage(
url: string,
contentType: string | undefined,
): boolean {
if (contentType?.startsWith("image/")) return true;

const pathname = getPotentialImageProxyPathname(url);

if (!pathname) return false;
Expand All @@ -63,9 +68,18 @@ export function isUrlImage(url: string): boolean {
);
}

const animatedImageExtensions = ["gif", "webp", "jxl", "avif"];
const animatedImageExtensions = ["gif", "webp", "jxl", "avif", "apng"];
const animatedImageContentTypes = animatedImageExtensions.map(
(extension) => `image/${extension}`,
);

export function isUrlPotentialAnimatedImage(
url: string,
contentType: string | undefined,
): boolean {
if (contentType && animatedImageContentTypes.includes(contentType))
return true;

export function isUrlPotentialAnimatedImage(url: string): boolean {
const pathname = getPotentialImageProxyPathname(url);

if (!pathname) return false;
Expand All @@ -77,7 +91,12 @@ export function isUrlPotentialAnimatedImage(url: string): boolean {

const videoExtensions = ["mp4", "webm", "gifv"];

export function isUrlVideo(url: string): boolean {
export function isUrlVideo(
url: string,
contentType: string | undefined,
): boolean {
if (contentType?.startsWith("video/")) return true;

const pathname = getPotentialImageProxyPathname(url);
if (!pathname) return false;

Expand All @@ -86,10 +105,12 @@ export function isUrlVideo(url: string): boolean {
);
}

export function findUrlMediaType(url: string): "video" | "image" | undefined {
if (isUrlImage(url)) return "image";

if (isUrlVideo(url)) return "video";
export function findUrlMediaType(
url: string,
contentType: string | undefined, // not available on older lemmy instances <0.19.6?
): "video" | "image" | undefined {
if (isUrlImage(url, contentType)) return "image";
if (isUrlVideo(url, contentType)) return "video";
}

// https://github.com/miguelmota/is-valid-hostname
Expand Down
24 changes: 20 additions & 4 deletions src/helpers/useSupported.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
import { compare } from "compare-versions";
import { CompareOperator, compare } from "compare-versions";
import { CommentSortType, PostSortType } from "lemmy-js-client";

import { lemmyVersionSelector } from "../features/auth/siteSlice";
import { useAppSelector } from "../store";
import { CommentSortType, PostSortType } from "lemmy-js-client";

const SUPPORTED_ON_OLDER_EXCLUSIVE = ">";
const SUPPORTED_ON_NEWER_INCLUSIVE = "<=";

/**
* What Lemmy version was support added?
*/
const featureVersionSupported = {
// "Instance Blocking": "0.19.0-rc.3",
// https://github.com/LemmyNet/lemmy-ui/issues/2796
"Fullsize thumbnails": ["0.19.6", SUPPORTED_ON_OLDER_EXCLUSIVE],
} as const;

type Feature = keyof typeof featureVersionSupported;
Expand All @@ -17,7 +22,18 @@ export default function useSupported(feature: Feature): boolean {

if (!lemmyVersion) return false;

return compare(featureVersionSupported[feature], lemmyVersion, "<=");
const supported = featureVersionSupported[feature];

let comparator: CompareOperator = SUPPORTED_ON_NEWER_INCLUSIVE;
let version: string;
if (typeof supported === "string") {
version = supported;
} else {
version = supported[0];
comparator = supported[1];
}

return compare(version, lemmyVersion, comparator);
}

export function is019Sort(
Expand Down

0 comments on commit 901d405

Please sign in to comment.