📏 Fixes for responsiveness
This commit is contained in:
@@ -34,6 +34,11 @@ import { styled } from "styled-components";
|
|||||||
import { COMICVINE_SERVICE_URI } from "../../constants/endpoints";
|
import { COMICVINE_SERVICE_URI } from "../../constants/endpoints";
|
||||||
import { refineQuery } from "filename-parser";
|
import { refineQuery } from "filename-parser";
|
||||||
|
|
||||||
|
// overridden <SlidingPanel> with some styles - moved outside component to prevent recreation
|
||||||
|
const StyledSlidingPanel = styled(SlidingPane)`
|
||||||
|
background: #ccc;
|
||||||
|
`;
|
||||||
|
|
||||||
interface ComicDetailProps {
|
interface ComicDetailProps {
|
||||||
data: {
|
data: {
|
||||||
_id: string;
|
_id: string;
|
||||||
@@ -98,11 +103,7 @@ export const ComicDetail = (data: ComicDetailProps): ReactElement => {
|
|||||||
// );
|
// );
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// overridden <SlidingPanel> with some styles
|
const afterOpenModal = useCallback((things: any) => {
|
||||||
const StyledSlidingPanel = styled(SlidingPane)`
|
|
||||||
background: #ccc;
|
|
||||||
`;
|
|
||||||
const afterOpenModal = useCallback((things) => {
|
|
||||||
// references are now sync'd and can be accessed.
|
// references are now sync'd and can be accessed.
|
||||||
// subtitle.style.color = "#f00";
|
// subtitle.style.color = "#f00";
|
||||||
console.log("kolaveri", things);
|
console.log("kolaveri", things);
|
||||||
|
|||||||
@@ -14,34 +14,41 @@ import { useStore } from "../../../store";
|
|||||||
import { useShallow } from "zustand/react/shallow";
|
import { useShallow } from "zustand/react/shallow";
|
||||||
import { escapePoundSymbol } from "../../../shared/utils/formatting.utils";
|
import { escapePoundSymbol } from "../../../shared/utils/formatting.utils";
|
||||||
|
|
||||||
export const ArchiveOperations = (props): ReactElement => {
|
export const ArchiveOperations = (props: { data: any }): ReactElement => {
|
||||||
const { data } = props;
|
const { data } = props;
|
||||||
|
|
||||||
const { socketIOInstance } = useStore(
|
const getSocket = useStore((state) => state.getSocket);
|
||||||
useShallow((state) => ({
|
|
||||||
socketIOInstance: state.socketIOInstance,
|
|
||||||
})),
|
|
||||||
);
|
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
// sliding panel config
|
// sliding panel config
|
||||||
const [visible, setVisible] = useState(false);
|
const [visible, setVisible] = useState(false);
|
||||||
const [slidingPanelContentId, setSlidingPanelContentId] = useState("");
|
const [slidingPanelContentId, setSlidingPanelContentId] = useState("");
|
||||||
// current image
|
// current image
|
||||||
const [currentImage, setCurrentImage] = useState([]);
|
const [currentImage, setCurrentImage] = useState<string>("");
|
||||||
const [uncompressedArchive, setUncompressedArchive] = useState([]);
|
const [uncompressedArchive, setUncompressedArchive] = useState<string[]>([]);
|
||||||
const [imageAnalysisResult, setImageAnalysisResult] = useState({});
|
const [imageAnalysisResult, setImageAnalysisResult] = useState<any>({});
|
||||||
const [shouldRefetchComicBookData, setShouldRefetchComicBookData] =
|
const [shouldRefetchComicBookData, setShouldRefetchComicBookData] =
|
||||||
useState(false);
|
useState(false);
|
||||||
const constructImagePaths = (data): Array<string> => {
|
const constructImagePaths = (data: string[]): Array<string> => {
|
||||||
return data?.map((path: string) =>
|
return data?.map((path: string) =>
|
||||||
escapePoundSymbol(encodeURI(`${LIBRARY_SERVICE_HOST}/${path}`)),
|
escapePoundSymbol(encodeURI(`${LIBRARY_SERVICE_HOST}/${path}`)),
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Listen to the uncompression complete event and orchestrate the final payload
|
// Listen to the uncompression complete event and orchestrate the final payload
|
||||||
socketIOInstance.on("LS_UNCOMPRESSION_JOB_COMPLETE", (data) => {
|
useEffect(() => {
|
||||||
setUncompressedArchive(constructImagePaths(data?.uncompressedArchive));
|
const socket = getSocket("/");
|
||||||
});
|
if (!socket) return;
|
||||||
|
|
||||||
|
const handleUncompressionComplete = (data: any) => {
|
||||||
|
setUncompressedArchive(constructImagePaths(data?.uncompressedArchive));
|
||||||
|
};
|
||||||
|
|
||||||
|
socket.on("LS_UNCOMPRESSION_JOB_COMPLETE", handleUncompressionComplete);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
socket.off("LS_UNCOMPRESSION_JOB_COMPLETE", handleUncompressionComplete);
|
||||||
|
};
|
||||||
|
}, [getSocket]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let isMounted = true;
|
let isMounted = true;
|
||||||
@@ -58,7 +65,7 @@ export const ArchiveOperations = (props): ReactElement => {
|
|||||||
},
|
},
|
||||||
transformResponse: async (responseData) => {
|
transformResponse: async (responseData) => {
|
||||||
const parsedData = JSON.parse(responseData);
|
const parsedData = JSON.parse(responseData);
|
||||||
const paths = parsedData.map((pathObject) => {
|
const paths = parsedData.map((pathObject: any) => {
|
||||||
return `${pathObject.containedIn}/${pathObject.name}${pathObject.extension}`;
|
return `${pathObject.containedIn}/${pathObject.name}${pathObject.extension}`;
|
||||||
});
|
});
|
||||||
const uncompressedArchive = constructImagePaths(paths);
|
const uncompressedArchive = constructImagePaths(paths);
|
||||||
@@ -131,7 +138,7 @@ export const ArchiveOperations = (props): ReactElement => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// sliding panel init
|
// sliding panel init
|
||||||
const contentForSlidingPanel = {
|
const contentForSlidingPanel: Record<string, { content: () => JSX.Element }> = {
|
||||||
imageAnalysis: {
|
imageAnalysis: {
|
||||||
content: () => {
|
content: () => {
|
||||||
return (
|
return (
|
||||||
@@ -143,7 +150,7 @@ export const ArchiveOperations = (props): ReactElement => {
|
|||||||
</pre>
|
</pre>
|
||||||
) : null}
|
) : null}
|
||||||
<pre className="font-hasklig mt-3 text-sm">
|
<pre className="font-hasklig mt-3 text-sm">
|
||||||
{JSON.stringify(imageAnalysisResult.analyzedData, null, 2)}
|
{JSON.stringify(imageAnalysisResult?.analyzedData, null, 2)}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@@ -152,7 +159,7 @@ export const ArchiveOperations = (props): ReactElement => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// sliding panel handlers
|
// sliding panel handlers
|
||||||
const openImageAnalysisPanel = useCallback((imageFilePath) => {
|
const openImageAnalysisPanel = useCallback((imageFilePath: string) => {
|
||||||
setSlidingPanelContentId("imageAnalysis");
|
setSlidingPanelContentId("imageAnalysis");
|
||||||
analyzeImage(imageFilePath);
|
analyzeImage(imageFilePath);
|
||||||
setCurrentImage(imageFilePath);
|
setCurrentImage(imageFilePath);
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
import { isUndefined } from "lodash";
|
import { isUndefined } from "lodash";
|
||||||
import React, { ReactElement } from "react";
|
import React, { ReactElement } from "react";
|
||||||
|
|
||||||
export const ComicInfoXML = (data): ReactElement => {
|
export const ComicInfoXML = (data: { json: any }): ReactElement => {
|
||||||
const { json } = data;
|
const { json } = data;
|
||||||
return (
|
return (
|
||||||
<div className="flex md:w-4/5 lg:w-78">
|
<div className="flex md:w-4/5 lg:w-78">
|
||||||
<dl className="dark:bg-yellow-600 bg-yellow-200 p-3 rounded-lg">
|
<dl className="dark:bg-yellow-600 bg-yellow-200 p-3 rounded-lg">
|
||||||
<dt>
|
<dt>
|
||||||
<p className="text-lg">{json.series[0]}</p>
|
<p className="text-lg">{json.series?.[0]}</p>
|
||||||
</dt>
|
</dt>
|
||||||
<dd className="text-sm">
|
<dd className="text-sm">
|
||||||
published by{" "}
|
published by{" "}
|
||||||
<span className="underline">
|
<span className="underline">
|
||||||
{json.publisher[0]}
|
{json.publisher?.[0]}
|
||||||
<i className="icon-[solar--arrow-right-up-outline] w-4 h-4" />
|
<i className="icon-[solar--arrow-right-up-outline] w-4 h-4" />
|
||||||
</span>
|
</span>
|
||||||
</dd>
|
</dd>
|
||||||
@@ -30,18 +30,20 @@ export const ComicInfoXML = (data): ReactElement => {
|
|||||||
</span>
|
</span>
|
||||||
</dd>
|
</dd>
|
||||||
)}
|
)}
|
||||||
<dd className="my-2">
|
{/* Genre */}
|
||||||
{/* Genre */}
|
{!isUndefined(json.genre) && (
|
||||||
<span className="inline-flex items-center bg-slate-50 text-slate-800 text-sm font-medium px-2 rounded-md dark:text-slate-900 dark:bg-slate-400">
|
<dd className="my-2">
|
||||||
<span className="pr-1 pt-1">
|
<span className="inline-flex items-center bg-slate-50 text-slate-800 text-sm font-medium px-2 rounded-md dark:text-slate-900 dark:bg-slate-400">
|
||||||
<i className="icon-[solar--sticker-smile-circle-bold-duotone] w-5 h-5"></i>
|
<span className="pr-1 pt-1">
|
||||||
</span>
|
<i className="icon-[solar--sticker-smile-circle-bold-duotone] w-5 h-5"></i>
|
||||||
|
</span>
|
||||||
|
|
||||||
<span className="text-slate-500 dark:text-slate-900">
|
<span className="text-slate-500 dark:text-slate-900">
|
||||||
{json.genre[0]}
|
{json.genre[0]}
|
||||||
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</dd>
|
||||||
</dd>
|
)}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<dd className="my-1">
|
<dd className="my-1">
|
||||||
@@ -52,12 +54,14 @@ export const ComicInfoXML = (data): ReactElement => {
|
|||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
</dd>
|
</dd>
|
||||||
<dd>
|
{!isUndefined(json.notes) && (
|
||||||
{/* Notes */}
|
<dd>
|
||||||
<span className="text-sm text-slate-500 dark:text-slate-900">
|
{/* Notes */}
|
||||||
{json.notes[0]}
|
<span className="text-sm text-slate-500 dark:text-slate-900">
|
||||||
</span>
|
{json.notes[0]}
|
||||||
</dd>
|
</span>
|
||||||
|
</dd>
|
||||||
|
)}
|
||||||
</dl>
|
</dl>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import {
|
|||||||
} from "../../shared/utils/metadata.utils";
|
} from "../../shared/utils/metadata.utils";
|
||||||
import { LIBRARY_SERVICE_HOST } from "../../constants/endpoints";
|
import { LIBRARY_SERVICE_HOST } from "../../constants/endpoints";
|
||||||
import Header from "../shared/Header";
|
import Header from "../shared/Header";
|
||||||
|
import useEmblaCarousel from "embla-carousel-react";
|
||||||
|
|
||||||
type RecentlyImportedProps = {
|
type RecentlyImportedProps = {
|
||||||
comics: any;
|
comics: any;
|
||||||
@@ -19,6 +20,15 @@ export const RecentlyImported = (
|
|||||||
comics: RecentlyImportedProps,
|
comics: RecentlyImportedProps,
|
||||||
): ReactElement => {
|
): ReactElement => {
|
||||||
console.log(comics);
|
console.log(comics);
|
||||||
|
|
||||||
|
// embla carousel
|
||||||
|
const [emblaRef, emblaApi] = useEmblaCarousel({
|
||||||
|
loop: false,
|
||||||
|
align: "start",
|
||||||
|
containScroll: "trimSnaps",
|
||||||
|
slidesToScroll: 1,
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Header
|
<Header
|
||||||
@@ -26,8 +36,10 @@ export const RecentlyImported = (
|
|||||||
subHeaderContent="Recent Library activity such as imports, tagging, etc."
|
subHeaderContent="Recent Library activity such as imports, tagging, etc."
|
||||||
iconClassNames="fa-solid fa-binoculars mr-2"
|
iconClassNames="fa-solid fa-binoculars mr-2"
|
||||||
/>
|
/>
|
||||||
<div className="grid grid-cols-5 gap-6 mt-3">
|
<div className="overflow-hidden -mr-4 sm:-mr-8 lg:-mr-16 xl:-mr-20 2xl:-mr-24 mt-3">
|
||||||
{comics?.comics.map(
|
<div className="overflow-hidden" ref={emblaRef}>
|
||||||
|
<div className="flex">
|
||||||
|
{comics?.comics.map(
|
||||||
(
|
(
|
||||||
{
|
{
|
||||||
_id,
|
_id,
|
||||||
@@ -56,13 +68,16 @@ export const RecentlyImported = (
|
|||||||
!isUndefined(comicvine) &&
|
!isUndefined(comicvine) &&
|
||||||
!isUndefined(comicvine.volumeInformation);
|
!isUndefined(comicvine.volumeInformation);
|
||||||
return (
|
return (
|
||||||
<Card
|
<div
|
||||||
orientation="vertical-2"
|
|
||||||
key={idx}
|
key={idx}
|
||||||
imageUrl={url}
|
className="flex-[0_0_200px] min-w-0 sm:flex-[0_0_220px] md:flex-[0_0_240px] lg:flex-[0_0_260px] xl:flex-[0_0_280px] pr-[15px]"
|
||||||
title={inferredMetadata.issue.name}
|
|
||||||
hasDetails
|
|
||||||
>
|
>
|
||||||
|
<Card
|
||||||
|
orientation="vertical-2"
|
||||||
|
imageUrl={url}
|
||||||
|
title={inferredMetadata.issue.name}
|
||||||
|
hasDetails
|
||||||
|
>
|
||||||
<div>
|
<div>
|
||||||
<dd className="text-sm my-1 flex flex-row gap-1">
|
<dd className="text-sm my-1 flex flex-row gap-1">
|
||||||
{/* Issue number */}
|
{/* Issue number */}
|
||||||
@@ -99,16 +114,17 @@ export const RecentlyImported = (
|
|||||||
<div className="sm:inline-flex sm:shrink-0 sm:items-center sm:gap-2">
|
<div className="sm:inline-flex sm:shrink-0 sm:items-center sm:gap-2">
|
||||||
{/* ComicInfo.xml presence */}
|
{/* ComicInfo.xml presence */}
|
||||||
{!isNil(comicInfo) && !isEmpty(comicInfo) && (
|
{!isNil(comicInfo) && !isEmpty(comicInfo) && (
|
||||||
<div mt-1>
|
<div className="mt-1">
|
||||||
<i className="h-7 w-7 icon-[solar--code-file-bold-duotone] text-yellow-500 dark:text-yellow-300"></i>
|
<i className="h-7 w-7 icon-[solar--code-file-bold-duotone] text-yellow-500 dark:text-yellow-300"></i>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{/* ComicVine metadata presence */}
|
{/* ComicVine metadata presence */}
|
||||||
{isComicVineMetadataAvailable && (
|
{isComicVineMetadataAvailable && (
|
||||||
<span className="w-7 h-7">
|
<span className="inline-block w-6 h-6 md:w-7 md:h-7 flex-shrink-0">
|
||||||
<img
|
<img
|
||||||
src="/src/client/assets/img/cvlogo.svg"
|
src="/src/client/assets/img/cvlogo.svg"
|
||||||
alt={"ComicVine metadata detected."}
|
alt={"ComicVine metadata detected."}
|
||||||
|
className="w-full h-full object-contain"
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
@@ -121,9 +137,12 @@ export const RecentlyImported = (
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
)}
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ export const WantedComicsList = ({
|
|||||||
<img
|
<img
|
||||||
src="/src/client/assets/img/cvlogo.svg"
|
src="/src/client/assets/img/cvlogo.svg"
|
||||||
alt={"ComicVine metadata detected."}
|
alt={"ComicVine metadata detected."}
|
||||||
className="w-7 h-7"
|
className="inline-block w-6 h-6 md:w-7 md:h-7 flex-shrink-0 object-contain"
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{!isEmpty(locg) && (
|
{!isEmpty(locg) && (
|
||||||
|
|||||||
@@ -72,8 +72,11 @@ export const LibraryGrid = (libraryGridProps: ILibraryGridProps) => {
|
|||||||
>
|
>
|
||||||
<div className="content is-flex is-flex-direction-row">
|
<div className="content is-flex is-flex-direction-row">
|
||||||
{!isEmpty(sourcedMetadata.comicvine) && (
|
{!isEmpty(sourcedMetadata.comicvine) && (
|
||||||
<span className="icon cv-icon is-small">
|
<span className="icon cv-icon is-small inline-block w-6 h-6 md:w-7 md:h-7 flex-shrink-0">
|
||||||
<img src="/src/client/assets/img/cvlogo.svg" />
|
<img
|
||||||
|
src="/src/client/assets/img/cvlogo.svg"
|
||||||
|
className="w-full h-full object-contain"
|
||||||
|
/>
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
{isNil(rawFileDetails) && (
|
{isNil(rawFileDetails) && (
|
||||||
|
|||||||
Reference in New Issue
Block a user