diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index b2a59f77..ab601df6 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -16,7 +16,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-node@v2 with: - node-version: '16' + node-version: '18' - run: make lint-frontend lint-backend: runs-on: ubuntu-latest @@ -24,7 +24,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-go@v2 with: - go-version: 1.20.6 + go-version: 1.21.0 - run: make lint-backend lint-commits: runs-on: ubuntu-latest @@ -34,7 +34,7 @@ jobs: fetch-depth: 0 - uses: actions/setup-node@v2 with: - node-version: '16' + node-version: '18' - run: make lint-commits lint: runs-on: ubuntu-latest @@ -49,7 +49,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-node@v2 with: - node-version: '16' + node-version: '18' - run: make test-frontend test-backend: runs-on: ubuntu-latest @@ -57,7 +57,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-go@v2 with: - go-version: 1.20.6 + go-version: 1.21.0 - run: make test-backend test: runs-on: ubuntu-latest @@ -76,10 +76,10 @@ jobs: fetch-depth: 0 - uses: actions/setup-go@v2 with: - go-version: 1.20.6 + go-version: 1.21.0 - uses: actions/setup-node@v2 with: - node-version: '16' + node-version: '18' - name: Set up QEMU uses: docker/setup-qemu-action@v1 - name: Set up Docker Buildx diff --git a/.gitignore b/.gitignore index 830774b6..5180999f 100644 --- a/.gitignore +++ b/.gitignore @@ -29,3 +29,6 @@ yarn-error.log* *.sw* bin/ build/ + +/frontend/dist/* +!/frontend/dist/.gitkeep diff --git a/files/file.go b/files/file.go index 51ed7a72..e0fdb162 100644 --- a/files/file.go +++ b/files/file.go @@ -29,20 +29,21 @@ const PermDir = 0755 // FileInfo describes a file. type FileInfo struct { *Listing - Fs afero.Fs `json:"-"` - Path string `json:"path"` - Name string `json:"name"` - Size int64 `json:"size"` - Extension string `json:"extension"` - ModTime time.Time `json:"modified"` - Mode os.FileMode `json:"mode"` - IsDir bool `json:"isDir"` - IsSymlink bool `json:"isSymlink"` - Type string `json:"type"` - Subtitles []string `json:"subtitles,omitempty"` - Content string `json:"content,omitempty"` - Checksums map[string]string `json:"checksums,omitempty"` - Token string `json:"token,omitempty"` + Fs afero.Fs `json:"-"` + Path string `json:"path"` + Name string `json:"name"` + Size int64 `json:"size"` + Extension string `json:"extension"` + ModTime time.Time `json:"modified"` + Mode os.FileMode `json:"mode"` + IsDir bool `json:"isDir"` + IsSymlink bool `json:"isSymlink"` + Type string `json:"type"` + Subtitles []string `json:"subtitles,omitempty"` + Content string `json:"content,omitempty"` + Checksums map[string]string `json:"checksums,omitempty"` + Token string `json:"token,omitempty"` + currentDir []os.FileInfo `json:"-"` } // FileOptions are the options when getting a file info. @@ -294,13 +295,21 @@ func (i *FileInfo) detectSubtitles() { // detect multiple languages. Base*.vtt // TODO: give subtitles descriptive names (lang) and track attributes parentDir := strings.TrimRight(i.Path, i.Name) - dir, err := afero.ReadDir(i.Fs, parentDir) - if err == nil { - base := strings.TrimSuffix(i.Name, ext) - for _, f := range dir { - if !f.IsDir() && strings.HasPrefix(f.Name(), base) && strings.HasSuffix(f.Name(), ".vtt") { - i.Subtitles = append(i.Subtitles, path.Join(parentDir, f.Name())) - } + var dir []os.FileInfo + if len(i.currentDir) > 0 { + dir = i.currentDir + } else { + var err error + dir, err = afero.ReadDir(i.Fs, parentDir) + if err != nil { + return + } + } + + base := strings.TrimSuffix(i.Name, ext) + for _, f := range dir { + if !f.IsDir() && strings.HasPrefix(f.Name(), base) && strings.HasSuffix(f.Name(), ".vtt") { + i.Subtitles = append(i.Subtitles, path.Join(parentDir, f.Name())) } } } @@ -340,15 +349,16 @@ func (i *FileInfo) readListing(checker rules.Checker, readHeader bool) error { } file := &FileInfo{ - Fs: i.Fs, - Name: name, - Size: f.Size(), - ModTime: f.ModTime(), - Mode: f.Mode(), - IsDir: f.IsDir(), - IsSymlink: isSymlink, - Extension: filepath.Ext(name), - Path: fPath, + Fs: i.Fs, + Name: name, + Size: f.Size(), + ModTime: f.ModTime(), + Mode: f.Mode(), + IsDir: f.IsDir(), + IsSymlink: isSymlink, + Extension: filepath.Ext(name), + Path: fPath, + currentDir: dir, } if file.IsDir { diff --git a/frontend/.eslintrc.json b/frontend/.eslintrc.json index e8c83858..607f9b61 100644 --- a/frontend/.eslintrc.json +++ b/frontend/.eslintrc.json @@ -9,7 +9,7 @@ "@vue/eslint-config-prettier" ], "rules": { - "vue/multi-word-component-names": "warn", + "vue/multi-word-component-names": "off", "vue/no-reserved-component-names": "warn", "vue/no-mutating-props": "warn" }, diff --git a/frontend/.gitignore b/frontend/.gitignore deleted file mode 100644 index 9770f7e8..00000000 --- a/frontend/.gitignore +++ /dev/null @@ -1,130 +0,0 @@ -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -lerna-debug.log* -.pnpm-debug.log* - -# Diagnostic reports (https://nodejs.org/api/report.html) -report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json - -# Runtime data -pids -*.pid -*.seed -*.pid.lock - -# Directory for instrumented libs generated by jscoverage/JSCover -lib-cov - -# Coverage directory used by tools like istanbul -coverage -*.lcov - -# nyc test coverage -.nyc_output - -# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) -.grunt - -# Bower dependency directory (https://bower.io/) -bower_components - -# node-waf configuration -.lock-wscript - -# Compiled binary addons (https://nodejs.org/api/addons.html) -build/Release - -# Dependency directories -node_modules/ -jspm_packages/ - -# Snowpack dependency directory (https://snowpack.dev/) -web_modules/ - -# TypeScript cache -*.tsbuildinfo - -# Optional npm cache directory -.npm - -# Optional eslint cache -.eslintcache - -# Optional stylelint cache -.stylelintcache - -# Microbundle cache -.rpt2_cache/ -.rts2_cache_cjs/ -.rts2_cache_es/ -.rts2_cache_umd/ - -# Optional REPL history -.node_repl_history - -# Output of 'npm pack' -*.tgz - -# Yarn Integrity file -.yarn-integrity - -# dotenv environment variable files -.env -.env.development.local -.env.test.local -.env.production.local -.env.local - -# parcel-bundler cache (https://parceljs.org/) -.cache -.parcel-cache - -# Next.js build output -.next -out - -# Nuxt.js build / generate output -.nuxt -dist/* - -# Gatsby files -.cache/ -# Comment in the public line in if your project uses Gatsby and not Next.js -# https://nextjs.org/blog/next-9-1#public-directory-support -# public - -# vuepress build output -.vuepress/dist - -# vuepress v2.x temp and cache directory -.temp -.cache - -# Docusaurus cache and generated files -.docusaurus - -# Serverless directories -.serverless/ - -# FuseBox cache -.fusebox/ - -# DynamoDB Local files -.dynamodb/ - -# TernJS port file -.tern-port - -# Stores VSCode versions used for testing VSCode extensions -.vscode-test - -# yarn v2 -.yarn/cache -.yarn/unplugged -.yarn/build-state.yml -.yarn/install-state.gz -.pnp.* diff --git a/frontend/dist/.gitkeep b/frontend/dist/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 4e97989d..a3ff1096 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -3671,7 +3671,8 @@ "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", "dev": true, "dependencies": { - "eslint-visitor-keys": "^1.1.0" + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" }, "engines": { "node": ">=6" @@ -3798,6 +3799,108 @@ "node": ">=8" } }, + "node_modules/eslint/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/espree": { "version": "9.6.1", "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", @@ -3815,17 +3918,16 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "node_modules/espree/node_modules/eslint-visitor-keys": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.2.tgz", + "integrity": "sha512-8drBzUEyZ2llkpCA67iYrgEssKDUu68V8ChqqOfFupIaG/LCVPUT+CoGJpT77zJprs4T/W7p07LP7zAIMuweVw==", "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, "engines": { - "node": ">=4" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/esquery": { @@ -6007,6 +6109,20 @@ "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-1.4.0.tgz", "integrity": "sha512-5x4eIEL6WgbzqGtF9UV8VEC/ehKptPXDS6L2b0mv4FRMkJxRtjaJfOWDd6a8+kYbqsjklix7yWP0N3SUepjXcg==", "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "dependencies": { "acorn": "^8.9.0", "chokidar": "^3.5.3", diff --git a/frontend/package.json b/frontend/package.json index 35390a7c..8b80f7f6 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -8,9 +8,10 @@ "serve": "vite serve", "build": "vite build", "watch": "vite build --watch", - "lint": "eslint --ext .vue,.js,.ts --ignore-path .gitignore src/", - "lint:fix": "eslint --ext .vue,.js,.ts --ignore-path .gitignore --fix src/", - "format": "prettier --write src/" + "clean": "find ./dist -maxdepth 1 -mindepth 1 ! -name '.gitkeep' -exec rm -r {} +", + "lint": "eslint --ext .vue,.js src/", + "lint:fix": "eslint --ext .vue,.js --fix src/", + "format": "prettier --write ." }, "dependencies": { "@vue/compat": "^3.3.4", diff --git a/frontend/public/.gitkeep b/frontend/public/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/frontend/src/components/files/ListingItem.vue b/frontend/src/components/files/ListingItem.vue index 0e46a5d3..261c83af 100644 --- a/frontend/src/components/files/ListingItem.vue +++ b/frontend/src/components/files/ListingItem.vue @@ -41,8 +41,9 @@ import { useFileStore } from "@/stores/file"; import { useLayoutStore } from "@/stores/layout"; import { enableThumbs } from "@/utils/constants"; -import { filesize } from "filesize"; -import dayjs from "dayjs"; +import { mapMutations, mapGetters, mapState } from "vuex"; +import filesize from "filesize"; +import moment from "moment"; import { files as api } from "@/api"; import * as upload from "@/utils/upload"; diff --git a/frontend/src/components/prompts/Copy.vue b/frontend/src/components/prompts/Copy.vue index ab40a40d..66c07cdf 100644 --- a/frontend/src/components/prompts/Copy.vue +++ b/frontend/src/components/prompts/Copy.vue @@ -33,11 +33,11 @@