MVP
This commit is contained in:
commit
2c2fd045b3
19 changed files with 3898 additions and 0 deletions
61
src/app/[file]/content.tsx
Normal file
61
src/app/[file]/content.tsx
Normal file
|
@ -0,0 +1,61 @@
|
|||
'use client'
|
||||
|
||||
import { useState, useEffect } from 'react'
|
||||
|
||||
import Error from './types/error';
|
||||
import Image from './types/image';
|
||||
import Text from './types/text';
|
||||
|
||||
export default function Content({ src }: { src: string}) {
|
||||
const [content, set_content] = useState();
|
||||
|
||||
type ContentType<T> = {
|
||||
matcher: RegExp,
|
||||
emit: () => undefined | Processor<T>,
|
||||
};
|
||||
type Processor<T> = {
|
||||
process: (response: Response) => Promise<T>,
|
||||
postprocess: (data: T) => undefined,
|
||||
};
|
||||
|
||||
const recognized_types: ContentType<Any>[] = [{
|
||||
matcher: /image\/\w+/,
|
||||
emit: () => {
|
||||
set_content(<Image src={src} />);
|
||||
},
|
||||
}, {
|
||||
matcher: /text\/\w+/,
|
||||
emit: () => {
|
||||
return {
|
||||
process: (response: Response) => {
|
||||
return response.text();
|
||||
},
|
||||
postprocess: (data: string) => {
|
||||
set_content(<Text text={data} />);
|
||||
}
|
||||
};
|
||||
}
|
||||
}];
|
||||
|
||||
useEffect(() => {
|
||||
if (content == undefined) {
|
||||
const result = fetch(src)
|
||||
.then(response => {
|
||||
const content_type = response.headers.get('Content-Type').split(';')[0];
|
||||
for (let type of recognized_types) {
|
||||
if (type.matcher.test(content_type)) {
|
||||
const emitted = type.emit();
|
||||
if (emitted != undefined) {
|
||||
result.then(emitted.postprocess);
|
||||
return emitted.process(response);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
set_content(<Error content_type={content_type} />);
|
||||
});
|
||||
}
|
||||
}, []);
|
||||
|
||||
return content ?? <p>Loading...</p>;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue