diff --git a/.eslintrc.json b/.eslintrc.json index 82fbe15..3722418 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,6 +1,3 @@ { - "extends": ["next/core-web-vitals", "next/typescript"], - "rules": { - "@typescript-eslint/no-explicit-any": "off" - } + "extends": ["next/core-web-vitals", "next/typescript"] } diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 8f04b61..0000000 --- a/Dockerfile +++ /dev/null @@ -1,55 +0,0 @@ -FROM chimeralinux/chimera:latest AS base -RUN apk add libgcc-chimera yarn - -# Install dependencies only when needed -FROM base AS deps -WORKDIR /app - -# Install dependencies based on the preferred package manager -COPY package.json yarn.lock* ./ -RUN yarn --frozen-lockfile; - -# Rebuild the source code only when needed -FROM base AS builder -WORKDIR /app -COPY --from=deps /app/node_modules ./node_modules -COPY . . - -# Next.js collects completely anonymous telemetry data about general usage. -# Learn more here: https://nextjs.org/telemetry -# Uncomment the following line in case you want to disable telemetry during the build. -ENV NEXT_TELEMETRY_DISABLED=1 - -RUN yarn run build; - -# Production image, copy all the files and run next -FROM base AS runner -WORKDIR /app - -ENV NODE_ENV=production -# Uncomment the following line in case you want to disable telemetry during runtime. -# ENV NEXT_TELEMETRY_DISABLED=1 - -RUN apk add shadow -RUN groupadd --system --gid 1001 nodejs -RUN useradd --system --uid 1001 nextjs - -# Set the correct permission for prerender cache -RUN mkdir .next -RUN chown nextjs:nodejs .next - -# Automatically leverage output traces to reduce image size -# https://nextjs.org/docs/advanced-features/output-file-tracing -COPY --from=builder --chown=nextjs:nextjs /app/.next/standalone ./ -COPY --from=builder --chown=nextjs:nextjs /app/.next/static ./.next/static - -USER nextjs - -EXPOSE 4730 - -ENV PORT=4730 - -# server.js is created by next build from the standalone output -# https://nextjs.org/docs/pages/api-reference/next-config-js/output -ENV HOSTNAME="0.0.0.0" -CMD ["node", "server.js"] diff --git a/next.config.mjs b/next.config.mjs index 0c3c06c..5dd825b 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -1,9 +1,7 @@ import { createVanillaExtractPlugin } from '@vanilla-extract/next-plugin' /** @type {import('next').NextConfig} */ -const nextConfig = { - output: "standalone", -} +const nextConfig = {} const withVanillaExtract = createVanillaExtractPlugin() diff --git a/src/app/[...file]/content.tsx b/src/app/[...file]/content.tsx index 003ecf9..d70df99 100644 --- a/src/app/[...file]/content.tsx +++ b/src/app/[...file]/content.tsx @@ -4,14 +4,14 @@ import { useState, useEffect } from 'react' import NetworkError from './types/error/network'; import ContentTypeError from './types/error/content_type'; -import ImageContent from './types/image'; +import Image from './types/image'; import Terminal from './types/terminal'; import Text from './types/text'; type ContentType = { content_type: RegExp, - path?: RegExp, - emit: () => void | Processor, + extension: RegExp, + emit: () => undefined | Processor, }; type Processor = { process: (response: Response) => Promise, @@ -22,8 +22,8 @@ function not_match(regex: RegExp | undefined, str: string) { return !(regex ?? /(?:)/).test(str); } -function is_type(response: Response, type: ContentType) { - if (not_match(type.content_type, response.headers.get('Content-Type')!.split(';')[0])) { +function is_type(response: Response, type: ContentType) { + if (not_match(type.content_type, response.headers.get('Content-Type').split(';')[0])) { return false; } else if (not_match(type.path, window.location.pathname)) { return false; @@ -32,12 +32,12 @@ function is_type(response: Response, type: ContentType) { } export default function Content({ src }: { src: string}) { - const [content, set_content] = useState(); + const [content, set_content] = useState(); - const recognized_types: ContentType[] = [{ + const recognized_types: ContentType[] = [{ content_type: /image\/\w+/, emit: () => { - set_content(); + set_content(); }, }, { content_type: /application\/octet-stream/, @@ -70,8 +70,9 @@ export default function Content({ src }: { src: string}) { if (content == undefined) { const result = fetch(src) .then(response => { + const content_type = response.headers.get('Content-Type').split(';')[0]; for (const type of recognized_types) { - if (is_type(response, type)) { + if (type.content_type.test(content_type)) { const emitted = type.emit(); if (emitted != undefined) { result.then(emitted.postprocess); @@ -80,13 +81,13 @@ export default function Content({ src }: { src: string}) { return; } } - set_content(); + set_content(); }) .catch(err => { set_content(); }); } - }); + }, []); return content ??

Loading...

; } diff --git a/src/app/[...file]/download_tty.tsx b/src/app/[...file]/download_tty.tsx index 80a4a53..93fbb27 100644 --- a/src/app/[...file]/download_tty.tsx +++ b/src/app/[...file]/download_tty.tsx @@ -1,15 +1,15 @@ 'use client' -// import { useState } from 'react'; +import { useState } from 'react'; import * as style from './download_tty.css'; export default function DownloadTTY({ text }: { text: string }) { - // const [copied, set_copied] = useState(false); - function make_copy_text(text: string) { - return () => { + const [copied, set_copied] = useState(false); + function make_copy_text(text) { + return (event) => { navigator.clipboard.writeText(text); - // set_copied(true); + set_copied(true); // setTimeout(() => { set_copied(false); }, 5000); }; } diff --git a/src/app/[...file]/page.css.ts b/src/app/[...file]/page.css.ts index 060cbb8..f4b11f2 100644 --- a/src/app/[...file]/page.css.ts +++ b/src/app/[...file]/page.css.ts @@ -61,6 +61,7 @@ export const download_button = style({ width: 'auto', height: '100%', marginLeft: '2em', + border: 0, padding: 0, border: `1px solid ${colors.background2}`, backgroundColor: colors.background, diff --git a/src/app/[...file]/page.tsx b/src/app/[...file]/page.tsx index ecd9095..24e3c69 100644 --- a/src/app/[...file]/page.tsx +++ b/src/app/[...file]/page.tsx @@ -1,4 +1,4 @@ -import type { Metadata } from 'next'; +import type { Metadata, ResolvingMetadata } from 'next'; import Image from 'next/image'; import DownloadTTY from './download_tty'; @@ -10,7 +10,7 @@ import download_image_light from './download_light.svg'; type SearchParams = { [key: string]: string | string[] | undefined }; type Props = { - params: { file: string[] }, + params: { file: string }, searchParams: SearchParams, }; @@ -24,6 +24,7 @@ function get_root(search_params: SearchParams) { export async function generateMetadata( { params, searchParams }: Props, + parent: ResolvingMetadata, ): Promise { return { title: `${get_path(params.file)} | ${get_root(searchParams)}`, @@ -51,7 +52,7 @@ export default async function Page({

{path}