Add more placeholders to apps

This commit is contained in:
Dustin Brett 2024-07-14 20:17:11 -07:00
parent d8dfbf42c7
commit 43e54c14fe
11 changed files with 101 additions and 95 deletions

View File

@ -1,21 +1,9 @@
import styled from "styled-components";
import Message from "styles/common/Message";
const StyledEmulator = styled.div`
&.drop {
&::before {
color: #f1f1f1;
content: "Drop rom file here";
display: flex;
font-size: 16px;
font-weight: 600;
height: 100%;
left: 0;
place-content: center;
place-items: center;
position: absolute;
top: 0;
width: 100%;
}
${Message("Drop rom file here", "#f1f1f1")};
}
`;

View File

@ -1,4 +1,5 @@
import styled from "styled-components";
import Message from "styles/common/Message";
import ScrollBars from "styles/common/ScrollBars";
import { DEFAULT_SCROLLBAR_WIDTH } from "utils/constants";
@ -10,7 +11,7 @@ const StyledMarked = styled.div`
font-size: 16px;
height: 100%;
line-height: 1.5;
overflow-y: scroll;
overflow-y: auto;
padding: 16px 32px;
width: 100%;
word-wrap: break-word;
@ -135,6 +136,10 @@ const StyledMarked = styled.div`
margin: 0;
padding: 0.2em 0.4em;
}
&.drop {
${Message("Drop markdown file here", "#000")};
}
}
`;

View File

@ -34,13 +34,17 @@ const useMarked = ({
const { prependFileToTitle } = useTitle(id);
const { processes: { [id]: { libs = [] } = {} } = {} } = useProcesses();
const openLink = useLinkHandler();
const getContainer = useCallback(
(): HTMLElement | null =>
containerRef.current?.querySelector("article") as HTMLElement,
[containerRef]
);
const loadFile = useCallback(async () => {
const markdownFile = await readFile(url);
const container = containerRef.current?.querySelector(
"article"
) as HTMLElement;
const container = getContainer();
if (container instanceof HTMLElement) {
container.classList.remove("drop");
container.innerHTML = window.DOMPurify.sanitize(
window.marked.parse(markdownFile.toString(), {
headerIds: false,
@ -63,7 +67,7 @@ const useMarked = ({
}
prependFileToTitle(basename(url));
}, [containerRef, openLink, prependFileToTitle, readFile, url]);
}, [getContainer, openLink, prependFileToTitle, readFile, url]);
useEffect(() => {
if (loading) {
@ -76,8 +80,11 @@ const useMarked = ({
}, [libs, loading, setLoading]);
useEffect(() => {
if (!loading && url) loadFile();
}, [loadFile, loading, url]);
if (!loading) {
if (url) loadFile();
else getContainer()?.classList.add("drop");
}
}, [getContainer, loadFile, loading, url]);
};
export default useMarked;

View File

@ -1,30 +1,13 @@
import styled, { css } from "styled-components";
import styled from "styled-components";
import Message from "styles/common/Message";
type StyledOpenTypeProps = {
$drop?: boolean;
};
const StyledOpenType = styled.div<StyledOpenTypeProps>`
const StyledOpenType = styled.div`
font-size: 13px;
overflow: hidden scroll;
overflow: hidden auto;
${({ $drop }) =>
$drop &&
css`
&::before {
content: "Drop OTF/TTF/WOFF file here";
display: flex;
font-size: 16px;
font-weight: 600;
height: 100%;
left: 0;
place-content: center;
place-items: center;
position: absolute;
top: 0;
width: 100%;
}
`}
&.drop {
${Message("Drop OTF/TTF/WOFF file here", "#000")};
}
ol {
&:not(:last-child) {

View File

@ -61,24 +61,25 @@ const FontCanvas: FC<FontCanvasProps> = ({
const MemoizedFontCanvas = memo(FontCanvas);
const OpenType: FC<ComponentProcessProps> = ({ id }) => {
const { processes: { [id]: { url = "" } = {} } = {}, title } = useProcesses();
const {
processes: { [id]: { url = "" } = {} } = {},
title,
url: setUrl,
} = useProcesses();
const { readFile } = useFileSystem();
const [font, setFont] = useState<Font>();
const [showDrop, setShowDrop] = useState(true);
const loadFont = useCallback(
async (fontUrl: string) => {
setShowDrop(false);
const { default: openType } = await import("opentype.js");
const { buffer } = await readFile(fontUrl);
try {
setFont(openType.parse(buffer));
} catch {
setShowDrop(true);
setUrl(id, "");
}
},
[readFile]
[id, readFile, setUrl]
);
const { name, types, version } = useMemo(() => {
const supportedTypes = [];
@ -112,7 +113,7 @@ const OpenType: FC<ComponentProcessProps> = ({ id }) => {
return (
<StyledOpenType
$drop={showDrop}
className={url ? "" : "drop"}
{...useFileDrop({ id })}
onContextMenuCapture={haltEvent}
>

View File

@ -1,4 +1,5 @@
import styled from "styled-components";
import Message from "styles/common/Message";
import ScrollBars from "styles/common/ScrollBars";
const StyledPDF = styled.div`
@ -19,6 +20,10 @@ const StyledPDF = styled.div`
box-shadow: 0 0 5px hsla(0, 0%, 10%, 50%);
margin: 4px 4px 0;
}
&.drop {
${Message("Drop PDF file here", "#fff")};
}
`;
export default StyledPDF;

View File

@ -85,45 +85,48 @@ const usePDF = ({
const renderingRef = useRef(false);
const abortControllerRef = useRef<AbortController | null>(null);
const renderPages = useCallback(async (): Promise<void> => {
if (
window.pdfjsLib &&
url &&
containerRef.current &&
!renderingRef.current
) {
renderingRef.current = true;
argument(id, "rendering", true);
if (containerRef.current) {
if (url) {
containerRef.current.classList.remove("drop");
// eslint-disable-next-line no-param-reassign
containerRef.current.scrollTop = 0;
setPages([]);
setLoading(true);
if (window.pdfjsLib && !renderingRef.current) {
renderingRef.current = true;
argument(id, "rendering", true);
const fileData = await readFile(url);
// eslint-disable-next-line no-param-reassign
containerRef.current.scrollTop = 0;
setPages([]);
setLoading(true);
if (fileData.length === 0) throw new Error("File is empty");
const fileData = await readFile(url);
const doc = await window.pdfjsLib.getDocument(fileData).promise;
const { info } = await doc.getMetadata();
if (fileData.length === 0) throw new Error("File is empty");
argument(id, "subTitle", (info as MetadataInfo).Title);
argument(id, "count", doc.numPages);
prependFileToTitle(basename(url));
const doc = await window.pdfjsLib.getDocument(fileData).promise;
const { info } = await doc.getMetadata();
abortControllerRef.current = new AbortController();
argument(id, "subTitle", (info as MetadataInfo).Title);
argument(id, "count", doc.numPages);
prependFileToTitle(basename(url));
for (let i = 0; i < doc.numPages; i += 1) {
if (abortControllerRef.current.signal.aborted) break;
if (i === 1) setLoading(false);
abortControllerRef.current = new AbortController();
// eslint-disable-next-line no-await-in-loop
const page = await renderPage(i + 1, doc);
for (let i = 0; i < doc.numPages; i += 1) {
if (abortControllerRef.current.signal.aborted) break;
if (i === 1) setLoading(false);
setPages((currentPages) => [...currentPages, page]);
// eslint-disable-next-line no-await-in-loop
const page = await renderPage(i + 1, doc);
setPages((currentPages) => [...currentPages, page]);
}
argument(id, "rendering", false);
renderingRef.current = false;
}
} else {
containerRef.current.classList.add("drop");
}
argument(id, "rendering", false);
renderingRef.current = false;
}
setLoading(false);

View File

@ -1,4 +1,5 @@
import styled from "styled-components";
import Message from "styles/common/Message";
const buttonSize = "48px";
const paddingSize = "32px";
@ -89,6 +90,10 @@ const StyledPhotos = styled.div<StyledPhotosProps>`
}
}
}
&.drop {
${Message("Drop photo file here", "#fff")};
}
`;
export default StyledPhotos;

View File

@ -109,6 +109,7 @@ const Photos: FC<ComponentProcessProps> = ({ id }) => {
<StyledPhotos
ref={containerRef}
$showImage={Boolean(src[url] && !brokenImage)}
className={url ? "" : "drop"}
onContextMenu={haltEvent}
{...useFileDrop({ id })}
>

View File

@ -1,24 +1,12 @@
import styled from "styled-components";
import Message from "styles/common/Message";
const StyledRuffle = styled.div`
height: 100%;
width: 100%;
&.drop {
&::before {
color: #ffad33;
content: "Drop SWF/SPL file here";
display: flex;
font-size: 16px;
font-weight: 600;
height: 100%;
left: 0;
place-content: center;
place-items: center;
position: absolute;
top: 0;
width: 100%;
}
${Message("Drop SWF/SPL file here", "#ffad33")};
}
ruffle-player {

20
styles/common/Message.ts Normal file
View File

@ -0,0 +1,20 @@
import { type RuleSet, css } from "styled-components";
const Message = (text: string, color: string): RuleSet<object> => css`
&::before {
color: ${color};
content: "${text}";
display: flex;
font-size: 16px;
font-weight: 600;
height: 100%;
left: 0;
place-content: center;
place-items: center;
position: absolute;
top: 0;
width: 100%;
}
`;
export default Message;