diff --git a/app/pages/PageEnigma/comps/ControlsTopButtons/LoadScene/LoadScene.tsx b/app/pages/PageEnigma/comps/ControlsTopButtons/LoadScene/LoadScene.tsx deleted file mode 100644 index 5c2b6d3640..0000000000 --- a/app/pages/PageEnigma/comps/ControlsTopButtons/LoadScene/LoadScene.tsx +++ /dev/null @@ -1,170 +0,0 @@ -import { useEffect, useRef, useState, useLayoutEffect } from "react"; -import { useSignals } from "@preact/signals-react/runtime"; -import dayjs from "dayjs"; - -import { MediaInfo } from "~/pages/PageEnigma/models"; -import { MediaFileType } from "~/pages/PageEnigma/enums"; -import { authentication } from "~/signals"; - -import { - GetMediaByUser, - GetMediaListResponse, -} from "~/api/media_files/GetMediaByUser"; -import { - ListFeaturedMediaFiles, - ListFeaturedMediaFilesResponse, -} from "~/api/media_files/ListFeaturedMediaFiles"; - -import { ScenePicker, SceneTypes } from "../ScenePicker"; -import { Label, LoadingSpinner } from "~/components"; - -interface LoadSceneProps { - onSceneSelect: (token: string) => void; -} - -export enum FetchStatus { - paused, - // ready triggers a new fetch - ready, - in_progress, - success, - error, -} - -export enum Filters { - Featured, - Mine, - Bookmarked, -} - -export const LoadScene = ({ onSceneSelect }: LoadSceneProps) => { - useSignals(); - const { userInfo } = authentication; - - const [scenes, setScenes] = useState([]); - const [featured, featuredSet] = useState([]); - - const sceneLoading = useRef(false); - const [isSceneLoading, setIsSceneLoading] = useState(true); - const [featuredStatus, featuredStatusSet] = useState(FetchStatus.ready); - useEffect(() => { - if (!userInfo.value || scenes.length || sceneLoading.current) { - return; - } - sceneLoading.current = true; - - const updateScenes = (results: MediaInfo[]) => - results.map((scene: MediaInfo) => ({ - token: scene.token, - name: scene.maybe_title ?? "Untitled", - updated_at: dayjs(scene.updated_at).format("MMM D, YYYY HH:mm:ss"), - thumbnail: scene.cover_image.maybe_cover_image_public_bucket_path - ? scene.cover_image.maybe_cover_image_public_bucket_path - : undefined, - })); - // console.log("load scene"); - GetMediaByUser( - userInfo.value.username, - {}, - { - filter_engine_categories: MediaFileType.Scene, - }, - ) - .then((res: GetMediaListResponse) => { - if (res.success && res.results) { - setScenes(updateScenes(res.results)); - setIsSceneLoading(false); - } - }) - .catch(() => { - return { - success: false, - error_reason: "Unknown error", - }; - }); - if (featuredStatus === FetchStatus.ready) { - featuredStatusSet(FetchStatus.in_progress); - ListFeaturedMediaFiles( - "", - {}, - { - filter_engine_categories: "scene", - page_size: 100, - }, - ).then((res: ListFeaturedMediaFilesResponse) => { - if (res.success && res.results) { - featuredStatusSet(FetchStatus.success); - featuredSet(updateScenes(res.results)); - } - }); - } - }, [featuredStatus, scenes, userInfo.value]); - - const handleSceneSelect = (selectedScene: SceneTypes) => { - onSceneSelect(selectedScene.token); - }; - const [bottomGradientOpacity, setBottomGradientOpacity] = useState(1); - const scrollContainerRef = useRef(null); - - const handleScroll = () => { - const element = scrollContainerRef.current; - if (element) { - const atBottom = - element.scrollHeight - element.scrollTop <= element.clientHeight + 1; - const hasOverflow = element.scrollHeight > element.clientHeight; - - setBottomGradientOpacity(hasOverflow && !atBottom ? 1 : 0); - } - }; - - useLayoutEffect(() => { - const element = scrollContainerRef.current; - if (element) { - handleScroll(); - element.addEventListener("scroll", handleScroll); - - return () => { - element.removeEventListener("scroll", handleScroll); - }; - } - }, [isSceneLoading]); - - return ( -
- -
- {isSceneLoading ? ( -
- - Loading scenes... -
- ) : ( - <> - {scenes.length !== 0 || featured.length !== 0 ? ( -
- -
- ) : ( -
- - You have no saved scenes yet. - -
- )} - - )} -
-
-
- ); -}; diff --git a/app/pages/PageEnigma/comps/ControlsTopButtons/LoadScene/index.tsx b/app/pages/PageEnigma/comps/ControlsTopButtons/LoadScene/index.tsx deleted file mode 100644 index c9c9d549fd..0000000000 --- a/app/pages/PageEnigma/comps/ControlsTopButtons/LoadScene/index.tsx +++ /dev/null @@ -1 +0,0 @@ -export { LoadScene } from "./LoadScene"; diff --git a/app/pages/PageEnigma/comps/ControlsTopButtons/LoadUserScenes/LoadUserScenes.tsx b/app/pages/PageEnigma/comps/ControlsTopButtons/LoadUserScenes/LoadUserScenes.tsx index f6e74c1aa0..13c1f0b43a 100644 --- a/app/pages/PageEnigma/comps/ControlsTopButtons/LoadUserScenes/LoadUserScenes.tsx +++ b/app/pages/PageEnigma/comps/ControlsTopButtons/LoadUserScenes/LoadUserScenes.tsx @@ -1,16 +1,23 @@ -import { useEffect, useLayoutEffect, useRef, useState } from "react"; +import { + useCallback, + useEffect, + useLayoutEffect, + useRef, + useState, +} from "react"; import dayjs from "dayjs"; import { MediaInfo } from "~/pages/PageEnigma/models"; -import { ToastTypes } from "~/enums"; +import { FilterEngineCategories, ToastTypes } from "~/enums"; import { addToast } from "~/signals"; -import { GetScenesByUser } from "./utilities"; import { ScenePicker, SceneTypes } from "../ScenePicker"; import { Label, LoadingSpinner } from "~/components"; +import { MediaFilesApi } from "~/Classes/ApiManager/MediaFilesApi"; + interface LoadSceneProps { onSceneSelect: (token: string) => void; } @@ -35,12 +42,7 @@ export const LoadUserScenes = ({ onSceneSelect }: LoadSceneProps) => { const scrollContainerRef = useRef(null); const [bottomGradientOpacity, setBottomGradientOpacity] = useState(1); - useEffect(() => { - if (scenes) { - //only call once on mount - return; - } - + const getScenesByUser = useCallback(async () => { const modMediaInfoToScenes = (results: MediaInfo[]) => results.map((scene: MediaInfo) => ({ token: scene.token, @@ -51,14 +53,27 @@ export const LoadUserScenes = ({ onSceneSelect }: LoadSceneProps) => { : undefined, })); - GetScenesByUser().then((res) => { - if ("results" in res) { - setScenes(modMediaInfoToScenes(res.results)); - return; - } - addToast(ToastTypes.ERROR, res.error_reason); + const mediaFilesApi = new MediaFilesApi(); + const response = await mediaFilesApi.ListUserMediaFiles({ + filter_engine_categories: [FilterEngineCategories.SCENE], }); - }, [scenes]); + if (response.success && response.data) { + setScenes(modMediaInfoToScenes(response.data)); + return; + } + addToast( + ToastTypes.ERROR, + response.errorMessage || "Unknown Error in Loading User Scenes", + ); + }, []); + + useEffect(() => { + if (scenes) { + //only call once on mount + return; + } + getScenesByUser(); + }, [scenes, getScenesByUser]); const handleSceneSelect = (selectedScene: SceneTypes) => { onSceneSelect(selectedScene.token); diff --git a/app/pages/PageEnigma/comps/ControlsTopButtons/LoadUserScenes/utilities.ts b/app/pages/PageEnigma/comps/ControlsTopButtons/LoadUserScenes/utilities.ts deleted file mode 100644 index 1839c6903b..0000000000 --- a/app/pages/PageEnigma/comps/ControlsTopButtons/LoadUserScenes/utilities.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { GetMediaListResponse } from "~/pages/PageEnigma/models"; -import { authentication, environmentVariables } from "~/signals"; - -const getMediaFilesByUsername = (username: string) => - `${environmentVariables.value.BASE_API}/v1/media_files/list/user/${username}?filter_media_type=scene_json`; - -export const GetScenesByUser = () => { - const unknownError = { - success: false, - error_reason: "Unknown error in Loading User Scenes", - }; - if (!authentication.userInfo.value) { - return new Promise((resolve) => { - resolve(unknownError); - }); - } - - const endpoint = getMediaFilesByUsername( - authentication.userInfo.value.username, - ); - - return fetch(endpoint, { - method: "GET", - headers: { - Accept: "application/json", - }, - credentials: "include", - }) - .then((res) => res.json()) - .then((res: GetMediaListResponse) => { - return res; - }) - .catch(() => { - return unknownError; - }); -}; diff --git a/app/pages/PageEnigma/comps/ControlsTopButtons/NewSceneFromTemplate/NewSceneFromTemplate.tsx b/app/pages/PageEnigma/comps/ControlsTopButtons/NewSceneFromTemplate/NewSceneFromTemplate.tsx index a4e9e0eb09..1effdecbc5 100644 --- a/app/pages/PageEnigma/comps/ControlsTopButtons/NewSceneFromTemplate/NewSceneFromTemplate.tsx +++ b/app/pages/PageEnigma/comps/ControlsTopButtons/NewSceneFromTemplate/NewSceneFromTemplate.tsx @@ -1,10 +1,20 @@ -import { useEffect, useLayoutEffect, useRef, useState } from "react"; +import { + useCallback, + useEffect, + useLayoutEffect, + useRef, + useState, +} from "react"; import dayjs from "dayjs"; import { MediaInfo } from "~/pages/PageEnigma/models"; +import { FilterEngineCategories, ToastTypes } from "~/enums"; import { ScenePicker, SceneTypes } from "../ScenePicker"; -import { ListFeaturedScenes } from "./utilities"; +import { LoadingSpinner } from "~/components"; + +import { MediaFilesApi } from "~/Classes/ApiManager/MediaFilesApi"; +import { addToast } from "~/signals"; interface NewSceneFromTemplateProps { onSceneSelect: (token: string) => void; @@ -13,16 +23,16 @@ interface NewSceneFromTemplateProps { export const NewSceneFromTemplate = ({ onSceneSelect, }: NewSceneFromTemplateProps) => { - const [featuredScenes, setFeaturedScenes] = useState([]); + const [featuredScenes, setFeaturedScenes] = useState< + SceneTypes[] | undefined + >(undefined); const [bottomGradientOpacity, setBottomGradientOpacity] = useState(1); const scrollContainerRef = useRef(null); - useEffect(() => { - if (featuredScenes.length > 0) { - //only call once on mount - return; - } + const listFeaturedScenes = useCallback(async () => { + const mediaFilesApi = new MediaFilesApi(); // Hard coded scenes + const dummyScenes: SceneTypes[] = [ { token: "m_nmzvdqr6kr8eqpmxqdzkqj0yknrjwv", @@ -30,7 +40,6 @@ export const NewSceneFromTemplate = ({ thumbnail: "/resources/placeholders/scene_placeholder.png", }, ]; - const modMediaInfoToScenes = (results: MediaInfo[]) => results.map((scene: MediaInfo) => ({ token: scene.token, @@ -40,18 +49,29 @@ export const NewSceneFromTemplate = ({ ? scene.cover_image.maybe_cover_image_public_bucket_path : undefined, })); - - ListFeaturedScenes().then((res) => { - if (res.success && "results" in res) { - setFeaturedScenes([ - ...modMediaInfoToScenes(res.results), - ...dummyScenes, - ]); - return; - } - setFeaturedScenes(dummyScenes); + const response = await mediaFilesApi.ListFeaturedMediaFiles({ + filter_engine_categories: [FilterEngineCategories.SCENE], }); - }, [featuredScenes]); + if (response.success && response.data) { + setFeaturedScenes([ + ...modMediaInfoToScenes(response.data), + ...dummyScenes, + ]); + return; + } + setFeaturedScenes(dummyScenes); + addToast( + ToastTypes.ERROR, + response.errorMessage || "Unknown Error in Listing Feature Scenes", + ); + }, []); + useEffect(() => { + if (featuredScenes) { + //only call once on mount + return; + } + listFeaturedScenes(); + }, [featuredScenes, listFeaturedScenes]); const handleSceneSelect = (selectedScene: SceneTypes) => { onSceneSelect(selectedScene.token); @@ -83,15 +103,23 @@ export const NewSceneFromTemplate = ({ return (
-
- -
+ {!featuredScenes && ( +
+ + Loading scenes... +
+ )} + {featuredScenes && ( +
+ +
+ )}
- `${environmentVariables.value.BASE_API}/v1/media_files/list_featured?filter_media_type=scene_json`; - -export const ListFeaturedScenes = () => { - const unknownError = { - success: false, - error_reason: "Unknown error in Loading Featured Scenes", - }; - const endpoint = listFeaturedScenes(); - - return fetch(endpoint, { - method: "GET", - headers: { - Accept: "application/json", - }, - credentials: "include", - }) - .then((res) => res.json()) - .then((res: ListFeaturedMediaFilesResponse) => { - return res; - }) - .catch(() => { - return unknownError; - }); -};