Skip to content

Commit

Permalink
Merge pull request #23 from varun-raj/improvements
Browse files Browse the repository at this point in the history
fix: minor ux improvements and video player support
  • Loading branch information
varun-raj authored Aug 28, 2024
2 parents 9d259b5 + 3be8938 commit 8d43cfb
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 31 deletions.
71 changes: 42 additions & 29 deletions src/components/albums/potential-albums/PotentialAlbumsAssets.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ import { listPotentialAlbumsAssets } from "@/handlers/api/album.handler";
import { IAsset } from "@/types/asset";
import React, { useEffect, useMemo, useState } from "react";
import { Gallery } from "react-grid-gallery";
import Lightbox from "yet-another-react-lightbox";
import Lightbox, { SlideImage, SlideTypes } from "yet-another-react-lightbox";
import Captions from "yet-another-react-lightbox/plugins/captions";
import { CalendarArrowDown, CalendarArrowUp, Hourglass } from "lucide-react";

import Video from "yet-another-react-lightbox/plugins/video";
export default function PotentialAlbumsAssets() {
const { startDate, selectedIds, assets, updateContext } = usePotentialAlbumContext();
const { startDate, selectedIds, assets, updateContext } =
usePotentialAlbumContext();

const [loading, setLoading] = useState(false);
const [errorMessage, setErrorMessage] = useState<string | null>(null);
Expand All @@ -20,7 +21,7 @@ export default function PotentialAlbumsAssets() {
setLoading(true);
updateContext({
assets: [],
})
});
return listPotentialAlbumsAssets({ startDate })
.then((assets) => updateContext({ assets }))
.catch(setErrorMessage)
Expand All @@ -40,52 +41,65 @@ export default function PotentialAlbumsAssets() {

const slides = useMemo(
() =>
images.map(({ original, width, height }) => ({
images.map(({ original, width, height, type, videoURL }) => ({
src: original,
width,
height,
type: (type === "VIDEO" ? "video" : "image") as any,
sources:
type === "VIDEO"
? [
{
src: videoURL,
type: "video/mp4",
},
]
: [],
})),
[images]
);

const handleClick = (idx: number) => setIndex(idx);

const handleSelect = (_idx: number, asset: IAsset) => {
const isPresent =selectedIds.includes(asset.id)
if(isPresent){
updateContext({selectedIds:selectedIds.filter((id)=>id!==asset.id)})
}
else{
updateContext({selectedIds:[...selectedIds,asset.id]})
const isPresent = selectedIds.includes(asset.id);
if (isPresent) {
updateContext({
selectedIds: selectedIds.filter((id) => id !== asset.id),
});
} else {
updateContext({ selectedIds: [...selectedIds, asset.id] });
}

};

useEffect(() => {
if (startDate) fetchAssets();
}, [startDate]);

if (loading) return (
<div className="flex flex-col gap-2 h-full justify-center items-center w-full">
<Hourglass />
<p className="text-lg">Loading...</p>
</div>
)
if (loading)
return (
<div className="flex flex-col gap-2 min-h-full justify-center items-center w-full">
<Hourglass />
<p className="text-lg">Loading...</p>
</div>
);

if (!startDate) return (
<div className="flex flex-col gap-2 h-full justify-center items-center w-full">
<CalendarArrowUp />
<p className="text-lg">Please select a date</p>
<p className="text-sm">
When you select a date from the left, you will see all the orphan assets captured on that date
</p>
</div>
)
if (!startDate)
return (
<div className="flex flex-col gap-2 min-h-full justify-center items-center w-full">
<CalendarArrowUp />
<p className="text-lg">Please select a date</p>
<p className="text-sm text-zinc-700">
When you select a date from the left, you will see all the orphan
assets captured on that date
</p>
</div>
);
return (
<>
<Lightbox
slides={slides}
plugins={[Captions]}
plugins={[Captions, Video]}
open={index >= 0}
index={index}
close={() => setIndex(-1)}
Expand All @@ -96,7 +110,6 @@ export default function PotentialAlbumsAssets() {
onClick={handleClick}
enableImageSelection={true}
onSelect={handleSelect}

/>
</div>
</>
Expand Down
3 changes: 2 additions & 1 deletion src/config/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,5 @@ export const LIST_MISSING_LOCATION_DATES_PATH = BASE_API_ENDPOINT + "/assets/mis
export const LIST_MISSING_LOCATION_ASSETS_PATH = BASE_API_ENDPOINT + "/assets/missing-location-assets";

export const ASSET_THUMBNAIL_PATH = (id: string) => BASE_PROXY_ENDPOINT + "/asset/thumbnail/" + id;
export const ASSET_PREVIEW_PATH = (id: string) => BASE_PROXY_ENDPOINT + "/asset/thumbnail/" + id + "?size=preview";
export const ASSET_PREVIEW_PATH = (id: string) => BASE_PROXY_ENDPOINT + "/asset/thumbnail/" + id + "?size=preview";
export const ASSET_VIDEO_PATH = (id: string) => BASE_PROXY_ENDPOINT + "/asset/video/" + id;
3 changes: 2 additions & 1 deletion src/helpers/asset.helper.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ASSET_PREVIEW_PATH, ASSET_THUMBNAIL_PATH, PERSON_THUBNAIL_PATH } from "@/config/routes"
import { ASSET_PREVIEW_PATH, ASSET_THUMBNAIL_PATH, ASSET_VIDEO_PATH, PERSON_THUBNAIL_PATH } from "@/config/routes"
import { IPerson } from "@/types/person"
import { parseDate } from "./date.helper"
import { IAsset } from "@/types/asset"
Expand All @@ -9,5 +9,6 @@ export const cleanUpAsset = (asset: IAsset): IAsset => {
...asset,
url: ASSET_THUMBNAIL_PATH(asset.id),
previewUrl: ASSET_PREVIEW_PATH(asset.id),
videoURL: ASSET_VIDEO_PATH(asset.id),
}
}
48 changes: 48 additions & 0 deletions src/pages/api/immich-proxy/asset/video/[id].ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// pages/api/proxy.js

import { ENV } from '@/config/environment';
import { NextApiRequest, NextApiResponse } from 'next'

export const config = {
api: {
bodyParser: false,
},
}

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
if (req.method !== 'GET') {
return res.status(405).json({ message: 'Method Not Allowed' })
}

const { id } = req.query;
const targetUrl = `${ENV.IMMICH_URL}/api/assets/${id}/original`;

try {
// Forward the request to the target API
const response = await fetch(targetUrl, {
method: 'GET',
headers: {
'Content-Type': 'application/octet-stream',
'x-api-key': ENV.IMMICH_API_KEY,
},
})

if (!response.ok) {
console.error('HTTP error:', response)
throw new Error(`HTTP error! status: ${response.status}`)
}

// Get the image data from the response
const imageBuffer = await response.arrayBuffer()

// Set the appropriate headers for the image response
res.setHeader('Content-Type', response.headers.get('Content-Type') || 'image/png')
res.setHeader('Content-Length', imageBuffer.byteLength)

// Send the image data
res.send(Buffer.from(imageBuffer))
} catch (error) {
console.error('Error:', error)
res.status(500).json({ message: 'Internal Server Error' })
}
}
1 change: 1 addition & 0 deletions src/types/asset.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export interface IAsset {
exifImageHeight: number;
url: string;
previewUrl: string;
videoURL?: string;
}

export interface IAssetThumbhash {
Expand Down

0 comments on commit 8d43cfb

Please sign in to comment.