Beta/v0.5.2 release (#356)
This commit is contained in:
parent
545a831c66
commit
c84a3b0d41
16
CHANGELOG.md
16
CHANGELOG.md
|
@ -2,6 +2,22 @@
|
||||||
|
|
||||||
All notable changes to this project will be documented in this file. For commit guidelines, please refer to [Standard Version](https://github.com/conventional-changelog/standard-version).
|
All notable changes to this project will be documented in this file. For commit guidelines, please refer to [Standard Version](https://github.com/conventional-changelog/standard-version).
|
||||||
|
|
||||||
|
## v0.5.2-beta
|
||||||
|
|
||||||
|
**New Features**:
|
||||||
|
- Markdown file preview https://github.com/gtsteffaniak/filebrowser/issues/343
|
||||||
|
- Easy access download button https://github.com/gtsteffaniak/filebrowser/issues/341
|
||||||
|
|
||||||
|
**Notes**:
|
||||||
|
- Adds message about what sharing means when creating a link.
|
||||||
|
- api log duration is now always in milliseconds for consistency.
|
||||||
|
- advanced index config option `fileEndsWith` is now respected.
|
||||||
|
- Added Informative error for missing files for certificate load https://github.com/gtsteffaniak/filebrowser/issues/354
|
||||||
|
|
||||||
|
**BugFixes**:
|
||||||
|
- onlyoffice close window missing files issue https://github.com/gtsteffaniak/filebrowser/issues/345
|
||||||
|
- fixed download link inside file preview
|
||||||
|
|
||||||
## v0.5.1-beta
|
## v0.5.1-beta
|
||||||
|
|
||||||
> Note: I changed the [config](https://github.com/gtsteffaniak/filebrowser/wiki/Configuration#example-auth-config) for password auth again... It was a mistake just to make it a boolean, so now you can provide options, going forward this allows for more.
|
> Note: I changed the [config](https://github.com/gtsteffaniak/filebrowser/wiki/Configuration#example-auth-config) for password auth again... It was a mistake just to make it a boolean, so now you can provide options, going forward this allows for more.
|
||||||
|
|
23
README.md
23
README.md
|
@ -1,11 +1,11 @@
|
||||||
<div align="center">
|
<div align="center">
|
||||||
|
|
||||||
[](https://goreportcard.com/report/github.com/gtsteffaniak/filebrowser/backend)
|
[](https://goreportcard.com/report/github.com/gtsteffaniak/filebrowser/backend)
|
||||||
[](https://github.com/gtsteffaniak/filebrowser/releases)
|
|
||||||
[](https://www.apache.org/licenses/LICENSE-2.0)
|
|
||||||
[](https://www.codacy.com/gh/gtsteffaniak/filebrowser/dashboard)
|
[](https://www.codacy.com/gh/gtsteffaniak/filebrowser/dashboard)
|
||||||
|
[](https://github.com/gtsteffaniak/filebrowser/releases)
|
||||||
[](https://hub.docker.com/r/gtstef/filebrowser)
|
[](https://hub.docker.com/r/gtstef/filebrowser)
|
||||||
|
[](https://www.apache.org/licenses/LICENSE-2.0)
|
||||||
|
|
||||||
<img width="150" src="https://github.com/user-attachments/assets/59986a2a-f960-4536-aa35-4a9a7c98ad48" title="Logo">
|
<img width="150" src="https://github.com/user-attachments/assets/59986a2a-f960-4536-aa35-4a9a7c98ad48" title="Logo">
|
||||||
<h3>FileBrowser Quantum</h3>
|
<h3>FileBrowser Quantum</h3>
|
||||||
A modern web-based file manager
|
A modern web-based file manager
|
||||||
|
@ -18,11 +18,11 @@
|
||||||
|
|
||||||
FileBrowser Quantum is a fork of the file browser open-source project with the following changes:
|
FileBrowser Quantum is a fork of the file browser open-source project with the following changes:
|
||||||
|
|
||||||
1. ✅ Indexes files efficiently. (See [indexing Wiki](https://github.com/gtsteffaniak/filebrowser/wiki/Indexing) for more info.)
|
1. ✅ Indexes files (See [indexing Wiki](https://github.com/gtsteffaniak/filebrowser/wiki/Indexing) for more info.)
|
||||||
- Real-time search results as you type
|
- Real-time search results as you type
|
||||||
- Search supports file/folder sizes and many file type filters.
|
- Search supports file/folder sizes and many file type filters.
|
||||||
- Enhanced interactive results that show file/folder sizes.
|
- Enhanced interactive results that show file/folder sizes.
|
||||||
2. ✅ Revamped and simplified GUI navbar and sidebar menu.
|
2. ✅ Revamped UI
|
||||||
- Additional compact view mode as well as refreshed view mode styles.
|
- Additional compact view mode as well as refreshed view mode styles.
|
||||||
- Many graphical and user experience improvements.
|
- Many graphical and user experience improvements.
|
||||||
- right-click context menu
|
- right-click context menu
|
||||||
|
@ -39,16 +39,10 @@ Notable features that this fork *does not* have (removed):
|
||||||
|
|
||||||
- ❌ jobs/runners are not supported yet (planned).
|
- ❌ jobs/runners are not supported yet (planned).
|
||||||
- ❌ per-user rules are not supported yet (planned).
|
- ❌ per-user rules are not supported yet (planned).
|
||||||
- ❌ pagination for directory items for extremely large directories.
|
|
||||||
- ❌ shell commands are completely removed and will not be returned.
|
- ❌ shell commands are completely removed and will not be returned.
|
||||||
- see feature matrix below for more.
|
|
||||||
|
|
||||||
## About
|
## About
|
||||||
|
|
||||||
FileBrowser Quantum provides a file-managing interface within a specified directory
|
|
||||||
and can be used to upload, delete, preview, rename, and edit your files.
|
|
||||||
It allows the creation of multiple users and each user can have its directory.
|
|
||||||
|
|
||||||
This repository is a fork of the original [filebrowser](https://github.com/filebrowser/filebrowser)
|
This repository is a fork of the original [filebrowser](https://github.com/filebrowser/filebrowser)
|
||||||
with a collection of changes that make this program work better in terms of
|
with a collection of changes that make this program work better in terms of
|
||||||
aesthetics and performance. Improved search, simplified UI
|
aesthetics and performance. Improved search, simplified UI
|
||||||
|
@ -103,7 +97,7 @@ Configuration is done via the `config.yaml`, see the [Configuration Wiki](https:
|
||||||
|
|
||||||
## Office File Support
|
## Office File Support
|
||||||
|
|
||||||
See [Office Support Wiki](https://github.com/gtsteffaniak/filebrowser/wiki/Office-Support#adding-open-office-integration-for-docker) on how to enable office file editing.
|
See [Office Support Wiki](https://github.com/gtsteffaniak/filebrowser/wiki/Office-Support#adding-open-office-integration-for-docker) on how to enable office file editing and office related features.
|
||||||
|
|
||||||
## Migration from the original filebrowser
|
## Migration from the original filebrowser
|
||||||
|
|
||||||
|
@ -111,7 +105,7 @@ See the [Migration Wiki](https://github.com/gtsteffaniak/filebrowser/wiki/Migrat
|
||||||
|
|
||||||
## Comparison Chart
|
## Comparison Chart
|
||||||
|
|
||||||
Application Name | <img width="48" src="frontend/public/img/icons/favicon-256x256.png" > Quantum | <img width="48" src="https://github.com/filebrowser/filebrowser/blob/master/frontend/public/img/logo.svg" > Filebrowser | <img width="48" src="https://github.com/mickael-kerjean/filestash/blob/master/public/assets/logo/app_icon.png?raw=true" > Filestash | <img width="48" src="https://avatars.githubusercontent.com/u/19211038?s=200&v=4" > Nextcloud | <img width="48" src="https://upload.wikimedia.org/wikipedia/commons/thumb/d/da/Google_Drive_logo.png/480px-Google_Drive_logo.png" > Google_Drive | <img width="48" src="https://avatars.githubusercontent.com/u/6422152?v=4" > FileRun
|
Application Name | <img width="48" src="https://github.com/user-attachments/assets/59986a2a-f960-4536-aa35-4a9a7c98ad48" > Quantum | <img width="48" src="https://github.com/filebrowser/filebrowser/blob/master/frontend/public/img/logo.svg" > Filebrowser | <img width="48" src="https://github.com/mickael-kerjean/filestash/blob/master/public/assets/logo/app_icon.png?raw=true" > Filestash | <img width="48" src="https://avatars.githubusercontent.com/u/19211038?s=200&v=4" > Nextcloud | <img width="48" src="https://upload.wikimedia.org/wikipedia/commons/thumb/d/da/Google_Drive_logo.png/480px-Google_Drive_logo.png" > Google_Drive | <img width="48" src="https://avatars.githubusercontent.com/u/6422152?v=4" > FileRun
|
||||||
--- | --- | --- | --- | --- | --- | --- |
|
--- | --- | --- | --- | --- | --- | --- |
|
||||||
Filesystem support | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ |
|
Filesystem support | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ |
|
||||||
Linux | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ |
|
Linux | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ |
|
||||||
|
@ -156,8 +150,7 @@ activity log | ❌ | ❌ | ❌ | ✅ | ✅ | ✅ |
|
||||||
Comments support | ❌ | ❌ | ❌ | ✅ | ✅ | ✅ |
|
Comments support | ❌ | ❌ | ❌ | ✅ | ✅ | ✅ |
|
||||||
trash support | ❌ | ❌ | ❌ | ✅ | ✅ | ✅ |
|
trash support | ❌ | ❌ | ❌ | ✅ | ✅ | ✅ |
|
||||||
Starred/pinned files | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ |
|
Starred/pinned files | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ |
|
||||||
Content preview icons | ✅ | ✅ | ❌ | ❌ | ✅ | ✅ |
|
|
||||||
Chromecast support | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ |
|
Chromecast support | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ |
|
||||||
Share collections of files | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ |
|
Share collections of files | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ |
|
||||||
Can archive selected files | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ |
|
Can archive selected files | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ |
|
||||||
Can browse archive files | ❌ | ❌ | ❌ | ❌ | ❌ | ✅
|
Can browse archive files | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ |
|
||||||
|
|
|
@ -341,6 +341,10 @@ func (i *ItemInfo) DetectType(realPath string, saveContent bool) {
|
||||||
ext := filepath.Ext(name)
|
ext := filepath.Ext(name)
|
||||||
|
|
||||||
// Attempt MIME detection by file extension
|
// Attempt MIME detection by file extension
|
||||||
|
if ext == ".md" {
|
||||||
|
i.Type = "text/markdown"
|
||||||
|
return
|
||||||
|
}
|
||||||
i.Type = strings.Split(mime.TypeByExtension(ext), ";")[0]
|
i.Type = strings.Split(mime.TypeByExtension(ext), ";")[0]
|
||||||
if i.Type == "" {
|
if i.Type == "" {
|
||||||
i.Type = extendedMimeTypeCheck(ext)
|
i.Type = extendedMimeTypeCheck(ext)
|
||||||
|
|
|
@ -311,6 +311,19 @@ func (idx *Index) shouldSkip(isDir bool, isHidden bool, fullCombined string) boo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !isDir && len(idx.Source.Config.Include.FileEndsWith) > 0 {
|
||||||
|
shouldSkip := true
|
||||||
|
for _, end := range idx.Source.Config.Include.FileEndsWith {
|
||||||
|
if strings.HasSuffix(fullCombined, end) {
|
||||||
|
shouldSkip = false
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if shouldSkip {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// check exclusions
|
// check exclusions
|
||||||
if isDir && slices.Contains(idx.Source.Config.Exclude.Folders, fullCombined) {
|
if isDir && slices.Contains(idx.Source.Config.Exclude.Folders, fullCombined) {
|
||||||
return true
|
return true
|
||||||
|
@ -321,5 +334,17 @@ func (idx *Index) shouldSkip(isDir bool, isHidden bool, fullCombined string) boo
|
||||||
if idx.Source.Config.IgnoreHidden && isHidden {
|
if idx.Source.Config.IgnoreHidden && isHidden {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !isDir && len(idx.Source.Config.Exclude.FileEndsWith) > 0 {
|
||||||
|
shouldSkip := false
|
||||||
|
for _, end := range idx.Source.Config.Exclude.FileEndsWith {
|
||||||
|
if strings.HasSuffix(fullCombined, end) {
|
||||||
|
shouldSkip = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return shouldSkip
|
||||||
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,24 +1,26 @@
|
||||||
module github.com/gtsteffaniak/filebrowser/backend
|
module github.com/gtsteffaniak/filebrowser/backend
|
||||||
|
|
||||||
go 1.22.5
|
go 1.23
|
||||||
|
|
||||||
|
toolchain go1.23.1
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/asdine/storm/v3 v3.2.1
|
github.com/asdine/storm/v3 v3.2.1
|
||||||
github.com/disintegration/imaging v1.6.2
|
github.com/disintegration/imaging v1.6.2
|
||||||
github.com/dsoprea/go-exif/v3 v3.0.1
|
github.com/dsoprea/go-exif/v3 v3.0.1
|
||||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568
|
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568
|
||||||
github.com/goccy/go-yaml v1.15.15
|
github.com/goccy/go-yaml v1.15.17
|
||||||
github.com/golang-jwt/jwt/v4 v4.5.1
|
github.com/golang-jwt/jwt/v4 v4.5.1
|
||||||
github.com/google/go-cmp v0.6.0
|
github.com/google/go-cmp v0.6.0
|
||||||
github.com/shirou/gopsutil/v3 v3.24.5
|
github.com/shirou/gopsutil/v3 v3.24.5
|
||||||
github.com/spf13/afero v1.11.0
|
github.com/spf13/afero v1.11.0
|
||||||
github.com/stretchr/testify v1.9.0
|
github.com/stretchr/testify v1.10.0
|
||||||
github.com/swaggo/http-swagger v1.3.4
|
github.com/swaggo/http-swagger v1.3.4
|
||||||
github.com/swaggo/swag v1.16.4
|
github.com/swaggo/swag v1.16.4
|
||||||
golang.org/x/crypto v0.32.0
|
golang.org/x/crypto v0.33.0
|
||||||
golang.org/x/image v0.23.0
|
golang.org/x/image v0.24.0
|
||||||
golang.org/x/sys v0.29.0
|
golang.org/x/sys v0.30.0
|
||||||
golang.org/x/text v0.21.0
|
golang.org/x/text v0.22.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
@ -40,7 +42,7 @@ require (
|
||||||
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect
|
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect
|
||||||
github.com/swaggo/files v1.0.1 // indirect
|
github.com/swaggo/files v1.0.1 // indirect
|
||||||
github.com/yusufpapurcu/wmi v1.2.4 // indirect
|
github.com/yusufpapurcu/wmi v1.2.4 // indirect
|
||||||
go.etcd.io/bbolt v1.3.11 // indirect
|
go.etcd.io/bbolt v1.4.0 // indirect
|
||||||
golang.org/x/net v0.34.0 // indirect
|
golang.org/x/net v0.34.0 // indirect
|
||||||
golang.org/x/tools v0.29.0 // indirect
|
golang.org/x/tools v0.29.0 // indirect
|
||||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||||
|
|
|
@ -46,8 +46,8 @@ github.com/go-openapi/spec v0.21.0 h1:LTVzPc3p/RzRnkQqLRndbAzjY0d0BCL72A6j3CdL9Z
|
||||||
github.com/go-openapi/spec v0.21.0/go.mod h1:78u6VdPw81XU44qEWGhtr982gJ5BWg2c0I5XwVMotYk=
|
github.com/go-openapi/spec v0.21.0/go.mod h1:78u6VdPw81XU44qEWGhtr982gJ5BWg2c0I5XwVMotYk=
|
||||||
github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE=
|
github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE=
|
||||||
github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=
|
github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=
|
||||||
github.com/goccy/go-yaml v1.15.15 h1:5turdzAlutS2Q7/QR/9R99Z1K0J00qDb4T0pHJcZ5ew=
|
github.com/goccy/go-yaml v1.15.17 h1:dK4FbbTTEOZTLH/NW3/xBqg0JdC14YKVmYwS9GT3H60=
|
||||||
github.com/goccy/go-yaml v1.15.15/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=
|
github.com/goccy/go-yaml v1.15.17/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=
|
||||||
github.com/golang-jwt/jwt/v4 v4.5.1 h1:JdqV9zKUdtaa9gdPlywC3aeoEsR681PlKC+4F5gQgeo=
|
github.com/golang-jwt/jwt/v4 v4.5.1 h1:JdqV9zKUdtaa9gdPlywC3aeoEsR681PlKC+4F5gQgeo=
|
||||||
github.com/golang-jwt/jwt/v4 v4.5.1/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
github.com/golang-jwt/jwt/v4 v4.5.1/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
||||||
github.com/golang/geo v0.0.0-20190916061304-5b978397cfec/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI=
|
github.com/golang/geo v0.0.0-20190916061304-5b978397cfec/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI=
|
||||||
|
@ -88,8 +88,8 @@ github.com/shirou/gopsutil/v3 v3.24.5/go.mod h1:bsoOS1aStSs9ErQ1WWfxllSeS1K5D+U3
|
||||||
github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8=
|
github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8=
|
||||||
github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY=
|
github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY=
|
||||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||||
github.com/swaggo/files v1.0.1 h1:J1bVJ4XHZNq0I46UU90611i9/YzdrF7x92oX1ig5IdE=
|
github.com/swaggo/files v1.0.1 h1:J1bVJ4XHZNq0I46UU90611i9/YzdrF7x92oX1ig5IdE=
|
||||||
github.com/swaggo/files v1.0.1/go.mod h1:0qXmMNH6sXNf+73t65aKeB+ApmgxdnkQzVTAj2uaMUg=
|
github.com/swaggo/files v1.0.1/go.mod h1:0qXmMNH6sXNf+73t65aKeB+ApmgxdnkQzVTAj2uaMUg=
|
||||||
github.com/swaggo/http-swagger v1.3.4 h1:q7t/XLx0n15H1Q9/tk3Y9L4n210XzJF5WtnDX64a5ww=
|
github.com/swaggo/http-swagger v1.3.4 h1:q7t/XLx0n15H1Q9/tk3Y9L4n210XzJF5WtnDX64a5ww=
|
||||||
|
@ -102,15 +102,15 @@ github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5t
|
||||||
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
|
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
|
||||||
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
||||||
go.etcd.io/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
|
go.etcd.io/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
|
||||||
go.etcd.io/bbolt v1.3.11 h1:yGEzV1wPz2yVCLsD8ZAiGHhHVlczyC9d1rP43/VCRJ0=
|
go.etcd.io/bbolt v1.4.0 h1:TU77id3TnN/zKr7CO/uk+fBCwF2jGcMuw2B/FMAzYIk=
|
||||||
go.etcd.io/bbolt v1.3.11/go.mod h1:dksAq7YMXoljX0xu6VF5DMZGbhYYoLUalEiSySYAS4I=
|
go.etcd.io/bbolt v1.4.0/go.mod h1:AsD+OCi/qPN1giOX1aiLAha3o1U8rAz65bvN4j0sRuk=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc=
|
golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus=
|
||||||
golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc=
|
golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M=
|
||||||
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||||
golang.org/x/image v0.23.0 h1:HseQ7c2OpPKTPVzNjG5fwJsOTCiiwS4QdsYi5XU6H68=
|
golang.org/x/image v0.24.0 h1:AN7zRgVsbvmTfNyqIbbOraYL8mSwcKncEj8ofjgzcMQ=
|
||||||
golang.org/x/image v0.23.0/go.mod h1:wJJBTdLfCCf3tiHa1fNxpZmUI4mmoZvwMCPP0ddoNKY=
|
golang.org/x/image v0.24.0/go.mod h1:4b/ITuLfqYq1hqZcjofwctIhi7sZh2WaCjvsBNjjya8=
|
||||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||||
golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4=
|
golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4=
|
||||||
golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
|
golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
|
||||||
|
@ -129,8 +129,8 @@ golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=
|
||||||
golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
|
golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
|
golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
|
||||||
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
@ -145,8 +145,8 @@ golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||||
golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
|
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
|
||||||
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||||
|
@ -155,8 +155,8 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||||
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
|
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
|
||||||
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||||
|
|
|
@ -321,13 +321,14 @@ func LoggingMiddleware(next http.Handler) http.Handler {
|
||||||
if len(truncUser) > 12 {
|
if len(truncUser) > 12 {
|
||||||
truncUser = truncUser[:10] + ".."
|
truncUser = truncUser[:10] + ".."
|
||||||
}
|
}
|
||||||
|
duration := time.Since(start)
|
||||||
logger.Api(
|
logger.Api(
|
||||||
fmt.Sprintf("%-7s | %3d | %-15s | %-12s | %-12s | \"%s\"",
|
fmt.Sprintf("%-7s | %3d | %-15s | %-12s | %-12s | \"%s\"",
|
||||||
r.Method,
|
r.Method,
|
||||||
wrappedWriter.StatusCode, // Captured status code
|
wrappedWriter.StatusCode, // Captured status code
|
||||||
r.RemoteAddr,
|
r.RemoteAddr,
|
||||||
truncUser,
|
truncUser,
|
||||||
time.Since(start).String(),
|
fmt.Sprintf("%vms", duration.Milliseconds()),
|
||||||
fullURL), wrappedWriter.StatusCode)
|
fullURL), wrappedWriter.StatusCode)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,6 +63,7 @@ func rawHandler(w http.ResponseWriter, r *http.Request, d *requestContext) (int,
|
||||||
}
|
}
|
||||||
return rawFilesHandler(w, r, d, fileList)
|
return rawFilesHandler(w, r, d, fileList)
|
||||||
}
|
}
|
||||||
|
|
||||||
func addFile(path string, d *requestContext, tarWriter *tar.Writer, zipWriter *zip.Writer, flatten bool) error {
|
func addFile(path string, d *requestContext, tarWriter *tar.Writer, zipWriter *zip.Writer, flatten bool) error {
|
||||||
idx := files.GetIndex("default")
|
idx := files.GetIndex("default")
|
||||||
realPath, _, _ := idx.GetRealPath(d.user.Scope, path)
|
realPath, _, _ := idx.GetRealPath(d.user.Scope, path)
|
||||||
|
|
|
@ -156,10 +156,11 @@ type UserDefaults struct {
|
||||||
By string `json:"by"`
|
By string `json:"by"`
|
||||||
Asc bool `json:"asc"`
|
Asc bool `json:"asc"`
|
||||||
} `json:"sorting"`
|
} `json:"sorting"`
|
||||||
Perm users.Permissions `json:"perm"`
|
Perm users.Permissions `json:"perm"`
|
||||||
Permissions users.Permissions `json:"permissions"`
|
Permissions users.Permissions `json:"permissions"`
|
||||||
Commands []string `json:"commands,omitempty"`
|
Commands []string `json:"commands,omitempty"`
|
||||||
ShowHidden bool `json:"showHidden"`
|
ShowHidden bool `json:"showHidden"`
|
||||||
DateFormat bool `json:"dateFormat"`
|
DateFormat bool `json:"dateFormat"`
|
||||||
ThemeColor string `json:"themeColor"`
|
ThemeColor string `json:"themeColor"`
|
||||||
|
QuickDownload bool `json:"quickDownload"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -1382,6 +1382,9 @@ const docTemplate = `{
|
||||||
"permissions": {
|
"permissions": {
|
||||||
"$ref": "#/definitions/users.Permissions"
|
"$ref": "#/definitions/users.Permissions"
|
||||||
},
|
},
|
||||||
|
"quickDownload": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
"rules": {
|
"rules": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
|
@ -1593,6 +1596,9 @@ const docTemplate = `{
|
||||||
"perm": {
|
"perm": {
|
||||||
"$ref": "#/definitions/users.Permissions"
|
"$ref": "#/definitions/users.Permissions"
|
||||||
},
|
},
|
||||||
|
"quickDownload": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
"rules": {
|
"rules": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
|
|
|
@ -1371,6 +1371,9 @@
|
||||||
"permissions": {
|
"permissions": {
|
||||||
"$ref": "#/definitions/users.Permissions"
|
"$ref": "#/definitions/users.Permissions"
|
||||||
},
|
},
|
||||||
|
"quickDownload": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
"rules": {
|
"rules": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
|
@ -1582,6 +1585,9 @@
|
||||||
"perm": {
|
"perm": {
|
||||||
"$ref": "#/definitions/users.Permissions"
|
"$ref": "#/definitions/users.Permissions"
|
||||||
},
|
},
|
||||||
|
"quickDownload": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
"rules": {
|
"rules": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
|
|
|
@ -144,6 +144,8 @@ definitions:
|
||||||
$ref: '#/definitions/users.Permissions'
|
$ref: '#/definitions/users.Permissions'
|
||||||
permissions:
|
permissions:
|
||||||
$ref: '#/definitions/users.Permissions'
|
$ref: '#/definitions/users.Permissions'
|
||||||
|
quickDownload:
|
||||||
|
type: boolean
|
||||||
rules:
|
rules:
|
||||||
items:
|
items:
|
||||||
$ref: '#/definitions/users.Rule'
|
$ref: '#/definitions/users.Rule'
|
||||||
|
@ -285,6 +287,8 @@ definitions:
|
||||||
type: string
|
type: string
|
||||||
perm:
|
perm:
|
||||||
$ref: '#/definitions/users.Permissions'
|
$ref: '#/definitions/users.Permissions'
|
||||||
|
quickDownload:
|
||||||
|
type: boolean
|
||||||
rules:
|
rules:
|
||||||
items:
|
items:
|
||||||
$ref: '#/definitions/users.Rule'
|
$ref: '#/definitions/users.Rule'
|
||||||
|
|
|
@ -56,6 +56,7 @@ type User struct {
|
||||||
DateFormat bool `json:"dateFormat"`
|
DateFormat bool `json:"dateFormat"`
|
||||||
GallerySize int `json:"gallerySize"`
|
GallerySize int `json:"gallerySize"`
|
||||||
ThemeColor string `json:"themeColor"`
|
ThemeColor string `json:"themeColor"`
|
||||||
|
QuickDownload bool `json:"quickDownload"`
|
||||||
}
|
}
|
||||||
|
|
||||||
var PublicUser = User{
|
var PublicUser = User{
|
||||||
|
|
|
@ -24,7 +24,9 @@
|
||||||
"ace-builds": "^1.24.2",
|
"ace-builds": "^1.24.2",
|
||||||
"clipboard": "^2.0.4",
|
"clipboard": "^2.0.4",
|
||||||
"css-vars-ponyfill": "^2.4.3",
|
"css-vars-ponyfill": "^2.4.3",
|
||||||
|
"dompurify": "^3.2.4",
|
||||||
"file-loader": "^6.2.0",
|
"file-loader": "^6.2.0",
|
||||||
|
"marked": "^15.0.6",
|
||||||
"normalize.css": "^8.0.1",
|
"normalize.css": "^8.0.1",
|
||||||
"qrcode.vue": "^3.4.1",
|
"qrcode.vue": "^3.4.1",
|
||||||
"vue": "^3.4.21",
|
"vue": "^3.4.21",
|
||||||
|
@ -33,8 +35,8 @@
|
||||||
"vue-router": "^4.3.0"
|
"vue-router": "^4.3.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@playwright/test": "^1.49.1",
|
|
||||||
"@intlify/unplugin-vue-i18n": "^4.0.0",
|
"@intlify/unplugin-vue-i18n": "^4.0.0",
|
||||||
|
"@playwright/test": "^1.49.1",
|
||||||
"@vitejs/plugin-vue": "^5.0.4",
|
"@vitejs/plugin-vue": "^5.0.4",
|
||||||
"@vue/eslint-config-typescript": "^13.0.0",
|
"@vue/eslint-config-typescript": "^13.0.0",
|
||||||
"eslint": "^8.57.0",
|
"eslint": "^8.57.0",
|
||||||
|
|
|
@ -140,4 +140,9 @@ export default {
|
||||||
.yellow-icons {
|
.yellow-icons {
|
||||||
color: yellow;
|
color: yellow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.simple-icons {
|
||||||
|
color: white;
|
||||||
|
font-size: 1.5em !important;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
@mouseup="cancelContext($event)"
|
@mouseup="cancelContext($event)"
|
||||||
>
|
>
|
||||||
<div @click="toggleClick" :class="{ activetitle: isMaximized && isSelected }">
|
<div @click="toggleClick" :class="{ activetitle: isMaximized && isSelected }">
|
||||||
|
|
||||||
<img
|
<img
|
||||||
v-if="
|
v-if="
|
||||||
readOnly === undefined &&
|
readOnly === undefined &&
|
||||||
|
@ -41,12 +42,14 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="text" :class="{ activecontent: isMaximized && isSelected }">
|
<div class="text" :class="{ activecontent: isMaximized && isSelected }">
|
||||||
<p class="name">{{ name }}</p>
|
<p :class="{'adjustment':quickDownloadEnabled}" class="name">{{ name }}</p>
|
||||||
<p class="size" :data-order="humanSize()">{{ humanSize() }}</p>
|
<p class="size" :class="{'adjustment':quickDownloadEnabled}" :data-order="humanSize()">{{ humanSize() }}</p>
|
||||||
<p class="modified">
|
<p class="modified">
|
||||||
<time :datetime="modified">{{ getTime() }}</time>
|
<time :datetime="modified">{{ getTime() }}</time>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
<Icon @click="downloadFile" v-if="quickDownloadEnabled" mimetype="file_download" style="padding-right: 0.5em" />
|
||||||
|
|
||||||
</a>
|
</a>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -77,6 +80,8 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { enableThumbs } from "@/utils/constants";
|
import { enableThumbs } from "@/utils/constants";
|
||||||
|
import downloadFiles from "@/utils/download";
|
||||||
|
|
||||||
import { getHumanReadableFilesize } from "@/utils/filesizes";
|
import { getHumanReadableFilesize } from "@/utils/filesizes";
|
||||||
import { fromNow } from "@/utils/moment";
|
import { fromNow } from "@/utils/moment";
|
||||||
import { filesApi } from "@/api";
|
import { filesApi } from "@/api";
|
||||||
|
@ -116,6 +121,9 @@ export default {
|
||||||
"hidden"
|
"hidden"
|
||||||
],
|
],
|
||||||
computed: {
|
computed: {
|
||||||
|
quickDownloadEnabled() {
|
||||||
|
return state.user?.quickDownload;
|
||||||
|
},
|
||||||
isHiddenNotSelected() {
|
isHiddenNotSelected() {
|
||||||
return !this.isSelected && this.hidden
|
return !this.isSelected && this.hidden
|
||||||
},
|
},
|
||||||
|
@ -145,13 +153,11 @@ export default {
|
||||||
},
|
},
|
||||||
canDrop() {
|
canDrop() {
|
||||||
if (!this.isDir || this.readOnly !== undefined) return false;
|
if (!this.isDir || this.readOnly !== undefined) return false;
|
||||||
|
|
||||||
for (let i of this.selected) {
|
for (let i of this.selected) {
|
||||||
if (state.req.items[i].url === this.url) {
|
if (state.req.items[i].url === this.url) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
thumbnailUrl() {
|
thumbnailUrl() {
|
||||||
|
@ -183,6 +189,12 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
downloadFile(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
mutations.resetSelected();
|
||||||
|
mutations.addSelected(this.index);
|
||||||
|
downloadFiles()
|
||||||
|
},
|
||||||
handleTouchMove(event) {
|
handleTouchMove(event) {
|
||||||
if (!state.isSafari) return;
|
if (!state.isSafari) return;
|
||||||
const touch = event.touches[0];
|
const touch = event.touches[0];
|
||||||
|
@ -424,6 +436,9 @@ export default {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
.icon-download {
|
||||||
|
font-size: 0.5em;
|
||||||
|
}
|
||||||
.item {
|
.item {
|
||||||
-webkit-touch-callout: none; /* Disable the default long press preview */
|
-webkit-touch-callout: none; /* Disable the default long press preview */
|
||||||
}
|
}
|
||||||
|
@ -431,4 +446,5 @@ export default {
|
||||||
.hiddenFile {
|
.hiddenFile {
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<h2>{{ $t("buttons.share") }}</h2>
|
<h2>{{ $t("buttons.share") }}</h2>
|
||||||
</div>
|
</div>
|
||||||
<div class="searchContext">Path: {{ subpath }}</div>
|
<div class="searchContext">Path: {{ subpath }}</div>
|
||||||
|
<p>Note: anyone who has access to the link (and optional password) can access the shared files. There is no need to be logged in.</p>
|
||||||
<template v-if="listing">
|
<template v-if="listing">
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<table>
|
<table>
|
||||||
|
|
|
@ -113,6 +113,7 @@ main > div {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
color: #6f6f6f;
|
color: #6f6f6f;
|
||||||
|
padding-left: 0.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.breadcrumbs span,
|
.breadcrumbs span,
|
||||||
|
|
|
@ -230,12 +230,23 @@ body.rtl #listingView {
|
||||||
width: 25%;
|
width: 25%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#listingView.list .item .size.adjustment,
|
||||||
|
#listingView.compact .item .size.adjustment {
|
||||||
|
width: calc(25% + 1em) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#listingView .header .name,
|
#listingView .header .name,
|
||||||
#listingView.list .item .name,
|
#listingView.list .item .name,
|
||||||
#listingView.compact .item .name {
|
#listingView.compact .item .name {
|
||||||
width: 50%;
|
width: 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#listingView.list .item .name.adjustment,
|
||||||
|
#listingView.compact .item .name.adjustment {
|
||||||
|
width: calc(50% + 1em) !important;
|
||||||
|
}
|
||||||
|
|
||||||
#listingView.normal .item .text {
|
#listingView.normal .item .text {
|
||||||
padding-left: 0.3em;
|
padding-left: 0.3em;
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,7 +103,11 @@ export const getters = {
|
||||||
if (typeof getters.currentPromptName() === "string" && !getters.isStickySidebar()) {
|
if (typeof getters.currentPromptName() === "string" && !getters.isStickySidebar()) {
|
||||||
visible = false;
|
visible = false;
|
||||||
}
|
}
|
||||||
if (getters.currentView() == "editor" || getters.currentView() == "preview" || getters.currentView() == "onlyOfficeEditor") {
|
if (
|
||||||
|
getters.currentView() == "editor" ||
|
||||||
|
getters.currentView() == "preview" ||
|
||||||
|
getters.currentView() == "onlyOfficeEditor"
|
||||||
|
) {
|
||||||
visible = false;
|
visible = false;
|
||||||
}
|
}
|
||||||
return visible
|
return visible
|
||||||
|
@ -144,6 +148,8 @@ export const getters = {
|
||||||
return "listingView";
|
return "listingView";
|
||||||
} else if (state.req?.onlyOfficeId) {
|
} else if (state.req?.onlyOfficeId) {
|
||||||
return "onlyOfficeEditor";
|
return "onlyOfficeEditor";
|
||||||
|
} else if ("content" in state.req && state.req.type == "text/markdown" && window.location.hash != "#edit") {
|
||||||
|
return "markdownViewer";
|
||||||
} else if ("content" in state.req) {
|
} else if ("content" in state.req) {
|
||||||
return "editor";
|
return "editor";
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -14,6 +14,7 @@ export const state = reactive({
|
||||||
},
|
},
|
||||||
editor: null,
|
editor: null,
|
||||||
user: {
|
user: {
|
||||||
|
quickDownloadEnabled: false,
|
||||||
gallarySize: 0,
|
gallarySize: 0,
|
||||||
singleClick: false,
|
singleClick: false,
|
||||||
stickySidebar: stickyStartup(),
|
stickySidebar: stickyStartup(),
|
||||||
|
|
|
@ -38,6 +38,14 @@ export function getTypeInfo(mimeType) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mimeType == "file_download") {
|
||||||
|
return {
|
||||||
|
classes: "material-icons simple-icons",
|
||||||
|
materialIcon: "file_download",
|
||||||
|
simpleType: "file_download",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
if (mimeType.startsWith("font/")) {
|
if (mimeType.startsWith("font/")) {
|
||||||
return {
|
return {
|
||||||
classes: "gray-icons material-icons",
|
classes: "gray-icons material-icons",
|
||||||
|
|
|
@ -24,6 +24,7 @@ import Preview from "@/views/files/Preview.vue";
|
||||||
import ListingView from "@/views/files/ListingView.vue";
|
import ListingView from "@/views/files/ListingView.vue";
|
||||||
import Editor from "@/views/files/Editor.vue";
|
import Editor from "@/views/files/Editor.vue";
|
||||||
import OnlyOfficeEditor from "./files/OnlyOfficeEditor.vue";
|
import OnlyOfficeEditor from "./files/OnlyOfficeEditor.vue";
|
||||||
|
import MarkdownViewer from "./files/MarkdownViewer.vue";
|
||||||
import { state, mutations, getters } from "@/store";
|
import { state, mutations, getters } from "@/store";
|
||||||
import { url } from "@/utils";
|
import { url } from "@/utils";
|
||||||
import { notify } from "@/notify";
|
import { notify } from "@/notify";
|
||||||
|
@ -38,6 +39,7 @@ export default {
|
||||||
ListingView,
|
ListingView,
|
||||||
Editor,
|
Editor,
|
||||||
OnlyOfficeEditor,
|
OnlyOfficeEditor,
|
||||||
|
MarkdownViewer,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -149,7 +149,7 @@ main {
|
||||||
}
|
}
|
||||||
|
|
||||||
main.moveWithSidebar {
|
main.moveWithSidebar {
|
||||||
padding-left: 20.5em;
|
padding-left: 20em;
|
||||||
}
|
}
|
||||||
|
|
||||||
main::-webkit-scrollbar {
|
main::-webkit-scrollbar {
|
||||||
|
|
|
@ -3,13 +3,15 @@
|
||||||
<action v-if="notShare" icon="close" :label="$t('buttons.close')" @action="close()" />
|
<action v-if="notShare" icon="close" :label="$t('buttons.close')" @action="close()" />
|
||||||
<title v-if="isSettings" class="topTitle">Settings</title>
|
<title v-if="isSettings" class="topTitle">Settings</title>
|
||||||
<title v-else class="topTitle">{{ req.name }}</title>
|
<title v-else class="topTitle">{{ req.name }}</title>
|
||||||
<action icon="hide_source" />
|
<action v-if="ismarkdownEditable" icon="edit" @action="edit()"/>
|
||||||
|
<action v-else icon="hide_source" />
|
||||||
</header>
|
</header>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import router from "@/router";
|
import router from "@/router";
|
||||||
import { getters, state, mutations } from "@/store";
|
import { getters, state, mutations } from "@/store";
|
||||||
|
import { removeLastDir } from "@/utils/url";
|
||||||
import Action from "@/components/Action.vue";
|
import Action from "@/components/Action.vue";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -18,6 +20,9 @@ export default {
|
||||||
Action,
|
Action,
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
ismarkdownEditable() {
|
||||||
|
return state.req.type == "text/markdown" && state.user.perm.modify;
|
||||||
|
},
|
||||||
notShare() {
|
notShare() {
|
||||||
return getters.currentView() != "share";
|
return getters.currentView() != "share";
|
||||||
},
|
},
|
||||||
|
@ -29,6 +34,9 @@ export default {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
async edit() {
|
||||||
|
window.location.hash = "#edit";
|
||||||
|
},
|
||||||
close() {
|
close() {
|
||||||
mutations.closeHovers();
|
mutations.closeHovers();
|
||||||
|
|
||||||
|
@ -38,6 +46,12 @@ export default {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (getters.currentView() === "onlyOfficeEditor") {
|
||||||
|
const current = window.location.pathname
|
||||||
|
const newpath = removeLastDir(current)
|
||||||
|
window.location = newpath + "#" + state.req.name;
|
||||||
|
return;
|
||||||
|
}
|
||||||
mutations.replaceRequest({});
|
mutations.replaceRequest({});
|
||||||
router.go(-1)
|
router.go(-1)
|
||||||
},
|
},
|
||||||
|
|
|
@ -9,10 +9,7 @@
|
||||||
:label="$t('buttons.save')"
|
:label="$t('buttons.save')"
|
||||||
@action="save()"
|
@action="save()"
|
||||||
/>
|
/>
|
||||||
<action
|
<action v-else icon="hide_source" />
|
||||||
v-else
|
|
||||||
icon="hide_source"
|
|
||||||
/>
|
|
||||||
</header>
|
</header>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -120,7 +117,6 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
close() {
|
close() {
|
||||||
mutations.replaceRequest({});
|
|
||||||
router.go(-1)
|
router.go(-1)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -36,7 +36,8 @@
|
||||||
v-else
|
v-else
|
||||||
id="listingView"
|
id="listingView"
|
||||||
ref="listingView"
|
ref="listingView"
|
||||||
:class="listingViewMode + ' file-icons'"
|
:class="{'add-padding': isStickySidebar,[listingViewMode]: true }"
|
||||||
|
class="file-icons"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div class="header" :class="{ 'dark-mode-item-header': isDarkMode }">
|
<div class="header" :class="{ 'dark-mode-item-header': isDarkMode }">
|
||||||
|
@ -177,6 +178,9 @@ export default {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
isStickySidebar() {
|
||||||
|
return getters.isStickySidebar();
|
||||||
|
},
|
||||||
lastFolderIndex() {
|
lastFolderIndex() {
|
||||||
const allItems = [...this.items.dirs, ...this.items.files];
|
const allItems = [...this.items.dirs, ...this.items.files];
|
||||||
for (let i = 0; i < allItems.length; i++) {
|
for (let i = 0; i < allItems.length; i++) {
|
||||||
|
@ -929,4 +933,9 @@ export default {
|
||||||
max-width: 100% !important;
|
max-width: 100% !important;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.add-padding {
|
||||||
|
padding-left: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
<template>
|
||||||
|
<div id="markedown-viewer" v-html="renderedContent"></div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { marked } from "marked";
|
||||||
|
import DOMPurify from 'dompurify';
|
||||||
|
import { state } from "@/store";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "markdownViewer",
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
content: "",
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
renderedContent() {
|
||||||
|
return DOMPurify.sanitize(marked(this.content));
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.content = state.req.content
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
#markedown-viewer {
|
||||||
|
margin: 1em;
|
||||||
|
padding: 1em;
|
||||||
|
background-color: var(--alt-background);
|
||||||
|
border-radius: 1em;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
c
|
|
@ -98,7 +98,7 @@ export default {
|
||||||
return this.nextLink !== "";
|
return this.nextLink !== "";
|
||||||
},
|
},
|
||||||
downloadUrl() {
|
downloadUrl() {
|
||||||
return filesApi.getDownloadURL(this.currentItem.path);
|
return filesApi.getDownloadURL(this.currentItem.url);
|
||||||
},
|
},
|
||||||
raw() {
|
raw() {
|
||||||
if (this.currentItem.url == "" || this.currentItem.url == undefined) {
|
if (this.currentItem.url == "" || this.currentItem.url == undefined) {
|
||||||
|
|
|
@ -12,7 +12,11 @@
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<input type="checkbox" v-model="showHidden" />
|
<input type="checkbox" v-model="showHidden" />
|
||||||
show hidden files
|
Show hidden files
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<input type="checkbox" v-model="quickDownload" />
|
||||||
|
Always show download icon for quick access
|
||||||
</p>
|
</p>
|
||||||
<h3>Theme Color</h3>
|
<h3>Theme Color</h3>
|
||||||
<ButtonGroup :buttons="colorChoices" @button-clicked="setColor" :initialActive="color" />
|
<ButtonGroup :buttons="colorChoices" @button-clicked="setColor" :initialActive="color" />
|
||||||
|
@ -45,6 +49,7 @@ export default {
|
||||||
locale: "",
|
locale: "",
|
||||||
color: "",
|
color: "",
|
||||||
showHidden: false,
|
showHidden: false,
|
||||||
|
quickDownload: false,
|
||||||
colorChoices: [
|
colorChoices: [
|
||||||
{ label: "blue", value: "var(--blue)" },
|
{ label: "blue", value: "var(--blue)" },
|
||||||
{ label: "red", value: "var(--red)" },
|
{ label: "red", value: "var(--red)" },
|
||||||
|
@ -61,6 +66,11 @@ export default {
|
||||||
this.updateSettings(); // Only run if initialized
|
this.updateSettings(); // Only run if initialized
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
quickDownload: function () {
|
||||||
|
if (this.initialized) {
|
||||||
|
this.updateSettings(); // Only run if initialized
|
||||||
|
}
|
||||||
|
},
|
||||||
dateFormat: function () {
|
dateFormat: function () {
|
||||||
if (this.initialized) {
|
if (this.initialized) {
|
||||||
this.updateSettings(); // Only run if initialized
|
this.updateSettings(); // Only run if initialized
|
||||||
|
@ -83,6 +93,7 @@ export default {
|
||||||
this.showHidden = state.user.showHidden;
|
this.showHidden = state.user.showHidden;
|
||||||
this.dateFormat = state.user.dateFormat;
|
this.dateFormat = state.user.dateFormat;
|
||||||
this.color = state.user.themeColor;
|
this.color = state.user.themeColor;
|
||||||
|
this.quickDownload = state.user?.quickDownload;
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.initialized = true;
|
this.initialized = true;
|
||||||
|
@ -106,6 +117,7 @@ export default {
|
||||||
showHidden: this.showHidden,
|
showHidden: this.showHidden,
|
||||||
dateFormat: this.dateFormat,
|
dateFormat: this.dateFormat,
|
||||||
themeColor: this.color,
|
themeColor: this.color,
|
||||||
|
quickDownload: this.quickDownload,
|
||||||
};
|
};
|
||||||
const shouldReload =
|
const shouldReload =
|
||||||
rtlLanguages.includes(data.locale) !== rtlLanguages.includes(i18n.locale);
|
rtlLanguages.includes(data.locale) !== rtlLanguages.includes(i18n.locale);
|
||||||
|
@ -113,6 +125,8 @@ export default {
|
||||||
"locale",
|
"locale",
|
||||||
"showHidden",
|
"showHidden",
|
||||||
"dateFormat",
|
"dateFormat",
|
||||||
|
"themeColor",
|
||||||
|
"quickDownload",
|
||||||
]);
|
]);
|
||||||
mutations.updateCurrentUser(data);
|
mutations.updateCurrentUser(data);
|
||||||
if (shouldReload) {
|
if (shouldReload) {
|
||||||
|
|
Loading…
Reference in New Issue