Skip to content

Commit

Permalink
Moooore progress
Browse files Browse the repository at this point in the history
  • Loading branch information
aeharding committed Dec 3, 2024
1 parent a826a20 commit 12f66d7
Show file tree
Hide file tree
Showing 10 changed files with 54 additions and 29 deletions.
2 changes: 1 addition & 1 deletion src/features/media/InlineMedia.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export default function InlineMedia({
src={src}
className={cx(mediaPlaceholderStyles.media, mediaClassName)}
style={buildStyle()}
ref={mediaRef}
ref={mediaRef as React.Ref<HTMLImageElement>}
onError={() => {
if (src) dispatch(imageFailed(src));
}}
Expand Down
2 changes: 1 addition & 1 deletion src/features/media/external/redgifs/redgifsSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ export const getVideoSrc = createAsyncThunk(
export const initializeIfNeeded = createAsyncThunk(
"redgifs/initialize",
async (_, { dispatch }) => {
const providerData = await db.getProvider("redgifs");
const providerData = (await db.getProvider("redgifs")) as RedgifsProvider;

if (!providerData) return;

Expand Down
8 changes: 4 additions & 4 deletions src/features/media/gallery/GalleryMedia.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
import { PostView } from "lemmy-js-client";
import { PreparedPhotoSwipeOptions } from "photoswipe";
import { ComponentProps, HTMLProps, MouseEvent, useContext } from "react";
import { ComponentProps, MouseEvent, useContext } from "react";

import useShouldAutoplay from "#/core/listeners/network/useShouldAutoplay";
import { useAutohidePostIfNeeded } from "#/features/feed/PageTypeContext";
import Video, { VideoProps } from "#/features/media/video/Video";
import { isUrlPotentialAnimatedImage, isUrlVideo } from "#/helpers/url";

import Video from "../video/Video";
import GalleryGif from "./GalleryGif";
import GalleryImg from "./GalleryImg";
import { GalleryContext } from "./GalleryProvider";

export interface GalleryMediaProps
extends Omit<HTMLProps<HTMLImageElement>, "ref" | "onClick"> {
export interface GalleryMediaProps extends Omit<VideoProps, "ref" | "src"> {
src?: string;
alt?: string;
className?: string;
Expand Down Expand Up @@ -80,6 +79,7 @@ export default function GalleryMedia({
return (
<Video
{...props}
src={props.src!}
controls={controls}
shouldPortal={shouldPortal}
volume={volume}
Expand Down
19 changes: 16 additions & 3 deletions src/features/media/gallery/GalleryProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { createPortal } from "react-dom";
import * as portals from "react-reverse-portal";
import { useLocation } from "react-router";

import Player from "#/features/media/video/Player";
import { useVideoPortalNode } from "#/features/media/video/VideoPortalProvider";
import { findBlurOverlayContainer } from "#/features/post/inFeed/large/media/BlurOverlayMessage";
import { setPostRead } from "#/features/post/postSlice";
Expand All @@ -40,6 +41,7 @@ interface IGalleryContext {
}

export const GalleryContext = createContext<IGalleryContext>({
// eslint-disable-next-line no-empty-function
open: async () => {},
close: noop,
});
Expand Down Expand Up @@ -146,7 +148,7 @@ export default function GalleryProvider({ children }: React.PropsWithChildren) {
showHideAnimationType: animationType ?? "fade",
zoom: false,
bgOpacity: 1,
preloadFirstSlide: false,
showAnimationDuration: thumbEl instanceof HTMLVideoElement ? 0 : 333,
// Put in ion-app element so share IonActionSheet is on top
appendToEl: document.querySelector("ion-app")!,
paddingFn: () => getSafeArea(),
Expand Down Expand Up @@ -186,13 +188,17 @@ export default function GalleryProvider({ children }: React.PropsWithChildren) {
e.preventDefault();

e.content.element = document.createElement("div");
e.content.type = "image"; // allow zoom
e.content.type = "video"; // allow zoom

e.content.state = "loaded";
e.content.onLoaded();
}
});

instance.addFilter("isContentZoomable", (isContentZoomable, content) => {
return isContentZoomable || content.type === "video";
});

instance.addFilter("useContentPlaceholder", (useContentPlaceholder) => {
if (thumbEl instanceof HTMLVideoElement) return false;

Expand Down Expand Up @@ -456,7 +462,14 @@ export default function GalleryProvider({ children }: React.PropsWithChildren) {

{videoContainer !== null && portalNode
? createPortal(
<portals.OutPortal node={portalNode} src={videoSrc} autoPlay />,
<portals.OutPortal<typeof Player>
node={portalNode}
src={videoSrc}
pauseWhenNotInView={false}
controls={false}
progress={false}
volume={false}
/>,
videoContainer,
)
: undefined}
Expand Down
6 changes: 3 additions & 3 deletions src/features/media/useMediaLoadObserver.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { ComponentRef, useEffect, useRef } from "react";

import { imageLoaded } from "#/features/media/imageSlice";
import type Media from "#/features/media/Media";
import { useAppDispatch } from "#/store";

import type GalleryMedia from "./gallery/GalleryMedia";
import useAspectRatio, { isLoadedAspectRatio } from "./useAspectRatio";

export default function useMediaLoadObserver(src: string | undefined) {
const dispatch = useAppDispatch();
const aspectRatio = useAspectRatio(src);
const mediaRef = useRef<ComponentRef<typeof Media>>(null);
const mediaRef = useRef<ComponentRef<typeof GalleryMedia>>(null);
const resizeObserverRef = useRef<ResizeObserver | undefined>();

useEffect(() => {
Expand Down Expand Up @@ -61,7 +61,7 @@ export default function useMediaLoadObserver(src: string | undefined) {
return [mediaRef, aspectRatio] as const;
}

export function getTargetDimensions(target: ComponentRef<typeof Media>) {
export function getTargetDimensions(target: ComponentRef<typeof GalleryMedia>) {
let width, height;

switch (true) {
Expand Down
2 changes: 2 additions & 0 deletions src/features/media/video/Player.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
overflow: hidden;

display: flex;

width: 100%; /* needed for iOS zoom in photoswipe */
}

.progress {
Expand Down
12 changes: 10 additions & 2 deletions src/features/media/video/Player.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { getVideoSrcForUrl } from "#/helpers/url";

import styles from "./Player.module.css";

export interface PlayerProps {
export interface PlayerProps extends React.HTMLProps<HTMLElement> {
src: string;

controls?: boolean;
Expand All @@ -31,6 +31,8 @@ export interface PlayerProps {
style?: CSSProperties;
alt?: string;

pauseWhenNotInView?: boolean;

ref?: React.RefObject<HTMLVideoElement>;
}

Expand All @@ -41,6 +43,7 @@ export default function Player({
progress: showProgress = !controls,
volume = true,
autoPlay: videoAllowedToAutoplay = true,
pauseWhenNotInView = true,
ref,
...rest
}: PlayerProps) {
Expand Down Expand Up @@ -102,13 +105,18 @@ export default function Player({

useEffect(() => {
if (!videoRef.current) return;
if (!pauseWhenNotInView) {
if (autoPlay) resume();

return;
}

if (inView) {
resume();
} else {
pause();
}
}, [inView, pause, resume]);
}, [inView, pause, resume, pauseWhenNotInView, autoPlay]);

return (
<span className={cx(styles.container, className)}>
Expand Down
25 changes: 14 additions & 11 deletions src/features/media/video/VideoPortalProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useIonViewWillEnter } from "@ionic/react";
import { last, noop } from "es-toolkit";
import { last, noop, without } from "es-toolkit";
import {
createContext,
useContext,
Expand Down Expand Up @@ -33,8 +33,9 @@ export default function VideoPortalProvider({
...videoRefs,
[src]: {
...potentialExisting,
// most recently used (currently playing location) is last
sourceUids: [
...potentialExisting.sourceUids.filter((id) => id !== sourceUid),
...without(potentialExisting.sourceUids, sourceUid),
sourceUid,
],
},
Expand All @@ -61,15 +62,18 @@ export default function VideoPortalProvider({
function cleanupPortalNodeForSrcIfNeeded(src: string, sourceUid: string) {
const videoRefs = videoRefsRef.current;

const videoRef = videoRefs[src];

if (!videoRef) return;

// Portal was handed off to another OutPortal.
// Some other portal outlet is controlling, so not responsible for cleanup
if (
videoRefs[src]?.sourceUids &&
last(videoRefs[src]?.sourceUids) !== sourceUid
)
return;
if (videoRef.sourceUids && last(videoRef.sourceUids) !== sourceUid) return;

if (videoRefs[src]?.sourceUids.length === 1) {
if (
videoRef.sourceUids.length === 1 &&
videoRef.sourceUids[0] === sourceUid
) {
setVideoRefs((videoRefs) => {
const updatedVideoRefs = { ...videoRefs };
delete updatedVideoRefs[src];
Expand All @@ -79,9 +83,8 @@ export default function VideoPortalProvider({
setVideoRefs((videoRefs) => ({
...videoRefs,
[src]: {
...videoRefs[src],
sourceUids:
videoRefs[src]?.sourceUids?.filter((id) => id !== sourceUid) ?? [],
...videoRef,
sourceUids: without(videoRef.sourceUids, sourceUid),
},
}));
}
Expand Down
2 changes: 1 addition & 1 deletion src/features/post/inFeed/large/media/BlurOverlay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import BlurOverlayMessage from "./BlurOverlayMessage";
import styles from "./BlurOverlay.module.css";

interface BlurOverlayProps extends React.PropsWithChildren {
src: string;
src: string | undefined;
}

export default function BlurOverlay({ src, children }: BlurOverlayProps) {
Expand Down
5 changes: 2 additions & 3 deletions src/features/shared/markdown/MarkdownImg.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { GalleryMediaProps } from "#/features/media/gallery/GalleryMedia";
import InlineMedia from "#/features/media/InlineMedia";
import InlineMedia, { InlineMediaProps } from "#/features/media/InlineMedia";
import { cx } from "#/helpers/css";

import styles from "./MarkdownImg.module.css";

interface MarkdownImgProps extends Omit<GalleryMediaProps, "ref"> {
interface MarkdownImgProps extends Omit<InlineMediaProps, "ref"> {
/**
* Restrict height of media within comments (unrestricted in post body)
*/
Expand Down

0 comments on commit 12f66d7

Please sign in to comment.