mirror of
https://github.com/mollersuite/monofile.git
synced 2024-11-21 13:36:25 -08:00
Port client to TypeScript
Co-authored-by: Jack W. <Jack5079@users.noreply.github.com>
This commit is contained in:
parent
77cfa27615
commit
f441e06a21
264
package-lock.json
generated
264
package-lock.json
generated
|
@ -30,6 +30,7 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@sveltejs/vite-plugin-svelte": "^2.4.6",
|
||||
"@tsconfig/svelte": "^4.0.1",
|
||||
"@types/bytes": "^3.1.1",
|
||||
"@types/cookie-parser": "^1.4.3",
|
||||
"@types/formidable": "^3.4.5",
|
||||
|
@ -37,10 +38,12 @@
|
|||
"discord-api-types": "^0.37.61",
|
||||
"sass": "^1.57.1",
|
||||
"svelte": "^3.55.1",
|
||||
"svelte-preprocess": "^5.1.3",
|
||||
"tslib": "^2.6.2",
|
||||
"vite": "^4.5.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=v16.11"
|
||||
"node": ">=v21"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-x64": {
|
||||
|
@ -158,6 +161,12 @@
|
|||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@tsconfig/svelte": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@tsconfig/svelte/-/svelte-4.0.1.tgz",
|
||||
"integrity": "sha512-B+XlGpmuAQzJqDoBATNCvEPqQg0HkO7S8pM14QDI5NsmtymzRexQ1N+nX2H6RTtFbuFgaZD4I8AAi8voGg0GLg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/body-parser": {
|
||||
"version": "1.19.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz",
|
||||
|
@ -246,6 +255,12 @@
|
|||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/pug": {
|
||||
"version": "2.0.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/pug/-/pug-2.0.10.tgz",
|
||||
"integrity": "sha512-Sk/uYFOBAB7mb74XcpizmH0KOR2Pv3D2Hmrh1Dmy5BmK3MpdSa5kqZcg6EKBdklU0bFXX9gCfzvpnyUehrPIuA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/qs": {
|
||||
"version": "6.9.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz",
|
||||
|
@ -319,6 +334,12 @@
|
|||
"form-data": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/balanced-match": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/binary-extensions": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
|
||||
|
@ -351,6 +372,16 @@
|
|||
"npm": "1.2.8000 || >= 1.4.16"
|
||||
}
|
||||
},
|
||||
"node_modules/brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/braces": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
|
||||
|
@ -363,6 +394,15 @@
|
|||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/buffer-crc32": {
|
||||
"version": "0.2.13",
|
||||
"resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
|
||||
"integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/buffer-from": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
|
||||
|
@ -445,6 +485,12 @@
|
|||
"node": ">=16"
|
||||
}
|
||||
},
|
||||
"node_modules/concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/concat-stream": {
|
||||
"version": "1.6.2",
|
||||
"resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
|
||||
|
@ -566,6 +612,15 @@
|
|||
"npm": "1.2.8000 || >= 1.4.16"
|
||||
}
|
||||
},
|
||||
"node_modules/detect-indent": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz",
|
||||
"integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/dezalgo": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz",
|
||||
|
@ -602,6 +657,12 @@
|
|||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/es6-promise": {
|
||||
"version": "3.3.1",
|
||||
"resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz",
|
||||
"integrity": "sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/esbuild": {
|
||||
"version": "0.18.20",
|
||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz",
|
||||
|
@ -816,10 +877,19 @@
|
|||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/function-bind": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
|
||||
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
|
||||
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/get-intrinsic": {
|
||||
"version": "1.1.3",
|
||||
|
@ -834,6 +904,26 @@
|
|||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/glob": {
|
||||
"version": "7.2.3",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
|
||||
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
"inherits": "2",
|
||||
"minimatch": "^3.1.1",
|
||||
"once": "^1.3.0",
|
||||
"path-is-absolute": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/glob-parent": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
|
||||
|
@ -846,6 +936,12 @@
|
|||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/graceful-fs": {
|
||||
"version": "4.2.11",
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
|
||||
"integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/has": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
|
||||
|
@ -916,6 +1012,16 @@
|
|||
"integrity": "sha512-fTMKDwtbvO5tldky9QZ2fMX7slR0mYpY5nbnFWYp0fOzDhHqhgIw9KoYgxLWsoNTS9ZHGauHj18DTyEw6BK3Og==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/inflight": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||
"integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"once": "^1.3.0",
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"node_modules/inherits": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||
|
@ -1048,6 +1154,27 @@
|
|||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/min-indent": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
|
||||
"integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/minimatch": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/minimist": {
|
||||
"version": "1.2.6",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
|
||||
|
@ -1207,6 +1334,15 @@
|
|||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/path-is-absolute": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
||||
"integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/path-to-regexp": {
|
||||
"version": "0.1.7",
|
||||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
|
||||
|
@ -1342,6 +1478,18 @@
|
|||
"node": ">=8.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/rimraf": {
|
||||
"version": "2.7.1",
|
||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
|
||||
"integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"glob": "^7.1.3"
|
||||
},
|
||||
"bin": {
|
||||
"rimraf": "bin.js"
|
||||
}
|
||||
},
|
||||
"node_modules/rollup": {
|
||||
"version": "3.29.4",
|
||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz",
|
||||
|
@ -1382,6 +1530,18 @@
|
|||
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
|
||||
},
|
||||
"node_modules/sander": {
|
||||
"version": "0.5.1",
|
||||
"resolved": "https://registry.npmjs.org/sander/-/sander-0.5.1.tgz",
|
||||
"integrity": "sha512-3lVqBir7WuKDHGrKRDn/1Ye3kwpXaDOMsiRP1wd6wpZW56gJhsbp5RqQpA6JG/P+pkXizygnr1dKR8vzWaVsfA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"es6-promise": "^3.1.2",
|
||||
"graceful-fs": "^4.1.3",
|
||||
"mkdirp": "^0.5.1",
|
||||
"rimraf": "^2.5.2"
|
||||
}
|
||||
},
|
||||
"node_modules/sass": {
|
||||
"version": "1.57.1",
|
||||
"resolved": "https://registry.npmjs.org/sass/-/sass-1.57.1.tgz",
|
||||
|
@ -1459,6 +1619,21 @@
|
|||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/sorcery": {
|
||||
"version": "0.11.0",
|
||||
"resolved": "https://registry.npmjs.org/sorcery/-/sorcery-0.11.0.tgz",
|
||||
"integrity": "sha512-J69LQ22xrQB1cIFJhPfgtLuI6BpWRiWu1Y3vSsIwK/eAScqJxd/+CJlUuHQRdX2C9NGFamq+KqNywGgaThwfHw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@jridgewell/sourcemap-codec": "^1.4.14",
|
||||
"buffer-crc32": "^0.2.5",
|
||||
"minimist": "^1.2.0",
|
||||
"sander": "^0.5.0"
|
||||
},
|
||||
"bin": {
|
||||
"sorcery": "bin/sorcery"
|
||||
}
|
||||
},
|
||||
"node_modules/source-map-js": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
|
||||
|
@ -1497,6 +1672,18 @@
|
|||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
||||
},
|
||||
"node_modules/strip-indent": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz",
|
||||
"integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"min-indent": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/svelte": {
|
||||
"version": "3.55.1",
|
||||
"resolved": "https://registry.npmjs.org/svelte/-/svelte-3.55.1.tgz",
|
||||
|
@ -1518,6 +1705,69 @@
|
|||
"svelte": "^3.19.0 || ^4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/svelte-preprocess": {
|
||||
"version": "5.1.3",
|
||||
"resolved": "https://registry.npmjs.org/svelte-preprocess/-/svelte-preprocess-5.1.3.tgz",
|
||||
"integrity": "sha512-xxAkmxGHT+J/GourS5mVJeOXZzne1FR5ljeOUAMXUkfEhkLEllRreXpbl3dIYJlcJRfL1LO1uIAPpBpBfiqGPw==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
"@types/pug": "^2.0.6",
|
||||
"detect-indent": "^6.1.0",
|
||||
"magic-string": "^0.30.5",
|
||||
"sorcery": "^0.11.0",
|
||||
"strip-indent": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 16.0.0",
|
||||
"pnpm": "^8.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@babel/core": "^7.10.2",
|
||||
"coffeescript": "^2.5.1",
|
||||
"less": "^3.11.3 || ^4.0.0",
|
||||
"postcss": "^7 || ^8",
|
||||
"postcss-load-config": "^2.1.0 || ^3.0.0 || ^4.0.0 || ^5.0.0",
|
||||
"pug": "^3.0.0",
|
||||
"sass": "^1.26.8",
|
||||
"stylus": "^0.55.0",
|
||||
"sugarss": "^2.0.0 || ^3.0.0 || ^4.0.0",
|
||||
"svelte": "^3.23.0 || ^4.0.0-next.0 || ^4.0.0 || ^5.0.0-next.0",
|
||||
"typescript": ">=3.9.5 || ^4.0.0 || ^5.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@babel/core": {
|
||||
"optional": true
|
||||
},
|
||||
"coffeescript": {
|
||||
"optional": true
|
||||
},
|
||||
"less": {
|
||||
"optional": true
|
||||
},
|
||||
"postcss": {
|
||||
"optional": true
|
||||
},
|
||||
"postcss-load-config": {
|
||||
"optional": true
|
||||
},
|
||||
"pug": {
|
||||
"optional": true
|
||||
},
|
||||
"sass": {
|
||||
"optional": true
|
||||
},
|
||||
"stylus": {
|
||||
"optional": true
|
||||
},
|
||||
"sugarss": {
|
||||
"optional": true
|
||||
},
|
||||
"typescript": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/to-regex-range": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||
|
@ -1538,6 +1788,12 @@
|
|||
"node": ">=0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/tslib": {
|
||||
"version": "2.6.2",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
|
||||
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/type-is": {
|
||||
"version": "1.6.18",
|
||||
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@sveltejs/vite-plugin-svelte": "^2.4.6",
|
||||
"@tsconfig/svelte": "^4.0.1",
|
||||
"@types/bytes": "^3.1.1",
|
||||
"@types/cookie-parser": "^1.4.3",
|
||||
"@types/formidable": "^3.4.5",
|
||||
|
@ -46,6 +47,8 @@
|
|||
"discord-api-types": "^0.37.61",
|
||||
"sass": "^1.57.1",
|
||||
"svelte": "^3.55.1",
|
||||
"svelte-preprocess": "^5.1.3",
|
||||
"tslib": "^2.6.2",
|
||||
"vite": "^4.5.0"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
content="width=device-width, initial-scale=1.0, user-scalable=0"
|
||||
/>
|
||||
|
||||
<script type="module" src="./svelte/index.js"></script>
|
||||
<script type="module" src="./svelte/index.ts"></script>
|
||||
|
||||
<title>monofile</title>
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ export default async function ServeError(
|
|||
|
||||
|
||||
// serve error
|
||||
return ctx.req.header("accept").includes("text/html") ? ctx.html(
|
||||
return ctx.req.header("accept")?.includes("text/html") ? ctx.html(
|
||||
errorPage
|
||||
.replaceAll("$code", code.toString())
|
||||
.replaceAll("$text", reason),
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
.pulldown_display[name=accounts] {
|
||||
.pulldown_display[data-name=accounts] {
|
||||
.notLoggedIn {
|
||||
.container_div {
|
||||
position:absolute;
|
||||
|
@ -185,3 +185,41 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes bounce {
|
||||
0% {
|
||||
top: 0.25em;
|
||||
}/*
|
||||
25% {
|
||||
top: 0.25em;
|
||||
}
|
||||
75% {
|
||||
top: -0.25em;
|
||||
}*/
|
||||
100% {
|
||||
top: -0.25em;
|
||||
}
|
||||
}
|
||||
|
||||
.loader {
|
||||
i {
|
||||
font-style: normal;
|
||||
position: relative;
|
||||
|
||||
animation-name: bounce;
|
||||
animation-duration: 500ms;
|
||||
animation-iteration-count: infinite;
|
||||
animation-direction: alternate;
|
||||
top:0.25em;
|
||||
|
||||
&:nth-of-type(1) {
|
||||
animation-delay: 0ms;
|
||||
}
|
||||
&:nth-of-type(2) {
|
||||
animation-delay: 125ms;
|
||||
}
|
||||
&:nth-of-type(3) {
|
||||
animation-delay: 250ms;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
.pulldown_display[name=files] {
|
||||
.pulldown_display[data-name=files] {
|
||||
.notLoggedIn {
|
||||
position:absolute;
|
||||
top:50%;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
.pulldown_display[name=help] {
|
||||
.pulldown_display[data-name=help] {
|
||||
|
||||
overflow-y:auto;
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
span {
|
||||
position:relative;
|
||||
|
||||
&._add_files_txt {
|
||||
&.add_files_txt {
|
||||
font-size:16px;
|
||||
top:-4px;
|
||||
left:10px;
|
||||
|
@ -29,7 +29,7 @@
|
|||
@media screen and (max-width:500px) {
|
||||
font-size: 40px;
|
||||
|
||||
span._add_files_txt {
|
||||
span.add_files_txt {
|
||||
font-size:20px;
|
||||
top:-6px;
|
||||
left:10px;
|
||||
|
@ -45,7 +45,7 @@
|
|||
flex-direction:row;
|
||||
column-gap:10px;
|
||||
|
||||
button, input[type=text] {
|
||||
button, input[type=text], input[type=submit] {
|
||||
background-color:#333333;
|
||||
color:#DDDDDD;
|
||||
border:none;
|
||||
|
@ -63,7 +63,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
button {
|
||||
button, input[type=submit] {
|
||||
cursor:pointer;
|
||||
|
||||
&:hover {
|
||||
|
|
|
@ -50,7 +50,7 @@
|
|||
overflow:auto;
|
||||
}
|
||||
|
||||
button {
|
||||
button, input[type=submit] {
|
||||
cursor:pointer;
|
||||
background-color:#393939;
|
||||
color:#DDDDDD;
|
||||
|
|
|
@ -1,19 +1,13 @@
|
|||
<script>
|
||||
<script lang="ts">
|
||||
import { onMount } from "svelte";
|
||||
import Topbar from "./elem/Topbar.svelte";
|
||||
import PulldownManager from "./elem/PulldownManager.svelte";
|
||||
import UploadWindow from "./elem/UploadWindow.svelte";
|
||||
import { pulldownManager } from "./elem/stores.mjs";
|
||||
import { pulldownManager } from "./elem/stores.js";
|
||||
|
||||
/**
|
||||
* @type Topbar
|
||||
*/
|
||||
let topbar;
|
||||
let topbar: Topbar;
|
||||
|
||||
/**
|
||||
* @type PulldownManager
|
||||
*/
|
||||
let pulldown;
|
||||
let pulldown: PulldownManager;
|
||||
|
||||
onMount(() => {
|
||||
pulldownManager.set(pulldown)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<script context="module">
|
||||
<script context="module" lang="ts">
|
||||
import { writable } from "svelte/store";
|
||||
|
||||
// can't find a better way to do this
|
||||
|
@ -13,10 +13,10 @@
|
|||
.set("help",Help)
|
||||
.set("files",Files)
|
||||
|
||||
export const pulldownOpen = writable(false);
|
||||
export const pulldownOpen = writable<string|false>(false);
|
||||
</script>
|
||||
|
||||
<script>
|
||||
<script lang="ts">
|
||||
import { onMount } from "svelte";
|
||||
import { fade, scale } from "svelte/transition";
|
||||
|
||||
|
@ -24,7 +24,7 @@
|
|||
return $pulldownOpen
|
||||
}
|
||||
|
||||
export function openPulldown(name) {
|
||||
export function openPulldown(name: string) {
|
||||
pulldownOpen.set(name)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,14 +1,11 @@
|
|||
<script>
|
||||
<script lang="ts">
|
||||
import { circOut } from "svelte/easing";
|
||||
import { scale } from "svelte/transition";
|
||||
import PulldownManager, {pulldownOpen} from "./PulldownManager.svelte";
|
||||
import { account } from "./stores.mjs";
|
||||
import { _void } from "./transition/_void";
|
||||
import { account } from "./stores.js";
|
||||
import { _void } from "./transition/_void.js";
|
||||
|
||||
/**
|
||||
* @type PulldownManager
|
||||
*/
|
||||
export let pulldown;
|
||||
export let pulldown: PulldownManager;
|
||||
</script>
|
||||
|
||||
<div id="topbar">
|
||||
|
@ -23,7 +20,7 @@
|
|||
<!-- too lazy to make this better -->
|
||||
|
||||
<button class="menuBtn" on:click={() => pulldown.openPulldown("files")}>files</button>
|
||||
<button class="menuBtn" on:click={() => pulldown.openPulldown("account")}>{$account.username ? `@${$account.username}` : "account"}</button>
|
||||
<button class="menuBtn" on:click={() => pulldown.openPulldown("account")}>{$account?.username ? `@${$account.username}` : "account"}</button>
|
||||
<button class="menuBtn" on:click={() => pulldown.openPulldown("help")}>help</button>
|
||||
|
||||
<div /> <!-- not sure what's offcenter but something is
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<script>
|
||||
<script lang="ts">
|
||||
import { _void } from "./transition/_void.js"
|
||||
import { padding_scaleY } from "./transition/padding_scaleY.js"
|
||||
import { fade } from "svelte/transition"
|
||||
import { circIn, circOut } from "svelte/easing"
|
||||
import { serverStats, refresh_stats, account } from "./stores.mjs"
|
||||
import { serverStats, refresh_stats, account } from "./stores.js"
|
||||
import bytes from "bytes"
|
||||
|
||||
import AttachmentZone from "./uploader/AttachmentZone.svelte"
|
||||
|
@ -14,52 +14,44 @@
|
|||
|
||||
// uploads
|
||||
|
||||
interface Upload {
|
||||
file: string | File
|
||||
|
||||
params: {
|
||||
uploadId?: string
|
||||
}
|
||||
|
||||
uploadStatus: {
|
||||
fileId?: string,
|
||||
error?: string,
|
||||
}
|
||||
|
||||
maximized?: boolean,
|
||||
viewingUrl?: boolean
|
||||
}
|
||||
|
||||
let attachmentZone
|
||||
let uploads = {}
|
||||
let uploads: Record<string, Upload> = {}
|
||||
let uploadInProgress = false
|
||||
let notificationPermission =
|
||||
globalThis?.Notification?.permission ?? "denied"
|
||||
let handle_file_upload = (ev) => {
|
||||
if (ev.detail.type == "clone") {
|
||||
let handle_file_upload = (file: Event & { detail: File|string }) => {
|
||||
|
||||
uploads[Math.random().toString().slice(2)] = {
|
||||
type: "clone",
|
||||
name: ev.detail.url,
|
||||
url: ev.detail.url,
|
||||
file: file.detail,
|
||||
|
||||
params: {
|
||||
uploadId: "",
|
||||
},
|
||||
|
||||
uploadStatus: {
|
||||
fileId: null,
|
||||
error: null,
|
||||
},
|
||||
uploadStatus: {}
|
||||
}
|
||||
|
||||
uploads = uploads
|
||||
} else if (ev.detail.type == "upload") {
|
||||
ev.detail.files.forEach((v, x) => {
|
||||
uploads[Math.random().toString().slice(2)] = {
|
||||
type: "upload",
|
||||
name: v.name,
|
||||
file: v,
|
||||
|
||||
params: {
|
||||
uploadId: "",
|
||||
},
|
||||
|
||||
uploadStatus: {
|
||||
fileId: null,
|
||||
error: null,
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
uploads = uploads
|
||||
}
|
||||
}
|
||||
|
||||
let handle_fetch_promise = (x, prom) => {
|
||||
let handle_fetch_promise = (x: string, prom: Promise<Response>) => {
|
||||
return prom
|
||||
.then(async (res) => {
|
||||
let txt = await res.text()
|
||||
|
@ -81,8 +73,8 @@
|
|||
],
|
||||
}).addEventListener(
|
||||
"notificationclick",
|
||||
({ action }) => {
|
||||
if (action === "open") {
|
||||
(event) => {
|
||||
if ("action" in event && event.action === "open") {
|
||||
open(
|
||||
"/download/" +
|
||||
uploads[x].uploadStatus.fileId
|
||||
|
@ -115,7 +107,7 @@
|
|||
let hdl = () => {
|
||||
let fd = new FormData()
|
||||
if (v.params.uploadId) fd.append("uploadId", v.params.uploadId)
|
||||
fd.append("file", v.type == "clone" ? v.url : v.file)
|
||||
fd.append("file", v.file)
|
||||
|
||||
return handle_fetch_promise(x,fetch("/api/v1/file",{
|
||||
method: "PUT",
|
||||
|
@ -130,10 +122,10 @@
|
|||
|
||||
// animation
|
||||
|
||||
function fileTransition(node) {
|
||||
function fileTransition(node: HTMLElement) {
|
||||
return {
|
||||
duration: 300,
|
||||
css: (t) => {
|
||||
css: (t: number) => {
|
||||
let eased = circOut(t)
|
||||
|
||||
return `
|
||||
|
@ -175,7 +167,7 @@
|
|||
</h1>
|
||||
<p style:color="#999999">
|
||||
<span class="number"
|
||||
>{$serverStats.version ? `v${$serverStats.version}` : "•••"}</span
|
||||
>{$serverStats?.version ? `v${$serverStats?.version}` : "•••"}</span
|
||||
> — Discord based file sharing
|
||||
</p>
|
||||
|
||||
|
@ -195,12 +187,9 @@
|
|||
: ""}
|
||||
>
|
||||
<h2>
|
||||
{upload[1].name}
|
||||
{typeof upload[1].file == "string" ? upload[1].file : upload[1].file.name}
|
||||
<span style:color="#999999" style:font-weight="400"
|
||||
>{upload[1].type}{@html upload[1].type == "upload"
|
||||
? ` (${bytes(upload[1].file.size)})`
|
||||
: ""}</span
|
||||
>
|
||||
>{@html typeof upload[1].file == "string" ? "clone" : `upload (${bytes(upload[1].file.size)})`}</span>
|
||||
</h2>
|
||||
|
||||
{#if upload[1].maximized && !uploadInProgress}
|
||||
|
@ -319,7 +308,7 @@
|
|||
|
||||
{#if uploadInProgress == false}
|
||||
<!-- if required for upload, check if logged in -->
|
||||
{#if ($serverStats.accounts || {}).requiredForUpload ? !!$account.username : true}
|
||||
{#if $serverStats?.accounts?.requiredForUpload ? !!$account?.username : true}
|
||||
<AttachmentZone
|
||||
bind:this={attachmentZone}
|
||||
on:addFiles={handle_file_upload}
|
||||
|
@ -352,12 +341,12 @@
|
|||
|
||||
<p style:color="#999999" style:text-align="center">
|
||||
Hosting <span class="number" style:font-weight="600"
|
||||
>{$serverStats.files || "•••"}</span
|
||||
>{$serverStats?.files ?? "•••"}</span
|
||||
>
|
||||
files — Maximum filesize is
|
||||
<span class="number" style:font-weight="600">
|
||||
{
|
||||
$serverStats.maxDiscordFiles
|
||||
$serverStats?.maxDiscordFiles
|
||||
? bytes($serverStats.maxDiscordFileSize * $serverStats.maxDiscordFiles)
|
||||
: "•••"
|
||||
}</span>
|
||||
|
|
|
@ -1,28 +1,30 @@
|
|||
<script>
|
||||
<script lang="ts">
|
||||
import { fade, slide } from "svelte/transition";
|
||||
|
||||
interface BaseModalOption {
|
||||
name:string,
|
||||
icon:string,
|
||||
id: string | number | symbol | boolean
|
||||
}
|
||||
|
||||
let activeModal;
|
||||
let modalResults;
|
||||
type ModalOption = BaseModalOption & {inputSettings: {password?: boolean}, id: any} | BaseModalOption & { description: string }
|
||||
|
||||
/**
|
||||
*
|
||||
* @param mdl {name:string,icon:string,description:string,id:string}[]
|
||||
* @returns Promise
|
||||
*/
|
||||
export function picker(title,mdl) {
|
||||
type ModalOptions = ModalOption[]
|
||||
type OptionPickerReturns = {selected: any} & Record<any,any> | null
|
||||
let activeModal: {resolve: (val: OptionPickerReturns) => void, title: string, modal: ModalOptions } | undefined;
|
||||
let modalResults: Record<string | number | symbol, string> = {};
|
||||
|
||||
export function picker(title: string,mdl: ModalOptions): Promise<OptionPickerReturns> {
|
||||
if (activeModal) forceCancel()
|
||||
|
||||
return new Promise((resolve,reject) => {
|
||||
return new Promise<OptionPickerReturns>((resolve,reject) => {
|
||||
activeModal = {
|
||||
resolve,
|
||||
title,
|
||||
modal:mdl
|
||||
}
|
||||
|
||||
modalResults = {
|
||||
|
||||
}
|
||||
modalResults = {}
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -30,7 +32,7 @@
|
|||
if (activeModal && activeModal.resolve) {
|
||||
activeModal.resolve(null)
|
||||
}
|
||||
activeModal = null
|
||||
activeModal = undefined
|
||||
}
|
||||
</script>
|
||||
|
||||
|
@ -46,9 +48,9 @@
|
|||
</div>
|
||||
|
||||
{#each activeModal.modal as option (option.id)}
|
||||
{#if option.inputSettings}
|
||||
{#if "inputSettings" in option}
|
||||
<div class="inp">
|
||||
<img src={option.icon} alt={option.id}>
|
||||
<img src={option.icon} alt={option.id.toString()}>
|
||||
|
||||
<!-- i have to do this stupidness because of svelte but -->
|
||||
<!-- its reason for blocking this is pretty good sooooo -->
|
||||
|
@ -60,8 +62,8 @@
|
|||
{/if}
|
||||
</div>
|
||||
{:else}
|
||||
<button on:click={() => {activeModal.resolve({...modalResults,selected:option.id});activeModal=null;modalResults=null;}}>
|
||||
<img src={option.icon} alt={option.id}>
|
||||
<button on:click={() => {activeModal?.resolve({...modalResults,selected:option.id});activeModal=undefined;modalResults={};}}>
|
||||
<img src={option.icon} alt={option.id.toString()}>
|
||||
<p>{option.name}<span><br />{option.description}</span></p>
|
||||
</button>
|
||||
{/if}
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import { fetchAccountData, account, refreshNeeded } from "../stores.mjs"
|
||||
import { fetchAccountData, account, refreshNeeded } from "../stores"
|
||||
import { get } from "svelte/store";
|
||||
import type OptionPicker from "./OptionPicker.svelte";
|
||||
|
||||
export function deleteAccount(optPicker) {
|
||||
export function deleteAccount(optPicker: OptionPicker) {
|
||||
optPicker.picker("What should we do with your files?",[
|
||||
{
|
||||
name: "Delete my files",
|
||||
|
@ -56,7 +57,7 @@ export function deleteAccount(optPicker) {
|
|||
})
|
||||
}
|
||||
|
||||
export function userChange(optPicker) {
|
||||
export function userChange(optPicker: OptionPicker) {
|
||||
optPicker.picker("Change username",[
|
||||
{
|
||||
name: "New username",
|
||||
|
@ -86,7 +87,7 @@ export function userChange(optPicker) {
|
|||
})
|
||||
}
|
||||
|
||||
export function forgotPassword(optPicker) {
|
||||
export function forgotPassword(optPicker: OptionPicker) {
|
||||
optPicker.picker("Forgot your password?",[
|
||||
{
|
||||
name: "Username",
|
||||
|
@ -115,7 +116,7 @@ export function forgotPassword(optPicker) {
|
|||
})
|
||||
}
|
||||
|
||||
export function emailPotentialRemove(optPicker) {
|
||||
export function emailPotentialRemove(optPicker: OptionPicker) {
|
||||
optPicker.picker("What would you like to do?",[
|
||||
{
|
||||
name: "Set a new email",
|
||||
|
@ -148,7 +149,7 @@ export function emailPotentialRemove(optPicker) {
|
|||
})
|
||||
}
|
||||
|
||||
export function emailChange(optPicker) {
|
||||
export function emailChange(optPicker: OptionPicker) {
|
||||
optPicker.picker("Change email",[
|
||||
{
|
||||
name: "New email",
|
||||
|
@ -177,7 +178,7 @@ export function emailChange(optPicker) {
|
|||
})
|
||||
}
|
||||
|
||||
export function pwdChng(optPicker) {
|
||||
export function pwdChng(optPicker: OptionPicker) {
|
||||
optPicker.picker("Change password",[
|
||||
{
|
||||
name: "New password",
|
||||
|
@ -209,7 +210,7 @@ export function pwdChng(optPicker) {
|
|||
})
|
||||
}
|
||||
|
||||
export function customcss(optPicker) {
|
||||
export function customcss(optPicker: OptionPicker) {
|
||||
optPicker.picker("Set custom CSS",[
|
||||
{
|
||||
name: "Enter a file ID",
|
||||
|
@ -250,7 +251,7 @@ export function customcss(optPicker) {
|
|||
}
|
||||
|
||||
|
||||
export function embedColor(optPicker) {
|
||||
export function embedColor(optPicker: OptionPicker) {
|
||||
optPicker.picker("Set embed color",[
|
||||
{
|
||||
name: "FFFFFF",
|
||||
|
@ -290,7 +291,7 @@ export function embedColor(optPicker) {
|
|||
}
|
||||
|
||||
|
||||
export function embedSize(optPicker) {
|
||||
export function embedSize(optPicker: OptionPicker) {
|
||||
optPicker.picker("Set embed image size",[
|
||||
{
|
||||
name: "Large",
|
|
@ -1,7 +1,8 @@
|
|||
import { fetchAccountData, fetchFilePointers, account } from "../stores.mjs"
|
||||
import { fetchAccountData, fetchFilePointers, account } from "../stores"
|
||||
import { get } from "svelte/store";
|
||||
import type OptionPicker from "./OptionPicker.svelte";
|
||||
|
||||
export function pwdReset(optPicker) {
|
||||
export function pwdReset(optPicker: OptionPicker) {
|
||||
optPicker.picker("Reset password",[
|
||||
{
|
||||
name: "Target user",
|
||||
|
@ -39,7 +40,7 @@ export function pwdReset(optPicker) {
|
|||
})
|
||||
}
|
||||
|
||||
export function chgOwner(optPicker) {
|
||||
export function chgOwner(optPicker: OptionPicker) {
|
||||
optPicker.picker("Transfer file ownership",[
|
||||
{
|
||||
name: "File ID",
|
||||
|
@ -75,7 +76,7 @@ export function chgOwner(optPicker) {
|
|||
})
|
||||
}
|
||||
|
||||
export function chgId(optPicker) {
|
||||
export function chgId(optPicker: OptionPicker) {
|
||||
optPicker.picker("Change file ID",[
|
||||
{
|
||||
name: "Target file",
|
||||
|
@ -111,7 +112,7 @@ export function chgId(optPicker) {
|
|||
})
|
||||
}
|
||||
|
||||
export function delFile(optPicker) {
|
||||
export function delFile(optPicker: OptionPicker) {
|
||||
optPicker.picker("Delete file",[
|
||||
{
|
||||
name: "File ID",
|
||||
|
@ -140,7 +141,7 @@ export function delFile(optPicker) {
|
|||
})
|
||||
}
|
||||
|
||||
export function elevateUser(optPicker) {
|
||||
export function elevateUser(optPicker: OptionPicker) {
|
||||
optPicker.picker("Elevate user",[
|
||||
{
|
||||
name: "Username",
|
||||
|
@ -171,7 +172,7 @@ export function elevateUser(optPicker) {
|
|||
|
||||
// im really lazy so i just stole this from account.js
|
||||
|
||||
export function deleteAccount(optPicker) {
|
||||
export function deleteAccount(optPicker: OptionPicker) {
|
||||
optPicker.picker("What should we do with the target account's files?",[
|
||||
{
|
||||
name: "Delete files",
|
|
@ -1,5 +1,7 @@
|
|||
import { fetchAccountData, fetchFilePointers, account } from "../stores.mjs"
|
||||
import { fetchAccountData, fetchFilePointers, account } from "../stores"
|
||||
import { get } from "svelte/store";
|
||||
import type OptionPicker from "./OptionPicker.svelte"
|
||||
import type { FilePointer } from "../../../server/lib/files";
|
||||
|
||||
export let options = {
|
||||
FV: [
|
||||
|
@ -51,7 +53,7 @@ export let options = {
|
|||
]
|
||||
}
|
||||
|
||||
export function dfv(optPicker) {
|
||||
export function dfv(optPicker: OptionPicker) {
|
||||
optPicker.picker("Default file visibility",options.FV).then((exp) => {
|
||||
if (exp && exp.selected) {
|
||||
fetch(`/auth/dfv`,{method:"POST", body:JSON.stringify({
|
||||
|
@ -68,21 +70,21 @@ export function dfv(optPicker) {
|
|||
})
|
||||
}
|
||||
|
||||
export function update_all_files(optPicker) {
|
||||
export function update_all_files(optPicker: OptionPicker) {
|
||||
optPicker.picker("You sure?",[
|
||||
{
|
||||
name: "Yeah",
|
||||
icon: "/static/assets/icons/update.svg",
|
||||
description: `This will make all of your files ${get(account).defaultFileVisibility || "public"}`,
|
||||
description: `This will make all of your files ${get(account)?.defaultFileVisibility || "public"}`,
|
||||
id: true
|
||||
}
|
||||
]).then((exp) => {
|
||||
if (exp && exp.selected) {
|
||||
fetch(`/files/manage`,{method:"POST", body:JSON.stringify({
|
||||
target:get(account).files,
|
||||
target:get(account)?.files,
|
||||
action: "changeFileVisibility",
|
||||
|
||||
value: get(account).defaultFileVisibility
|
||||
value: get(account)?.defaultFileVisibility
|
||||
})}).then((response) => {
|
||||
|
||||
if (response.status != 200) {
|
||||
|
@ -95,7 +97,7 @@ export function update_all_files(optPicker) {
|
|||
})
|
||||
}
|
||||
|
||||
export function fileOptions(optPicker,file) {
|
||||
export function fileOptions(optPicker: OptionPicker, file: FilePointer & {id:string}) {
|
||||
optPicker.picker(file.filename,[
|
||||
{
|
||||
name: file.tag ? "Remove tag" : "Tag file",
|
|
@ -1,26 +1,26 @@
|
|||
<script>
|
||||
<script lang="ts">
|
||||
import Pulldown from "./Pulldown.svelte"
|
||||
import { padding_scaleY } from "../transition/padding_scaleY"
|
||||
import { circIn,circOut } from "svelte/easing"
|
||||
import { account, fetchAccountData, serverStats, refreshNeeded } from "../stores.mjs";
|
||||
import { account, fetchAccountData, serverStats, refreshNeeded } from "../stores";
|
||||
import { fade } from "svelte/transition";
|
||||
import OptionPicker from "../prompts/OptionPicker.svelte";
|
||||
import * as accOpts from "../prompts/account";
|
||||
import * as uplOpts from "../prompts/uploads";
|
||||
import * as admOpts from "../prompts/admin";
|
||||
|
||||
let targetAction
|
||||
let inProgress
|
||||
let authError
|
||||
let targetAction: "login"|"create"
|
||||
let inProgress: boolean
|
||||
let authError:{status:number,message:string}|undefined
|
||||
|
||||
let pwErr
|
||||
let pwErr: HTMLDivElement
|
||||
|
||||
let optPicker;
|
||||
let optPicker: OptionPicker;
|
||||
|
||||
// lazy
|
||||
|
||||
let username
|
||||
let password
|
||||
let username: string
|
||||
let password: string
|
||||
|
||||
let execute = () => {
|
||||
if (inProgress) return
|
||||
|
@ -43,7 +43,7 @@
|
|||
}
|
||||
})
|
||||
} else {
|
||||
authError = null, username = "", password = "";
|
||||
authError = undefined, username = "", password = "";
|
||||
fetchAccountData();
|
||||
}
|
||||
}).catch(() => {})
|
||||
|
@ -66,55 +66,7 @@
|
|||
|
||||
<Pulldown name="accounts">
|
||||
<OptionPicker bind:this={optPicker} />
|
||||
{#if Object.keys($account).length == 0}
|
||||
|
||||
<div class="notLoggedIn" transition:fade={{duration:200}}>
|
||||
<div class="container_div">
|
||||
<h1>monofile <span style:color="#999999">accounts</span></h1>
|
||||
<p class="flavor">Gain control of your uploads.</p>
|
||||
|
||||
{#if targetAction}
|
||||
|
||||
<div class="fields" out:padding_scaleY|local={{easingFunc:circIn}} in:padding_scaleY|local>
|
||||
{#if !$serverStats.accounts.registrationEnabled && targetAction == "create"}
|
||||
<div class="pwError">
|
||||
<div style:background-color="#554C33">
|
||||
<p>Account registration has been disabled by this instance's owner</p>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if authError}
|
||||
<div class="pwError" out:padding_scaleY|local={{easingFunc:circIn}} in:padding_scaleY|local>
|
||||
<div bind:this={pwErr}>
|
||||
<p><strong>{authError.status}</strong> {authError.message}</p>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<input placeholder="username" type="text" bind:value={username}>
|
||||
<input placeholder="password" type="password" bind:value={password}>
|
||||
<button on:click={execute}>{ inProgress ? "• • •" : (targetAction=="login" ? "Log in" : "Create account") }</button>
|
||||
|
||||
{#if targetAction == "login"}
|
||||
<button class="flavor" on:click={() => accOpts.forgotPassword(optPicker)}>I forgot my password</button>
|
||||
{/if}
|
||||
|
||||
</div>
|
||||
|
||||
{:else}
|
||||
|
||||
<div class="lgBtnContainer" out:padding_scaleY|local={{easingFunc:circIn}} in:padding_scaleY|local>
|
||||
<button on:click={() => targetAction="login"}>Log in</button>
|
||||
<button on:click={() => targetAction="create"}>Sign up</button>
|
||||
</div>
|
||||
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{:else}
|
||||
|
||||
{#if $account}
|
||||
<div class="loggedIn" transition:fade={{duration:200}}>
|
||||
<h1>
|
||||
Hey there, <span class="monospace">@{$account.username}</span>
|
||||
|
@ -131,7 +83,7 @@
|
|||
<p>Change username</p>
|
||||
</button>
|
||||
|
||||
<button on:click={() => ($account.email ? accOpts.emailPotentialRemove : accOpts.emailChange)(optPicker)}>
|
||||
<button on:click={() => ($account?.email ? accOpts.emailPotentialRemove : accOpts.emailChange)(optPicker)}>
|
||||
<img src="/static/assets/icons/mail.svg" alt="change email">
|
||||
<p>Change email{#if $account.email}<span class="monospaceText"><br />{$account.email}</span>{/if}</p>
|
||||
</button>
|
||||
|
@ -182,7 +134,7 @@
|
|||
</button>
|
||||
|
||||
{#if $refreshNeeded}
|
||||
<button on:click={() => window.location.reload(true)} transition:fade={{duration: 200}}>
|
||||
<button on:click={() => window.location.reload()} transition:fade={{duration: 200}}>
|
||||
<img src="/static/assets/icons/refresh.svg" alt="refresh">
|
||||
<p>Refresh<span><br />Changes were made which require a refresh</span></p>
|
||||
</button>
|
||||
|
@ -194,12 +146,12 @@
|
|||
|
||||
<button on:click={() => fetch(`/auth/logout_sessions`,{method:"POST"}).then(() => fetchAccountData())}>
|
||||
<img src="/static/assets/icons/logout_all.svg" alt="logout_all">
|
||||
<p>Log out all sessions<span><br />{$account.sessionCount} session(s) active</span></p>
|
||||
<p>Log out all sessions<span><br />{$account?.sessionCount} session(s) active</span></p>
|
||||
</button>
|
||||
|
||||
<button on:click={() => fetch(`/auth/logout`,{method:"POST"}).then(() => fetchAccountData())}>
|
||||
<img src="/static/assets/icons/logout.svg" alt="logout">
|
||||
<p>Log out<span><br />Session expires {new Date($account.sessionExpires).toLocaleDateString()}</span></p>
|
||||
<p>Log out<span><br />Session expires {new Date($account?.sessionExpires).toLocaleDateString()}</span></p>
|
||||
</button>
|
||||
|
||||
{#if $account.admin}
|
||||
|
@ -242,6 +194,50 @@
|
|||
<p style="font-size:12px;color:#AAAAAA;text-align:center;" class="monospace"><br />{$account.id}</p>
|
||||
</div>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="notLoggedIn" transition:fade={{duration:200}}>
|
||||
<div class="container_div">
|
||||
<h1>monofile <span style:color="#999999">accounts</span></h1>
|
||||
<p class="flavor">Gain control of your uploads.</p>
|
||||
|
||||
{#if targetAction}
|
||||
|
||||
<div class="fields" out:padding_scaleY|local={{easingFunc:circIn}} in:padding_scaleY|local>
|
||||
{#if !$serverStats?.accounts.registrationEnabled && targetAction == "create"}
|
||||
<div class="pwError">
|
||||
<div style:background-color="#554C33">
|
||||
<p>Account registration has been disabled by this instance's owner</p>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if authError}
|
||||
<div class="pwError" out:padding_scaleY|local={{easingFunc:circIn}} in:padding_scaleY|local>
|
||||
<div bind:this={pwErr}>
|
||||
<p><strong>{authError.status}</strong> {authError.message}</p>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<input placeholder="username" type="text" bind:value={username}>
|
||||
<input placeholder="password" type="password" bind:value={password}>
|
||||
<button on:click={execute}>{@html inProgress ? "<span class=loader><i>•</i> <i>•</i> <i>•</i></span>" : (targetAction=="login" ? "Log in" : "Create account") }</button>
|
||||
|
||||
{#if targetAction == "login"}
|
||||
<button class="flavor" on:click={() => accOpts.forgotPassword(optPicker)}>I forgot my password</button>
|
||||
{/if}
|
||||
|
||||
</div>
|
||||
|
||||
{:else}
|
||||
|
||||
<div class="lgBtnContainer" out:padding_scaleY|local={{easingFunc:circIn}} in:padding_scaleY|local>
|
||||
<button on:click={() => targetAction="login"}>Log in</button>
|
||||
<button on:click={() => targetAction="create"}>Sign up</button>
|
||||
</div>
|
||||
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</Pulldown>
|
|
@ -1,13 +1,13 @@
|
|||
<script>
|
||||
<script lang="ts">
|
||||
import Pulldown from "./Pulldown.svelte";
|
||||
import { account, fetchFilePointers, files, pulldownManager } from "../stores.mjs";
|
||||
import { account, fetchFilePointers, files, pulldownManager } from "../stores.js";
|
||||
|
||||
import { fade } from "svelte/transition";
|
||||
import { flip } from "svelte/animate";
|
||||
import { fileOptions } from "../prompts/uploads";
|
||||
import OptionPicker from "../prompts/OptionPicker.svelte";
|
||||
|
||||
let picker;
|
||||
let picker: OptionPicker;
|
||||
let query = "";
|
||||
|
||||
fetchFilePointers();
|
||||
|
@ -17,22 +17,14 @@
|
|||
|
||||
<OptionPicker bind:this={picker} />
|
||||
|
||||
{#if !$account.username}
|
||||
<div class="notLoggedIn">
|
||||
<div style:height="10px" />
|
||||
<p class="flavor">Log in to view uploads</p>
|
||||
<button on:click={$pulldownManager.openPulldown("account")}>OK</button>
|
||||
<div style:height="14px" />
|
||||
</div>
|
||||
{:else}
|
||||
<div class="loggedIn">
|
||||
{#if $account?.username}<div class="loggedIn">
|
||||
<input type="text" placeholder={`Search ${$files.length} file(s)`} class="searchBar" bind:value={query}>
|
||||
|
||||
<div class="fileList">
|
||||
<!-- Probably wildly inefficient but who cares, I just wanna get this over with -->
|
||||
{#each $files.filter(f => f&&(f.filename.toLowerCase().includes(query.toLowerCase()) || f.id.toLowerCase().includes(query.toLowerCase()) || f.tag?.includes(query.toLowerCase()))) as file (file.id)}
|
||||
<div class="flFile" transition:fade={{duration:200}} animate:flip={{duration:200}}>
|
||||
<button class="hitbox" on:click={window.open(`/download/${file.id}`)}></button> <!-- this is bad, but I'm lazy -->
|
||||
<button class="hitbox" on:click={() => window.open(`/download/${file.id}`)}></button> <!-- this is bad, but I'm lazy -->
|
||||
<div class="flexCont">
|
||||
<div class="fileInfo">
|
||||
<h2>{file.filename}</h2>
|
||||
|
@ -51,7 +43,7 @@
|
|||
{/if}
|
||||
</p>
|
||||
</div>
|
||||
<button class="more" on:click={fileOptions(picker, file)}>
|
||||
<button class="more" on:click={() => fileOptions(picker, file)}>
|
||||
<img src="/static/assets/icons/more.svg" alt="more" />
|
||||
</button>
|
||||
</div>
|
||||
|
@ -59,6 +51,13 @@
|
|||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="notLoggedIn">
|
||||
<div style:height="10px" />
|
||||
<p class="flavor">Log in to view uploads</p>
|
||||
<button on:click={$pulldownManager.openPulldown("account")}>OK</button>
|
||||
<div style:height="14px" />
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
</Pulldown>
|
|
@ -1,13 +1,13 @@
|
|||
<script>
|
||||
<script lang=ts>
|
||||
|
||||
import { fade } from "svelte/transition";
|
||||
|
||||
export let name;
|
||||
export let name: string;
|
||||
|
||||
</script>
|
||||
<div
|
||||
class="pulldown_display"
|
||||
name={name}
|
||||
data-name={name}
|
||||
transition:fade={{duration:150}}
|
||||
>
|
||||
<slot />
|
||||
|
|
|
@ -1,17 +1,22 @@
|
|||
import { writable } from "svelte/store"
|
||||
//import type Pulldown from "./pulldowns/Pulldown.svelte"
|
||||
import type { SvelteComponent } from "svelte"
|
||||
import type { Account } from "../../server/lib/accounts"
|
||||
import type cfg from "../../../config.json"
|
||||
import type { FilePointer } from "../../server/lib/files"
|
||||
|
||||
export let refreshNeeded = writable(false)
|
||||
export let pulldownManager = writable(0)
|
||||
export let account = writable({})
|
||||
export let serverStats = writable({})
|
||||
export let files = writable([])
|
||||
export let pulldownManager = writable<SvelteComponent>()
|
||||
export let account = writable<Account & {sessionCount: number, sessionExpires: number}|undefined>()
|
||||
export let serverStats = writable<typeof cfg & {version: string, files: number} | undefined>()
|
||||
export let files = writable<(FilePointer & {id:string})[]>([])
|
||||
|
||||
export let fetchAccountData = function() {
|
||||
fetch("/auth/me").then(async (response) => {
|
||||
if (response.status == 200) {
|
||||
account.set(await response.json())
|
||||
} else {
|
||||
account.set({})
|
||||
account.set(undefined)
|
||||
}
|
||||
}).catch((err) => { console.error(err) })
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
import { circIn, circOut } from "svelte/easing"
|
||||
|
||||
export function _void(node, { duration, easingFunc, op, prop, rTarg }) {
|
||||
let rect = node.getBoundingClientRect()
|
||||
|
||||
return {
|
||||
duration: duration||300,
|
||||
css: t => {
|
||||
let eased = (easingFunc || circIn)(t)
|
||||
|
||||
return `
|
||||
white-space: nowrap;
|
||||
${prop||"height"}: ${(eased)*(rect[rTarg||prop||"height"])}px;
|
||||
padding: 0px;
|
||||
opacity:${eased};
|
||||
overflow: clip;
|
||||
`
|
||||
}
|
||||
}
|
||||
}
|
23
src/svelte/elem/transition/_void.ts
Normal file
23
src/svelte/elem/transition/_void.ts
Normal file
|
@ -0,0 +1,23 @@
|
|||
import { circIn, circOut } from "svelte/easing"
|
||||
|
||||
export function _void(
|
||||
node: HTMLElement,
|
||||
options?: { duration?:number, easingFunc?: (a:number)=>number, prop?:string, rTarg?: "height"|"width"}
|
||||
) {
|
||||
const { duration = 300, easingFunc = circIn, prop, rTarg } = options ?? {}
|
||||
let rect = node.getBoundingClientRect()
|
||||
|
||||
return {
|
||||
duration,
|
||||
css: (t: number) => {
|
||||
let eased = easingFunc(t)
|
||||
return `
|
||||
white-space: nowrap;
|
||||
${prop||"height"}: ${(eased)*(rect[rTarg || (prop && prop in rect) ? prop as keyof Omit<DOMRect, "toJSON"> : "height"])}px;
|
||||
padding: 0px;
|
||||
opacity:${eased};
|
||||
overflow: clip;
|
||||
`
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
import { circIn, circOut } from "svelte/easing"
|
||||
|
||||
export function padding_scaleY(node, { duration, easingFunc, padY, padX, op }) {
|
||||
let rect = node.getBoundingClientRect()
|
||||
|
||||
return {
|
||||
duration: duration||300,
|
||||
css: t => {
|
||||
let eased = (easingFunc || circOut)(t)
|
||||
|
||||
return `
|
||||
height: ${eased*(rect.height-(padY||0))}px;
|
||||
${padX&&padY ? `padding: ${(eased)*(padY)}px ${(padX)}px;` : ""}
|
||||
${op ? `opacity: ${eased};` : ""}
|
||||
`
|
||||
}
|
||||
}
|
||||
}
|
21
src/svelte/elem/transition/padding_scaleY.ts
Normal file
21
src/svelte/elem/transition/padding_scaleY.ts
Normal file
|
@ -0,0 +1,21 @@
|
|||
import { circIn, circOut } from "svelte/easing"
|
||||
|
||||
function padding_scaleY(node: HTMLElement, options?: { duration?: number, easingFunc?: (a: number) => number, padY?: number, padX?: number, op?: boolean }) {
|
||||
const { duration = 300, easingFunc = circOut, padY, padX, op } = options ?? {}
|
||||
let rect = node.getBoundingClientRect()
|
||||
|
||||
return {
|
||||
duration,
|
||||
css: (t:number) => {
|
||||
let eased = easingFunc(t)
|
||||
|
||||
return `
|
||||
height: ${eased*(rect.height-(padY||0))}px;
|
||||
${padX&&padY ? `padding: ${(eased)*(padY)}px ${(padX)}px;` : ""}
|
||||
${op ? `opacity: ${eased};` : ""}
|
||||
`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export {padding_scaleY}
|
|
@ -1,56 +1,35 @@
|
|||
<script>
|
||||
<script lang="ts">
|
||||
import { createEventDispatcher } from "svelte";
|
||||
import { circIn, circOut } from "svelte/easing"
|
||||
import { fade } from "svelte/transition";
|
||||
import { circOut } from "svelte/easing"
|
||||
import { _void } from "../transition/_void"
|
||||
|
||||
let uploadTypes = {
|
||||
files: 1,
|
||||
clone: 2
|
||||
enum UploadTypes {
|
||||
None,
|
||||
Files,
|
||||
Clone
|
||||
}
|
||||
|
||||
let uploadType = undefined
|
||||
let uploadType: UploadTypes = UploadTypes.None
|
||||
let dispatch = createEventDispatcher();
|
||||
|
||||
// file upload
|
||||
|
||||
/**
|
||||
* @type HTMLInputElement
|
||||
*/
|
||||
let fileUpload;
|
||||
|
||||
$: {
|
||||
if (fileUpload) {
|
||||
fileUpload.addEventListener("change",() => {
|
||||
dispatch("addFiles",{
|
||||
type: "upload",
|
||||
files: Array.from(fileUpload.files)
|
||||
})
|
||||
uploadType = undefined
|
||||
})
|
||||
}
|
||||
let files: FileList | undefined
|
||||
$: if (files) {
|
||||
[...files].forEach(file=>dispatch("addFiles", file))
|
||||
uploadType = UploadTypes.None
|
||||
}
|
||||
|
||||
// file clone
|
||||
/**
|
||||
* @type HTMLButtonElement
|
||||
*/
|
||||
let cloneButton;
|
||||
|
||||
/**
|
||||
* @type HTMLInputElement
|
||||
*/
|
||||
let cloneUrlTextbox;
|
||||
let cloneUrlTextbox: HTMLInputElement;
|
||||
let cloneForm: HTMLFormElement;
|
||||
|
||||
$: {
|
||||
if (cloneButton && cloneUrlTextbox) {
|
||||
cloneButton.addEventListener("click",() => {
|
||||
if (cloneForm && cloneUrlTextbox) {
|
||||
cloneForm.addEventListener("submit",(e) => {
|
||||
e.preventDefault()
|
||||
if (cloneUrlTextbox.value) {
|
||||
dispatch("addFiles",{
|
||||
type: "clone",
|
||||
url: cloneUrlTextbox.value
|
||||
})
|
||||
uploadType = undefined;
|
||||
dispatch("addFiles",cloneUrlTextbox.value)
|
||||
uploadType = UploadTypes.None;
|
||||
} else {
|
||||
cloneUrlTextbox.animate([
|
||||
{"transform":"translateX(0px)"},
|
||||
|
@ -68,26 +47,26 @@
|
|||
|
||||
<div id="add_new_files" transition:_void={{duration:200}}>
|
||||
<p>
|
||||
+<span class="_add_files_txt">add files</span>
|
||||
+<span class="add_files_txt">add files</span>
|
||||
</p>
|
||||
{#if !uploadType}
|
||||
{#if uploadType == UploadTypes.None}
|
||||
<div id="file_add_btns" out:_void in:_void={{easingFunc:circOut}}>
|
||||
<button on:click={() => uploadType = uploadTypes.files} >upload files...</button>
|
||||
<button on:click={() => uploadType = uploadTypes.clone} >clone url...</button>
|
||||
<button on:click={() => uploadType = UploadTypes.Files} >upload files...</button>
|
||||
<button on:click={() => uploadType = UploadTypes.Clone} >clone url...</button>
|
||||
</div>
|
||||
{:else}
|
||||
{#if uploadType == uploadTypes.files}
|
||||
{#if uploadType == UploadTypes.Files}
|
||||
<div id="file_add_btns" out:_void in:_void={{easingFunc:circOut}}>
|
||||
<div class="fileUpload">
|
||||
<p>click/tap to browse<br/>or drag files into this box</p>
|
||||
<input type="file" multiple bind:this={fileUpload}>
|
||||
<input type="file" multiple bind:files={files}>
|
||||
</div>
|
||||
</div>
|
||||
{:else if uploadType == uploadTypes.clone}
|
||||
<div id="file_add_btns" out:_void in:_void={{easingFunc:circOut}}>
|
||||
{:else if uploadType == UploadTypes.Clone}
|
||||
<form id="file_add_btns" out:_void in:_void={{easingFunc:circOut}} bind:this={cloneForm}>
|
||||
<input placeholder="url" type="text" bind:this={cloneUrlTextbox}>
|
||||
<button style:flex-basis="30%" bind:this={cloneButton}>add file</button>
|
||||
</div>
|
||||
<input type="submit" value="add file" style:flex-basis="30%">
|
||||
</form>
|
||||
{/if}
|
||||
{/if}
|
||||
</div>
|
1
src/svelte/global.d.ts
vendored
Normal file
1
src/svelte/global.d.ts
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
/// <reference types="svelte" />
|
18
src/svelte/tsconfig.json
Normal file
18
src/svelte/tsconfig.json
Normal file
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"extends": "@tsconfig/svelte/tsconfig.json",
|
||||
"include": ["**/*"],
|
||||
"compilerOptions": {
|
||||
"target": "ESNext",
|
||||
"outDir": "../../dist/static/vite",
|
||||
"useDefineForClassFields": true,
|
||||
"module": "ESNext",
|
||||
"resolveJsonModule": true,
|
||||
"allowJs": true,
|
||||
"checkJs": true,
|
||||
"isolatedModules": true,
|
||||
"moduleResolution": "bundler"
|
||||
},
|
||||
"references": [
|
||||
{ "path": "../../tsconfig.json" }
|
||||
]
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
import { defineConfig } from "vite"
|
||||
import { svelte } from "@sveltejs/vite-plugin-svelte"
|
||||
import autoPreprocess from "svelte-preprocess"
|
||||
import { resolve } from "path"
|
||||
export default defineConfig({
|
||||
root: "./src",
|
||||
|
@ -14,5 +15,7 @@ export default defineConfig({
|
|||
},
|
||||
},
|
||||
},
|
||||
plugins: [svelte({})],
|
||||
plugins: [svelte({
|
||||
preprocess: autoPreprocess()
|
||||
})],
|
||||
})
|
Loading…
Reference in a new issue