Skip to content

Commit

Permalink
feat: improves post parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
malcodeman committed Nov 19, 2024
1 parent 2965480 commit 37e2701
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 43 deletions.
11 changes: 3 additions & 8 deletions app/_components/Posts.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
"use client";
import { useEffect, useRef } from "react";
import { isEmpty, map, or } from "ramda";
import { map } from "ramda";
import { useIntersectionObserver } from "@react-hookz/web";
import Post from "@/app/_components/Post";
import { FiLoader } from "react-icons/fi";
import ServerError from "@/app/_components/ServerError";
import { usePosts } from "@/app/_hooks/usePosts";
import { getGalleryImages, isRedgifs } from "@/app/_lib/utils";
import { getGalleryImages } from "@/app/_lib/utils";

type Props = {
queryKey: string[];
Expand Down Expand Up @@ -54,16 +54,11 @@ export default function Posts(props: Props) {
(item) =>
map((item) => {
const gallery = getGalleryImages(item.data.media_metadata);
const previewUrl =
item.data.preview?.images?.[0]?.source.url ?? "";
const url = or(isEmpty(item.data.url), isRedgifs(item.data.url))
? previewUrl
: item.data.url;

return (
<Post
key={item.data.id}
url={item.data.is_gallery ? gallery[0] : url}
url={item.data.is_gallery ? gallery[0] : item.data.url}
isVideo={item.data.is_video}
href={item.data.permalink}
isGallery={item.data.is_gallery || false}
Expand Down
126 changes: 91 additions & 35 deletions app/_lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,37 +6,55 @@ import {
equals,
filter,
includes,
isNil,
isNotNil,
map,
or,
not,
replace,
values,
} from "ramda";
import {
SUPPORTED_FILE_EXTENSIONS,
SUPPORTED_VIDEO_EXTENSIONS,
} from "@/app/_lib/constants";

export const getExtension = (path: string) => {
return parse(path).ext;
};
import { SUPPORTED_FILE_EXTENSIONS } from "@/app/_lib/constants";

export const parseGifv = (url: string) => {
return replace("gifv", "mp4", url);
};
export const parsePost = (post: RedditPost) => {
if (hasRedditVideo(post)) {
return {
...post,
data: {
...post.data,
is_video: true,
url: post.data.media?.reddit_video?.fallback_url ?? "",
},
};
}

export const parsePost = (post: RedditPost): RedditPost => {
const { url } = post.data;
const extension = getExtension(url);
if (hasVideoPreview(post)) {
return {
...post,
data: {
...post.data,
is_video: true,
url: post.data.preview?.reddit_video_preview?.fallback_url ?? "",
},
};
}

if (includes(extension, SUPPORTED_VIDEO_EXTENSIONS)) {
if (isGifv(post)) {
return {
...post,
data: {
...post.data,
is_video: true,
url: equals(extension, ".gifv")
? post.data.preview?.reddit_video_preview?.fallback_url || ""
: url,
url: parseGifv(post.data.url),
},
};
}

if (hasImagePreview(post)) {
return {
...post,
data: {
...post.data,
url: post.data.preview?.images?.[0].source.url ?? "",
},
};
}
Expand All @@ -45,20 +63,31 @@ export const parsePost = (post: RedditPost): RedditPost => {
};

export const parsePosts = (posts: RedditPost[]) => {
return filter(
(item) =>
or(
includes(getExtension(item.data.url), SUPPORTED_FILE_EXTENSIONS),
and(
equals(item.data.is_gallery, true),
all(
(item) => equals(item.status, "valid"),
values(item.data.media_metadata ?? {}),
),
),
const isValidFileExtension = (url: string) =>
includes(getExtension(url), SUPPORTED_FILE_EXTENSIONS);
const isValidGallery = (item: RedditPost) =>
and(
equals(item.data.is_gallery, true),
all(
(item) => equals(item.status, "valid"),
values(item.data.media_metadata ?? {}),
),
posts,
);
);
const isImgurAndOver18 = (item: RedditPost) =>
and(isImgur(item.data.url), item.data.over_18);
const isRedgifsAndNoPreview = (item: RedditPost) =>
and(isRedgifs(item.data.url), isNil(item.data.preview));

return filter((item) => {
return and(
isValidFileExtension(item.data.url) ||
isValidGallery(item) ||
hasVideoPreview(item) ||
hasImagePreview(item) ||
hasRedditVideo(item),
not(isImgurAndOver18(item)) && not(isRedgifsAndNoPreview(item)),
);
}, posts);
};

export const parseComments = (comments: RedditComment[]) => {
Expand Down Expand Up @@ -86,12 +115,39 @@ export const getGalleryImages = (
);
};

export const isRedgifs = (url: string) => {
const getExtension = (path: string) => {
return parse(path).ext;
};

const isRedgifs = (url: string) => {
try {
const hostname = new URL(url).hostname;
return includes("redgifs.com", new URL(url).hostname);
} catch {
return false;
}
};

return includes("redgifs.com", hostname);
const isImgur = (url: string) => {
try {
return includes("imgur.com", new URL(url).hostname);
} catch {
return false;
}
};

const isGifv = (item: RedditPost) => {
return equals(getExtension(item.data.url), ".gifv");
};

const parseGifv = (url: string) => {
return replace("gifv", "mp4", url);
};

const hasVideoPreview = (item: RedditPost) =>
isNotNil(item.data.preview?.reddit_video_preview?.fallback_url);

const hasImagePreview = (item: RedditPost) =>
isNotNil(item.data.preview?.images?.[0].source.url);

const hasRedditVideo = (item: RedditPost) =>
isNotNil(item.data.media?.reddit_video?.fallback_url);
6 changes: 6 additions & 0 deletions types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ export type RedditPost = {
ups: number;
number: number;
created_utc: number;
over_18: boolean;
media: {
reddit_video?: {
fallback_url: string;
};
} | null;
};
};

Expand Down

0 comments on commit 37e2701

Please sign in to comment.