Merge branch 'main' into fix/#157/resize-when-converting-to-ico

This commit is contained in:
Emrik Östling 2024-10-05 01:02:48 +02:00 committed by GitHub
commit 64e4a271e1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
19 changed files with 205 additions and 133 deletions

View file

@ -1,7 +0,0 @@
version = 1
[[analyzers]]
name = "javascript"
[analyzers.meta]
environment = ["nodejs"]

BIN
bun.lockb

Binary file not shown.

View file

@ -1,28 +1,23 @@
import comments from "@eslint-community/eslint-plugin-eslint-comments/configs";
import { fixupPluginRules } from "@eslint/compat"; import { fixupPluginRules } from "@eslint/compat";
import js from "@eslint/js"; import eslint from "@eslint/js";
import deprecationPlugin from "eslint-plugin-deprecation"; import deprecationPlugin from "eslint-plugin-deprecation";
import importPlugin from "eslint-plugin-import"; import eslintPluginReadableTailwind from "eslint-plugin-readable-tailwind";
import simpleImportSortPlugin from "eslint-plugin-simple-import-sort"; import simpleImportSortPlugin from "eslint-plugin-simple-import-sort";
import tailwind from "eslint-plugin-tailwindcss"; import tailwind from "eslint-plugin-tailwindcss";
import globals from "globals"; import globals from "globals";
import tseslint from "typescript-eslint"; import tseslint from "typescript-eslint";
export default tseslint.config( export default tseslint.config(
js.configs.recommended, eslint.configs.recommended,
importPlugin.flatConfigs.recommended,
comments.recommended,
...tseslint.configs.recommended, ...tseslint.configs.recommended,
...tailwind.configs["flat/recommended"], ...tailwind.configs["flat/recommended"],
{ {
plugins: { plugins: {
"@typescript-eslint": tseslint.plugin,
deprecation: fixupPluginRules(deprecationPlugin), deprecation: fixupPluginRules(deprecationPlugin),
import: fixupPluginRules(importPlugin),
"simple-import-sort": simpleImportSortPlugin, "simple-import-sort": simpleImportSortPlugin,
"readable-tailwind": eslintPluginReadableTailwind,
}, },
ignores: ["**/node_modules/**", "**/public/**"], ignores: ["**/node_modules/**"],
languageOptions: { languageOptions: {
parserOptions: { parserOptions: {
projectService: true, projectService: true,
@ -36,12 +31,20 @@ export default tseslint.config(
...globals.browser, ...globals.browser,
}, },
}, },
files: ["**/*.{js,mjs,cjs}"], files: ["**/*.{js,mjs,cjs,tsx,ts}"],
rules: { rules: {
"tailwindcss/no-custom-classname": [ ...eslintPluginReadableTailwind.configs.warning.rules,
"error", "tailwindcss/classnames-order": "off",
"readable-tailwind/multiline": [
"warn",
{
group: "newLine",
printWidth: 100,
},
],
"tailwindcss/no-custom-classname": [
"warn",
{ {
config: "./tailwind.config.js",
whitelist: [ whitelist: [
"select_container", "select_container",
"convert_to_popup", "convert_to_popup",
@ -51,7 +54,6 @@ export default tseslint.config(
], ],
}, },
], ],
"import/no-named-as-default": "off",
}, },
}, },
); );

View file

@ -4,12 +4,12 @@
"scripts": { "scripts": {
"dev": "bun run --watch src/index.tsx", "dev": "bun run --watch src/index.tsx",
"hot": "bun run --hot src/index.tsx", "hot": "bun run --hot src/index.tsx",
"format": "biome format --write ./src", "format": "eslint --fix .",
"build": "postcss ./src/main.css -o ./src/public/generated.css", "build": "postcss ./src/main.css -o ./src/public/generated.css",
"lint": "run-p 'lint:*'", "lint": "run-p 'lint:*'",
"lint:tsc": "tsc --noEmit", "lint:tsc": "tsc --noEmit",
"lint:knip": "knip", "lint:knip": "knip",
"lint:biome": "biome lint --error-on-warnings ./src" "lint:eslint": "eslint ."
}, },
"dependencies": { "dependencies": {
"@elysiajs/cookie": "^0.8.0", "@elysiajs/cookie": "^0.8.0",
@ -24,13 +24,10 @@
"start": "bun run src/index.tsx" "start": "bun run src/index.tsx"
}, },
"devDependencies": { "devDependencies": {
"@biomejs/biome": "1.9.3",
"@eslint-community/eslint-plugin-eslint-comments": "^4.4.0",
"@eslint/compat": "^1.1.1", "@eslint/compat": "^1.1.1",
"@eslint/js": "^9.11.1", "@eslint/js": "^9.12.0",
"@ianvs/prettier-plugin-sort-imports": "^4.3.1", "@ianvs/prettier-plugin-sort-imports": "^4.3.1",
"@kitajs/ts-html-plugin": "^4.1.0", "@kitajs/ts-html-plugin": "^4.1.0",
"@picocss/pico": "^2.0.6",
"@total-typescript/ts-reset": "^0.6.1", "@total-typescript/ts-reset": "^0.6.1",
"@types/bun": "^1.1.10", "@types/bun": "^1.1.10",
"@types/eslint": "^9.6.1", "@types/eslint": "^9.6.1",
@ -41,12 +38,12 @@
"@typescript-eslint/parser": "^8.7.0", "@typescript-eslint/parser": "^8.7.0",
"autoprefixer": "^10.4.20", "autoprefixer": "^10.4.20",
"cssnano": "^7.0.6", "cssnano": "^7.0.6",
"eslint": "^9.11.1", "eslint": "^9.12.0",
"eslint-config-prettier": "^9.1.0", "eslint-config-prettier": "^9.1.0",
"eslint-plugin-deprecation": "^3.0.0", "eslint-plugin-deprecation": "^3.0.0",
"eslint-plugin-import": "^2.30.0",
"eslint-plugin-isaacscript": "^4.0.0", "eslint-plugin-isaacscript": "^4.0.0",
"eslint-plugin-prettier": "^5.2.1", "eslint-plugin-prettier": "^5.2.1",
"eslint-plugin-readable-tailwind": "^1.8.1",
"eslint-plugin-simple-import-sort": "^12.1.1", "eslint-plugin-simple-import-sort": "^12.1.1",
"eslint-plugin-tailwindcss": "^3.17.4", "eslint-plugin-tailwindcss": "^3.17.4",
"globals": "^15.9.0", "globals": "^15.9.0",
@ -59,9 +56,6 @@
"tailwind-scrollbar": "^3.1.0", "tailwind-scrollbar": "^3.1.0",
"tailwindcss": "^3.4.13", "tailwindcss": "^3.4.13",
"typescript": "^5.6.2", "typescript": "^5.6.2",
"typescript-eslint": "^8.7.0" "typescript-eslint": "^8.8.0"
}, }
"trustedDependencies": [
"@biomejs/biome"
]
} }

View file

@ -1,9 +1,9 @@
// eslint-disable-next-line no-undef
module.exports = { module.exports = {
plugins: { plugins: {
tailwindcss: {}, tailwindcss: {},
autoprefixer: {}, autoprefixer: {},
// eslint-disable-next-line no-undef
...(process.env.NODE_ENV === 'production' ? { cssnano: {} } : {}) ...(process.env.NODE_ENV === 'production' ? { cssnano: {} } : {})
} }
} }

View file

@ -1,6 +1,7 @@
{ {
"$schema": "https://docs.renovatebot.com/renovate-schema.json", "$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [ "extends": [
"config:recommended" "config:recommended",
":disableDependencyDashboard"
] ]
} }

View file

@ -8,14 +8,20 @@ export const Header = ({
<ul class="flex gap-4"> <ul class="flex gap-4">
<li> <li>
<a <a
class="text-accent-600 transition-all hover:text-accent-500 hover:underline" class={`
text-accent-600 transition-all
hover:text-accent-500 hover:underline
`}
href="/history"> href="/history">
History History
</a> </a>
</li> </li>
<li> <li>
<a <a
class="text-accent-600 transition-all hover:text-accent-500 hover:underline" class={`
text-accent-600 transition-all
hover:text-accent-500 hover:underline
`}
href="/logoff"> href="/logoff">
Logout Logout
</a> </a>
@ -27,7 +33,10 @@ export const Header = ({
<ul class="flex gap-4"> <ul class="flex gap-4">
<li> <li>
<a <a
class="text-accent-600 transition-all hover:text-accent-500 hover:underline" class={`
text-accent-600 transition-all
hover:text-accent-500 hover:underline
`}
href="/login"> href="/login">
Login Login
</a> </a>
@ -35,7 +44,10 @@ export const Header = ({
{accountRegistration ? ( {accountRegistration ? (
<li> <li>
<a <a
class="text-accent-600 transition-all hover:text-accent-500 hover:underline" class={`
text-accent-600 transition-all
hover:text-accent-500 hover:underline
`}
href="/register"> href="/register">
Register Register
</a> </a>

View file

@ -116,8 +116,8 @@ export async function convert(
fileType: string, fileType: string,
convertTo: string, convertTo: string,
targetPath: string, targetPath: string,
// biome-ignore lint/suspicious/noExplicitAny: <explanation> // eslint-disable-next-line @typescript-eslint/no-unused-vars
options?: any, options?: unknown,
): Promise<string> { ): Promise<string> {
// let command = "ffmpeg"; // let command = "ffmpeg";

View file

@ -690,7 +690,7 @@ export async function convert(
convertTo: string, convertTo: string,
targetPath: string, targetPath: string,
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
_options?: unknown, options?: unknown,
): Promise<string> { ): Promise<string> {
let extra = ""; let extra = "";

View file

@ -313,8 +313,8 @@ export function convert(
fileType: string, fileType: string,
convertTo: string, convertTo: string,
targetPath: string, targetPath: string,
// biome-ignore lint/suspicious/noExplicitAny: <explanation> // eslint-disable-next-line @typescript-eslint/no-unused-vars
options?: any, options?: unknown,
): Promise<string> { ): Promise<string> {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
exec( exec(

View file

@ -39,8 +39,8 @@ export function convert(
fileType: string, fileType: string,
convertTo: string, convertTo: string,
targetPath: string, targetPath: string,
// biome-ignore lint/suspicious/noExplicitAny: <explanation> // eslint-disable-next-line @typescript-eslint/no-unused-vars
options?: any, options?: unknown,
): Promise<string> { ): Promise<string> {
let tool = ""; let tool = "";
if (fileType === "jxl") { if (fileType === "jxl") {

View file

@ -1,67 +1,64 @@
import { normalizeFiletype } from "../helpers/normalizeFiletype";
import { import {
convert as convertImage, convert as convertassimp,
properties as propertiesImage properties as propertiesassimp,
} from "./vips"; } from "./assimp";
import {
convert as convertPandoc,
properties as propertiesPandoc,
} from "./pandoc";
import { import {
convert as convertFFmpeg, convert as convertFFmpeg,
properties as propertiesFFmpeg, properties as propertiesFFmpeg,
} from "./ffmpeg"; } from "./ffmpeg";
import { import {
convert as convertGraphicsmagick, convert as convertGraphicsmagick,
properties as propertiesGraphicsmagick, properties as propertiesGraphicsmagick,
} from "./graphicsmagick"; } from "./graphicsmagick";
import {
convert as convertLibjxl,
properties as propertiesLibjxl,
} from "./libjxl";
import {
convert as convertPandoc,
properties as propertiesPandoc,
} from "./pandoc";
import {
convert as convertresvg,
properties as propertiesresvg,
} from "./resvg";
import { convert as convertImage, properties as propertiesImage } from "./vips";
import { import {
convert as convertxelatex, convert as convertxelatex,
properties as propertiesxelatex, properties as propertiesxelatex,
} from "./xelatex"; } from "./xelatex";
import {
convert as convertLibjxl,
properties as propertiesLibjxl,
} from "./libjxl";
import {
convert as convertresvg,
properties as propertiesresvg,
} from "./resvg";
import {
convert as convertassimp,
properties as propertiesassimp,
} from "./assimp";
import { normalizeFiletype } from "../helpers/normalizeFiletype";
// This should probably be reconstructed so that the functions are not imported instead the functions hook into this to make the converters more modular // This should probably be reconstructed so that the functions are not imported instead the functions hook into this to make the converters more modular
const properties: Record<string, { const properties: Record<
string,
{
properties: { properties: {
from: Record<string, string[]>; from: Record<string, string[]>;
to: Record<string, string[]>; to: Record<string, string[]>;
options?: Record<string, Record<string, { options?: Record<
string,
Record<
string,
{
description: string; description: string;
type: string; type: string;
default: number; default: number;
}>>; }
>
>;
}; };
converter: ( converter: (
filePath: string, filePath: string,
fileType: string, fileType: string,
convertTo: string, convertTo: string,
targetPath: string, targetPath: string,
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
options?: any, options?: unknown,
// biome-ignore lint/suspicious/noExplicitAny: <explanation> ) => unknown;
) => any; }
}> = { > = {
libjxl: { libjxl: {
properties: propertiesLibjxl, properties: propertiesLibjxl,
converter: convertLibjxl, converter: convertLibjxl,
@ -99,24 +96,20 @@ const properties: Record<string, {
export async function mainConverter( export async function mainConverter(
inputFilePath: string, inputFilePath: string,
fileTypeOriginal: string, fileTypeOriginal: string,
// biome-ignore lint/suspicious/noExplicitAny: <explanation> convertTo: string,
convertTo: any,
targetPath: string, targetPath: string,
// biome-ignore lint/suspicious/noExplicitAny: <explanation> options?: unknown,
options?: any,
converterName?: string, converterName?: string,
) { ) {
const fileType = normalizeFiletype(fileTypeOriginal); const fileType = normalizeFiletype(fileTypeOriginal);
// biome-ignore lint/suspicious/noExplicitAny: <explanation> let converterFunc: ((filePath: string, fileType: string, convertTo: string, targetPath: string, options?: unknown) => unknown) | undefined;
let converterFunc: any;
// let converterName = converterName; // let converterName = converterName;
if (converterName) { if (converterName) {
converterFunc = properties[converterName]?.converter; converterFunc = properties[converterName]?.converter;
} else { } else {
// Iterate over each converter in properties // Iterate over each converter in properties
// biome-ignore lint/style/noParameterAssign: <explanation>
for (converterName in properties) { for (converterName in properties) {
const converterObj = properties[converterName]; const converterObj = properties[converterName];
@ -190,9 +183,7 @@ for (const converterName in properties) {
} }
} }
export const getPossibleTargets = ( export const getPossibleTargets = (from: string): Record<string, string[]> => {
from: string,
): Record<string, string[]> => {
const fromClean = normalizeFiletype(from); const fromClean = normalizeFiletype(from);
return possibleTargets[fromClean] || {}; return possibleTargets[fromClean] || {};
@ -216,6 +207,7 @@ for (const converterName in properties) {
} }
possibleInputs.sort(); possibleInputs.sort();
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const getPossibleInputs = () => { const getPossibleInputs = () => {
return possibleInputs; return possibleInputs;
}; };

View file

@ -124,8 +124,8 @@ export function convert(
fileType: string, fileType: string,
convertTo: string, convertTo: string,
targetPath: string, targetPath: string,
// biome-ignore lint/suspicious/noExplicitAny: <explanation> // eslint-disable-next-line @typescript-eslint/no-unused-vars
options?: any, options?: unknown,
): Promise<string> { ): Promise<string> {
// set xelatex here // set xelatex here
const xelatex = ["pdf", "latex"]; const xelatex = ["pdf", "latex"];

View file

@ -14,8 +14,8 @@ export function convert(
fileType: string, fileType: string,
convertTo: string, convertTo: string,
targetPath: string, targetPath: string,
// biome-ignore lint/suspicious/noExplicitAny: <explanation> // eslint-disable-next-line @typescript-eslint/no-unused-vars
options?: any, options?: unknown,
): Promise<string> { ): Promise<string> {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
exec(`resvg "${filePath}" "${targetPath}"`, (error, stdout, stderr) => { exec(`resvg "${filePath}" "${targetPath}"`, (error, stdout, stderr) => {

View file

@ -94,8 +94,8 @@ export function convert(
fileType: string, fileType: string,
convertTo: string, convertTo: string,
targetPath: string, targetPath: string,
// biome-ignore lint/suspicious/noExplicitAny: <explanation> // eslint-disable-next-line @typescript-eslint/no-unused-vars
options?: any, options?: unknown,
): Promise<string> { ): Promise<string> {
// if (fileType === "svg") { // if (fileType === "svg") {
// const scale = options.scale || 1; // const scale = options.scale || 1;

View file

@ -14,8 +14,8 @@ export function convert(
fileType: string, fileType: string,
convertTo: string, convertTo: string,
targetPath: string, targetPath: string,
// biome-ignore lint/suspicious/noExplicitAny: <explanation> // eslint-disable-next-line @typescript-eslint/no-unused-vars
options?: any, options?: unknown,
): Promise<string> { ): Promise<string> {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
// const fileName: string = (targetPath.split("/").pop() as string).replace(".pdf", "") // const fileName: string = (targetPath.split("/").pop() as string).replace(".pdf", "")

View file

@ -141,7 +141,9 @@ const app = new Elysia({
<main class="mx-auto w-full max-w-4xl px-4"> <main class="mx-auto w-full max-w-4xl px-4">
<h1 class="my-8 text-3xl">Welcome to ConvertX!</h1> <h1 class="my-8 text-3xl">Welcome to ConvertX!</h1>
<article class="article p-0"> <article class="article p-0">
<header class="w-full bg-neutral-800 p-4">Create your account</header> <header class="w-full bg-neutral-800 p-4">
Create your account
</header>
<form method="post" action="/register" class="p-4"> <form method="post" action="/register" class="p-4">
<fieldset class="mb-4 flex flex-col gap-4"> <fieldset class="mb-4 flex flex-col gap-4">
<label class="flex flex-col gap-1"> <label class="flex flex-col gap-1">
@ -172,7 +174,10 @@ const app = new Elysia({
<footer class="p-4"> <footer class="p-4">
Report any issues on{" "} Report any issues on{" "}
<a <a
class="text-accent-500 underline hover:text-accent-400" class={`
text-accent-500 underline
hover:text-accent-400
`}
href="https://github.com/C4illin/ConvertX" href="https://github.com/C4illin/ConvertX"
> >
GitHub GitHub
@ -528,12 +533,21 @@ const app = new Elysia({
<div class="mb-4 max-h-[50vh] overflow-y-auto scrollbar-thin"> <div class="mb-4 max-h-[50vh] overflow-y-auto scrollbar-thin">
<table <table
id="file-list" id="file-list"
class="w-full table-auto rounded bg-neutral-900 [&_td]:p-4 [&_tr]:rounded [&_tr]:border-b [&_tr]:border-neutral-800" class={`
w-full table-auto rounded bg-neutral-900
[&_td]:p-4
[&_tr]:rounded [&_tr]:border-b [&_tr]:border-neutral-800
`}
/> />
</div> </div>
<div <div
id="dropzone" id="dropzone"
class="relative flex h-48 w-full items-center justify-center rounded border border-dashed border-neutral-700 transition-all hover:border-neutral-600 [&.dragover]:border-4 [&.dragover]:border-neutral-500" class={`
relative flex h-48 w-full items-center justify-center rounded border border-dashed
border-neutral-700 transition-all
[&.dragover]:border-4 [&.dragover]:border-neutral-500
hover:border-neutral-600
`}
> >
<span> <span>
<b>Choose a file</b> or drag it here <b>Choose a file</b> or drag it here
@ -561,11 +575,17 @@ const app = new Elysia({
class="w-full rounded bg-neutral-800 p-4" class="w-full rounded bg-neutral-800 p-4"
/> />
<div class="select_container relative"> <div class="select_container relative">
<article class="convert_to_popup absolute z-[2] m-0 hidden h-[30vh] max-h-[50vh] w-full flex-col overflow-y-auto overflow-x-hidden rounded bg-neutral-800 sm:h-[30vh]"> <article class={`
convert_to_popup absolute z-[2] m-0 hidden h-[30vh] max-h-[50vh] w-full flex-col
overflow-y-auto overflow-x-hidden rounded bg-neutral-800
sm:h-[30vh]
`}>
{Object.entries(getAllTargets()).map( {Object.entries(getAllTargets()).map(
([converter, targets]) => ( ([converter, targets]) => (
<article <article
class="convert_to_group w-full border-b border-neutral-700 p-4 flex flex-col" class={`
convert_to_group flex w-full flex-col border-b border-neutral-700 p-4
`}
data-converter={converter} data-converter={converter}
> >
<header class="mb-2 w-full text-xl font-bold" safe> <header class="mb-2 w-full text-xl font-bold" safe>
@ -576,7 +596,10 @@ const app = new Elysia({
<button <button
// https://stackoverflow.com/questions/121499/when-a-blur-event-occurs-how-can-i-find-out-which-element-focus-went-to#comment82388679_33325953 // https://stackoverflow.com/questions/121499/when-a-blur-event-occurs-how-can-i-find-out-which-element-focus-went-to#comment82388679_33325953
tabindex={0} tabindex={0}
class="target rounded bg-neutral-700 p-1 text-base hover:bg-neutral-600" class={`
target rounded bg-neutral-700 p-1 text-base
hover:bg-neutral-600
`}
data-value={`${target},${converter}`} data-value={`${target},${converter}`}
data-target={target} data-target={target}
data-converter={converter} data-converter={converter}
@ -629,11 +652,15 @@ const app = new Elysia({
({ body }) => { ({ body }) => {
return ( return (
<> <>
<article class="convert_to_popup absolute z-[2] m-0 hidden h-[50vh] max-h-[50vh] w-full flex-col overflow-y-auto overflow-x-hidden rounded bg-neutral-800 sm:h-[30vh]"> <article class={`
convert_to_popup absolute z-[2] m-0 hidden h-[50vh] max-h-[50vh] w-full flex-col
overflow-y-auto overflow-x-hidden rounded bg-neutral-800
sm:h-[30vh]
`}>
{Object.entries(getPossibleTargets(body.fileType)).map( {Object.entries(getPossibleTargets(body.fileType)).map(
([converter, targets]) => ( ([converter, targets]) => (
<article <article
class="convert_to_group w-full border-b border-neutral-700 p-4 flex flex-col" class="convert_to_group flex w-full flex-col border-b border-neutral-700 p-4"
data-converter={converter} data-converter={converter}
> >
<header class="mb-2 w-full text-xl font-bold" safe> <header class="mb-2 w-full text-xl font-bold" safe>
@ -644,7 +671,10 @@ const app = new Elysia({
<button <button
// https://stackoverflow.com/questions/121499/when-a-blur-event-occurs-how-can-i-find-out-which-element-focus-went-to#comment82388679_33325953 // https://stackoverflow.com/questions/121499/when-a-blur-event-occurs-how-can-i-find-out-which-element-focus-went-to#comment82388679_33325953
tabindex={0} tabindex={0}
class="target rounded bg-neutral-700 p-1 text-base hover:bg-neutral-600" class={`
target rounded bg-neutral-700 p-1 text-base
hover:bg-neutral-600
`}
data-value={`${target},${converter}`} data-value={`${target},${converter}`}
data-target={target} data-target={target}
data-converter={converter} data-converter={converter}
@ -713,7 +743,7 @@ const app = new Elysia({
await Bun.write(`${userUploadsDir}${file.name}`, file); await Bun.write(`${userUploadsDir}${file.name}`, file);
} }
} else { } else {
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions, @typescript-eslint/dot-notation
await Bun.write(`${userUploadsDir}${body.file["name"]}`, body.file); await Bun.write(`${userUploadsDir}${body.file["name"]}`, body.file);
} }
} }
@ -893,7 +923,11 @@ const app = new Elysia({
<main class="w-full px-4"> <main class="w-full px-4">
<article class="article"> <article class="article">
<h1 class="mb-4 text-xl">Results</h1> <h1 class="mb-4 text-xl">Results</h1>
<table class="w-full table-auto rounded bg-neutral-900 text-left [&_td]:p-4 [&_tr]:rounded [&_tr]:border-b [&_tr]:border-neutral-800"> <table class={`
w-full table-auto rounded bg-neutral-900 text-left
[&_td]:p-4
[&_tr]:rounded [&_tr]:border-b [&_tr]:border-neutral-800
`}>
<thead> <thead>
<tr> <tr>
<th class="px-4 py-2">Time</th> <th class="px-4 py-2">Time</th>
@ -912,7 +946,10 @@ const app = new Elysia({
<td safe>{job.status}</td> <td safe>{job.status}</td>
<td> <td>
<a <a
class="text-accent-500 underline hover:text-accent-400" class={`
text-accent-500 underline
hover:text-accent-400
`}
href={`/results/${job.id}`} href={`/results/${job.id}`}
> >
View View
@ -990,9 +1027,20 @@ const app = new Elysia({
<progress <progress
max={job.num_files} max={job.num_files}
value={files.length} value={files.length}
class="mb-4 inline-block h-2 w-full appearance-none overflow-hidden rounded-full border-0 bg-neutral-700 bg-none text-accent-500 accent-accent-500 [&::-moz-progress-bar]:bg-neutral-700 [&::-webkit-progress-value]:rounded-full [&::-webkit-progress-value]:[background:none] [&[value]::-webkit-progress-value]:bg-accent-500 [&[value]::-webkit-progress-value]:transition-[inline-size]" class={`
mb-4 inline-block h-2 w-full appearance-none overflow-hidden rounded-full
border-0 bg-neutral-700 bg-none text-accent-500 accent-accent-500
[&::-moz-progress-bar]:bg-neutral-700 [&::-webkit-progress-value]:rounded-full
[&::-webkit-progress-value]:[background:none]
[&[value]::-webkit-progress-value]:bg-accent-500
[&[value]::-webkit-progress-value]:transition-[inline-size]
`}
/> />
<table class="w-full table-auto rounded bg-neutral-900 text-left [&_td]:p-4 [&_tr]:rounded [&_tr]:border-b [&_tr]:border-neutral-800"> <table class={`
w-full table-auto rounded bg-neutral-900 text-left
[&_td]:p-4
[&_tr]:rounded [&_tr]:border-b [&_tr]:border-neutral-800
`}>
<thead> <thead>
<tr> <tr>
<th class="px-4 py-2">Converted File Name</th> <th class="px-4 py-2">Converted File Name</th>
@ -1008,7 +1056,10 @@ const app = new Elysia({
<td safe>{file.status}</td> <td safe>{file.status}</td>
<td> <td>
<a <a
class="text-accent-500 underline hover:text-accent-400" class={`
text-accent-500 underline
hover:text-accent-400
`}
href={`/download/${outputPath}${file.output_file_name}`} href={`/download/${outputPath}${file.output_file_name}`}
> >
View View
@ -1016,7 +1067,10 @@ const app = new Elysia({
</td> </td>
<td> <td>
<a <a
class="text-accent-500 underline hover:text-accent-400" class={`
text-accent-500 underline
hover:text-accent-400
`}
href={`/download/${outputPath}${file.output_file_name}`} href={`/download/${outputPath}${file.output_file_name}`}
download={file.output_file_name} download={file.output_file_name}
> >
@ -1093,9 +1147,20 @@ const app = new Elysia({
<progress <progress
max={job.num_files} max={job.num_files}
value={files.length} value={files.length}
class="mb-4 inline-block h-2 w-full appearance-none overflow-hidden rounded-full border-0 bg-neutral-700 bg-none text-accent-500 accent-accent-500 [&::-moz-progress-bar]:bg-neutral-700 [&::-webkit-progress-value]:rounded-full [&::-webkit-progress-value]:[background:none] [&[value]::-webkit-progress-value]:bg-accent-500 [&[value]::-webkit-progress-value]:transition-[inline-size]" class={`
mb-4 inline-block h-2 w-full appearance-none overflow-hidden rounded-full border-0
bg-neutral-700 bg-none text-accent-500 accent-accent-500
[&::-moz-progress-bar]:bg-neutral-700 [&::-webkit-progress-value]:rounded-full
[&::-webkit-progress-value]:[background:none]
[&[value]::-webkit-progress-value]:bg-accent-500
[&[value]::-webkit-progress-value]:transition-[inline-size]
`}
/> />
<table class="w-full table-auto rounded bg-neutral-900 text-left [&_td]:p-4 [&_tr]:rounded [&_tr]:border-b [&_tr]:border-neutral-800"> <table class={`
w-full table-auto rounded bg-neutral-900 text-left
[&_td]:p-4
[&_tr]:rounded [&_tr]:border-b [&_tr]:border-neutral-800
`}>
<thead> <thead>
<tr> <tr>
<th class="px-4 py-2">Converted File Name</th> <th class="px-4 py-2">Converted File Name</th>
@ -1111,7 +1176,10 @@ const app = new Elysia({
<td safe>{file.status}</td> <td safe>{file.status}</td>
<td> <td>
<a <a
class="text-accent-500 underline hover:text-accent-400" class={`
text-accent-500 underline
hover:text-accent-400
`}
href={`/download/${outputPath}${file.output_file_name}`} href={`/download/${outputPath}${file.output_file_name}`}
> >
View View
@ -1119,7 +1187,10 @@ const app = new Elysia({
</td> </td>
<td> <td>
<a <a
class="text-accent-500 underline hover:text-accent-400" class={`
text-accent-500 underline
hover:text-accent-400
`}
href={`/download/${outputPath}${file.output_file_name}`} href={`/download/${outputPath}${file.output_file_name}`}
download={file.output_file_name} download={file.output_file_name}
> >
@ -1179,7 +1250,12 @@ const app = new Elysia({
<main class="w-full px-4"> <main class="w-full px-4">
<article class="article"> <article class="article">
<h1 class="mb-4 text-xl">Converters</h1> <h1 class="mb-4 text-xl">Converters</h1>
<table class="w-full table-auto rounded bg-neutral-900 text-left [&_td]:p-4 [&_tr]:rounded [&_tr]:border-b [&_tr]:border-neutral-800 [&_ul]:list-inside [&_ul]:list-disc"> <table class={`
w-full table-auto rounded bg-neutral-900 text-left
[&_td]:p-4
[&_tr]:rounded [&_tr]:border-b [&_tr]:border-neutral-800
[&_ul]:list-inside [&_ul]:list-disc
`}>
<thead> <thead>
<tr> <tr>
<th class="mx-4 my-2">Converter</th> <th class="mx-4 my-2">Converter</th>

View file

@ -4,11 +4,11 @@ const dropZone = document.getElementById("dropzone");
const fileNames = []; const fileNames = [];
let fileType; let fileType;
dropZone.addEventListener("dragover", (e) => { dropZone.addEventListener("dragover", () => {
dropZone.classList.add("dragover"); dropZone.classList.add("dragover");
}); });
dropZone.addEventListener("dragleave", (e) => { dropZone.addEventListener("dragleave", () => {
dropZone.classList.remove("dragover"); dropZone.classList.remove("dragover");
}); });
@ -153,6 +153,7 @@ const setTitle = () => {
}; };
// Add a onclick for the delete button // Add a onclick for the delete button
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const deleteRow = (target) => { const deleteRow = (target) => {
const filename = target.parentElement.parentElement.children[0].textContent; const filename = target.parentElement.parentElement.children[0].textContent;
const row = target.parentElement.parentElement; const row = target.parentElement.parentElement;
@ -203,7 +204,7 @@ const uploadFiles = (files) => {
const formConvert = document.querySelector("form[action='/convert']"); const formConvert = document.querySelector("form[action='/convert']");
formConvert.addEventListener("submit", (e) => { formConvert.addEventListener("submit", () => {
const hiddenInput = document.querySelector("input[name='file_names']"); const hiddenInput = document.querySelector("input[name='file_names']");
hiddenInput.value = JSON.stringify(fileNames); hiddenInput.value = JSON.stringify(fileNames);
}); });

View file

@ -1,5 +1,6 @@
/* eslint-disable @typescript-eslint/no-require-imports */
/** @type {import('tailwindcss').Config} */ /** @type {import('tailwindcss').Config} */
// eslint-disable-next-line no-undef
module.exports = { module.exports = {
content: ["./src/**/*.{html,js,tsx,jsx,cjs,mjs}"], content: ["./src/**/*.{html,js,tsx,jsx,cjs,mjs}"],
theme: { theme: {