Beta/v0.5.2 release (#356)

This commit is contained in:
Graham Steffaniak 2025-02-07 19:12:11 -05:00 committed by GitHub
parent 545a831c66
commit c84a3b0d41
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
30 changed files with 244 additions and 63 deletions

View File

@ -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.

View File

@ -1,10 +1,10 @@
<div align="center"> <div align="center">
[![Go Report Card](https://goreportcard.com/badge/github.com/gtsteffaniak/filebrowser/backend)](https://goreportcard.com/report/github.com/gtsteffaniak/filebrowser/backend) [![Go Report Card](https://goreportcard.com/badge/github.com/gtsteffaniak/filebrowser/backend)](https://goreportcard.com/report/github.com/gtsteffaniak/filebrowser/backend)
[![latest version](https://img.shields.io/github/release/gtsteffaniak/filebrowser/all.svg)](https://github.com/gtsteffaniak/filebrowser/releases)
[![Apache-2.0 License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0)
[![Codacy Badge](https://app.codacy.com/project/badge/Grade/1c48cfb7646d4009aa8c6f71287670b8)](https://www.codacy.com/gh/gtsteffaniak/filebrowser/dashboard) [![Codacy Badge](https://app.codacy.com/project/badge/Grade/1c48cfb7646d4009aa8c6f71287670b8)](https://www.codacy.com/gh/gtsteffaniak/filebrowser/dashboard)
[![latest version](https://img.shields.io/github/release/gtsteffaniak/filebrowser/all.svg)](https://github.com/gtsteffaniak/filebrowser/releases)
[![DockerHub Pulls](https://img.shields.io/docker/pulls/gtstef/filebrowser?label=latest%20Docker%20pulls)](https://hub.docker.com/r/gtstef/filebrowser) [![DockerHub Pulls](https://img.shields.io/docker/pulls/gtstef/filebrowser?label=latest%20Docker%20pulls)](https://hub.docker.com/r/gtstef/filebrowser)
[![Apache-2.0 License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](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>
@ -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 | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ |

View File

@ -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)

View File

@ -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
} }

View File

@ -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

View File

@ -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=

View File

@ -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)
}) })
} }

View File

@ -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)

View File

@ -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"`
} }

View File

@ -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": {

View File

@ -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": {

View File

@ -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'

View File

@ -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{

View File

@ -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",

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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,

View File

@ -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;
} }

View File

@ -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 {

View File

@ -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(),

View File

@ -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",

View File

@ -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 {

View File

@ -149,7 +149,7 @@ main {
} }
main.moveWithSidebar { main.moveWithSidebar {
padding-left: 20.5em; padding-left: 20em;
} }
main::-webkit-scrollbar { main::-webkit-scrollbar {

View File

@ -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)
}, },

View File

@ -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)
}, },
}, },

View File

@ -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>

View File

@ -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

View File

@ -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) {

View File

@ -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) {