This commit is contained in:
Gnarwhal 2024-09-16 19:44:19 +00:00
commit 2c2fd045b3
Signed by: Gnarwhal
GPG key ID: 0989A73D8C421174
19 changed files with 3898 additions and 0 deletions

3
.eslintrc.json Normal file
View file

@ -0,0 +1,3 @@
{
"extends": ["next/core-web-vitals", "next/typescript"]
}

36
.gitignore vendored Normal file
View file

@ -0,0 +1,36 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
.yarn/install-state.gz
# testing
/coverage
# next.js
/.next/
/out/
# production
/build
# misc
.DS_Store
*.pem
# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# local env files
.env*.local
# vercel
.vercel
# typescript
*.tsbuildinfo
next-env.d.ts

3
README.md Normal file
View file

@ -0,0 +1,3 @@
# Motto
Static file beautifier

8
next.config.mjs Normal file
View file

@ -0,0 +1,8 @@
import { createVanillaExtractPlugin } from '@vanilla-extract/next-plugin'
/** @type {import('next').NextConfig} */
const nextConfig = {}
const withVanillaExtract = createVanillaExtractPlugin()
export default withVanillaExtract(nextConfig)

26
package.json Normal file
View file

@ -0,0 +1,26 @@
{
"name": "motto",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"@vanilla-extract/css": "^1.15.5",
"next": "14.2.9",
"react": "^18",
"react-dom": "^18"
},
"devDependencies": {
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
"@vanilla-extract/next-plugin": "^2.4.5",
"eslint": "^8",
"eslint-config-next": "14.2.9",
"typescript": "^5"
}
}

View 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>;
}

BIN
src/app/[file]/download.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

View file

@ -0,0 +1,66 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="512"
height="512"
viewBox="0 0 135.46666 135.46667"
version="1.1"
id="svg1"
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25)"
sodipodi:docname="download.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#222222"
borderopacity="1"
inkscape:showpageshadow="2"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="false"
inkscape:deskcolor="#3d3d3d"
inkscape:document-units="px"
inkscape:zoom="1.6531383"
inkscape:cx="271.90707"
inkscape:cy="288.23964"
inkscape:window-width="2560"
inkscape:window-height="1403"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs1" />
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<rect
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.830298;stroke-dasharray:none;stroke-opacity:1"
id="rect4"
width="60.391628"
height="11.312016"
x="66.7099"
y="19.924133"
transform="rotate(45)" />
<rect
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.830298;stroke-dasharray:none;stroke-opacity:1"
id="rect4-3"
width="60.391628"
height="11.312016"
x="-29.155479"
y="-127.10163"
transform="rotate(135)" />
<rect
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.977747;stroke-dasharray:none;stroke-opacity:1"
id="rect4-3-2"
width="83.745499"
height="11.312016"
x="22.514505"
y="-73.397362"
transform="rotate(90)" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2 KiB

View file

@ -0,0 +1,67 @@
import { style } from '@vanilla-extract/css';
import * as colors from '../colors.css';
export const root = style({
width: '100%',
height: '100%',
display: 'flex',
justifyContent: 'center',
});
export const center = style({
width: '100%',
height: 'max-content',
padding: '2em',
});
export const title_group = style({
marginBottom: '1em',
width: '100%',
height: '4em',
display: 'flex',
justifyContent: 'space-between'
});
export const title_text_group = style({
flexGrow: 1,
boxSizing: 'border-box',
height: '100%',
borderBottom: `1px solid ${colors.background2}`,
});
export const title = style({
margin: 0,
fontSize: '2em',
});
export const supertitle = style({
margin: 0,
color: colors.foreground2
});
export const download_button = style({
width: 'auto',
height: '100%',
marginLeft: '2em',
border: 0,
padding: 0,
backgroundColor: colors.background2,
color: colors.foreground,
});
export const download_button_image = style({
display: 'block',
width: 'auto',
height: '100%',
});
export const download_text_section = style({
marginLeft: '1em',
});
export const download_text = style({
margin: '0.5em 0',
fontFamily: 'monospace',
fontSize: '1.5em',
});

65
src/app/[file]/page.tsx Normal file
View file

@ -0,0 +1,65 @@
import type { Metadata, ResolvingMetadata } from 'next';
import Image from 'next/image';
import Content from './content';
import {
root,
center,
title_group,
title_text_group,
supertitle,
title,
download_button,
download_button_image,
download_text_section,
download_text,
} from './page.css';
import download_image from './download.png';
type SearchParams = { [key: string]: string | string[] | undefined };
type Props = {
params: { file: string },
searchParams: SearchParams,
};
function get_root(search_params: SearchParams) {
console.log("HEEEERORORORRO", search_params)
return search_params['root'] ?? 'raw.monodon.me';
}
export async function generateMetadata(
{ params, searchParams }: Props,
parent: ResolvingMetadata,
): Promise<Metadata> {
return {
title: `${params.file} | ${get_root(searchParams)}`,
};
}
export default async function Page({
params, searchParams
}: Props) {
const root_url = `https://${get_root(searchParams)}/`;
return (
<div className={root}>
<div className={center}>
<div className={title_group}>
<div className={title_text_group}>
<p className={supertitle}>{root_url}</p>
<p className={title}>{params.file}</p>
</div>
<button className={download_button}>
<Image
className={download_button_image}
src={download_image}
alt="Download Button"
/>
</button>
</div>
<Content src={`${root_url}${params.file}`} />
</div>
</div>
);
}

View file

@ -0,0 +1,3 @@
export default function Error({ content_type }: { content_type: string }) {
return <p>{`Unrecognised MIME type: ${content_type}`}</p>
}

View file

@ -0,0 +1,5 @@
export default function Image({ src }: { src: string }) {
return (
<img src={src} />
);
}

View file

@ -0,0 +1,5 @@
export default function Text({ text }: { text: string }) {
return (
<p>{text}</p>
);
}

28
src/app/colors.css.ts Normal file
View file

@ -0,0 +1,28 @@
import { createVar, globalStyle} from '@vanilla-extract/css';
export const background = createVar();
export const background2 = createVar();
export const foreground = createVar();
export const foreground2 = createVar();
export const accent = createVar();
globalStyle(':root', {
vars: {
[background]: '#000000',
[background2]: '#303030',
[foreground]: '#F0F0F0',
[foreground2]: '#777777',
[accent]: '#9834D4',
},
'@media': {
'(prefers-color-scheme: light)': {
vars: {
[background]: '#FFFFFF',
[background2]: '#DADADA',
[foreground]: '#171717',
[foreground2]: '#333333',
[accent]: '#9834D4',
}
}
}
});

12
src/app/globals.css.ts Normal file
View file

@ -0,0 +1,12 @@
import { globalStyle } from '@vanilla-extract/css';
import * as colors from './colors.css';
globalStyle('html, body', {
margin: '0',
width: '100%',
height: '100%',
backgroundColor: colors.background,
color: colors.foreground,
fontFamily: 'sans-serif',
});

15
src/app/layout.tsx Normal file
View file

@ -0,0 +1,15 @@
import "./globals.css";
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode
}>) {
return (
<html lang="en">
<body>
{children}
</body>
</html>
);
}

8
src/app/page.tsx Normal file
View file

@ -0,0 +1,8 @@
export default function App() {
return (
<div>
<h1>Dev - Motto</h1>
<p>Motto is a WIP</p>
</div>
);
}

26
tsconfig.json Normal file
View file

@ -0,0 +1,26 @@
{
"compilerOptions": {
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"plugins": [
{
"name": "next"
}
],
"paths": {
"@/*": ["./src/*"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
}

3461
yarn.lock Normal file

File diff suppressed because it is too large Load diff