Compare commits

...

13 Commits

Author SHA1 Message Date
Henrique Dias
17f1e08a58 chore(release): 2.46.1 2025-11-15 08:51:04 +01:00
Henrique Dias
ffc850454e fix: remove duplicated 'hide-defaults' flag (is 'hideDefaults') (#5548) 2025-11-15 08:50:22 +01:00
Henrique Dias
13814e1119 fix: env key replacer and remove unused function (#5547) 2025-11-15 08:40:37 +01:00
Henrique Dias
4e9e312984 chore(release): 2.46.0 2025-11-14 18:15:33 +01:00
Henrique Dias
ce3b407c51 docs: clarify status 2025-11-14 17:49:52 +01:00
transifex-integration[bot]
fb5d099f85 feat: Updates for project File Browser (#5544) 2025-11-14 17:47:21 +01:00
Omar Hussein
1ace579a55 feat: add context menu (#3343)
Co-authored-by: Henrique Dias <mail@hacdias.com>
2025-11-14 16:53:16 +01:00
Lucky Jain
ac7b49c148 feat: add option to hide the login button from public-facing pages (#3922)
Co-authored-by: Henrique Dias <mail@hacdias.com>
2025-11-14 16:21:08 +01:00
Henrique Dias
9d44932dba chore: use more standard golangci-lint options 2025-11-14 16:18:12 +01:00
Ahmad Hesam
0d973d3aad feat: add 'hide-dotfiles' as command line parameter (#3802)
Co-authored-by: Henrique Dias <mail@hacdias.com>
2025-11-14 08:19:03 +01:00
Henrique Dias
cacc0999e9 chore: let functions be longer 2025-11-14 08:11:10 +01:00
Henrique Dias
42d1b6f3ae docs: fix badge in readme 2025-11-13 18:03:51 +01:00
Henrique Dias
bb10c3dfa9 docs: clarify release 2025-11-13 17:39:51 +01:00
60 changed files with 263 additions and 197 deletions

View File

@@ -1,132 +1,9 @@
version: "2" version: "2"
linters: linters:
# inverted configuration with `default: all` and `disable` is not scalable during updates of golangci-lint default: standard
default: none
enable:
- bodyclose
- dogsled
- dupl
- errcheck
- errorlint
- exhaustive
- funlen
- gocheckcompilerdirectives
- gochecknoinits
- gocritic
- gocyclo
- godox
- goprintffuncname
- gosec
- govet
- ineffassign
- lll
- misspell
- mnd
- nakedret
- nolintlint
- prealloc
- revive
- rowserrcheck
- staticcheck
- testifylint
- unconvert
- unparam
- unused
- whitespace
settings:
dupl:
threshold: 100
exhaustive:
default-signifies-exhaustive: false
funlen:
lines: 100
statements: 50
gocritic:
disabled-checks:
- dupImport # https://github.com/go-critic/go-critic/issues/845
- ifElseChain
- octalLiteral
- whyNoLint
- wrapperFunc
enabled-tags:
- diagnostic
- experimental
- opinionated
- performance
- style
gocyclo:
min-complexity: 15
govet:
enable:
- nilness
- shadow
lll:
line-length: 140
misspell:
locale: US
mnd:
# don't include the "operation" and "assign"
checks:
- argument
- case
- condition
- return
ignored-numbers:
- "0"
- "1"
- "2"
- "3"
- "0666"
- "0700"
- "0700"
ignored-functions:
- strings.SplitN
- make
nolintlint:
allow-unused: false # report any unused nolint directives
require-explanation: false # require an explanation for nolint directives
require-specific: true # require nolint directives to be specific about which linter is being skipped
staticcheck:
checks:
- "all"
- "-QF*"
exclusions: exclusions:
generated: lax
presets: presets:
- comments
- common-false-positives
- legacy
- std-error-handling - std-error-handling
rules:
- linters:
- gochecknoinits
path: cmd/.*.go
- linters:
- dupl
- funlen
- gochecknoinits
- gocyclo
- lll
- scopelint
path: .*_test.go
- linters:
- misspell
text: "[aA]uther"
- linters:
- mnd
text: strconv.Parse
paths:
- frontend/
formatters:
enable:
- goimports
settings:
goimports:
local-prefixes:
- github.com/filebrowser/filebrowser
exclusions:
generated: lax
paths: paths:
- frontend/ - frontend/

View File

@@ -2,8 +2,28 @@
All notable changes to this project will be documented in this file. See [commit-and-tag-version](https://github.com/absolute-version/commit-and-tag-version) for commit guidelines. All notable changes to this project will be documented in this file. See [commit-and-tag-version](https://github.com/absolute-version/commit-and-tag-version) for commit guidelines.
## [2.46.1](https://github.com/filebrowser/filebrowser/compare/v2.46.0...v2.46.1) (2025-11-15)
### Bug Fixes
* env key replacer and remove unused function ([#5547](https://github.com/filebrowser/filebrowser/issues/5547)) ([13814e1](https://github.com/filebrowser/filebrowser/commit/13814e11197ebd9101940883e3ca85998f86d442))
* remove duplicated 'hide-defaults' flag (is 'hideDefaults') ([#5548](https://github.com/filebrowser/filebrowser/issues/5548)) ([ffc8504](https://github.com/filebrowser/filebrowser/commit/ffc850454e4cb8f10b970511681d6c627340afc7))
## [2.46.0](https://github.com/filebrowser/filebrowser/compare/v2.45.3...v2.46.0) (2025-11-14)
### Features
* add 'hide-dotfiles' as command line parameter ([#3802](https://github.com/filebrowser/filebrowser/issues/3802)) ([0d973d3](https://github.com/filebrowser/filebrowser/commit/0d973d3aad70ceb88950f2cd9c297fc76e7955b1))
* add context menu ([#3343](https://github.com/filebrowser/filebrowser/issues/3343)) ([1ace579](https://github.com/filebrowser/filebrowser/commit/1ace579a553486bb15af2d11f537414156606434))
* add option to hide the login button from public-facing pages ([#3922](https://github.com/filebrowser/filebrowser/issues/3922)) ([ac7b49c](https://github.com/filebrowser/filebrowser/commit/ac7b49c1484b4e27a1149310542ccd1e90659ee2))
* Updates for project File Browser ([#5544](https://github.com/filebrowser/filebrowser/issues/5544)) ([fb5d099](https://github.com/filebrowser/filebrowser/commit/fb5d099f8514516216f407be012d2e3f25de2441))
## [2.45.3](https://github.com/filebrowser/filebrowser/compare/v2.45.2...v2.45.3) (2025-11-13) ## [2.45.3](https://github.com/filebrowser/filebrowser/compare/v2.45.2...v2.45.3) (2025-11-13)
This is a test release to ensure the updated workflow works.
## [2.45.2](https://github.com/filebrowser/filebrowser/compare/v2.45.1...v2.45.2) (2025-11-13) ## [2.45.2](https://github.com/filebrowser/filebrowser/compare/v2.45.1...v2.45.2) (2025-11-13)

View File

@@ -2,7 +2,7 @@
<img src="https://raw.githubusercontent.com/filebrowser/filebrowser/master/branding/banner.png" width="550"/> <img src="https://raw.githubusercontent.com/filebrowser/filebrowser/master/branding/banner.png" width="550"/>
</p> </p>
[![Build](https://github.com/filebrowser/filebrowser/actions/workflows/main.yaml/badge.svg)](https://github.com/filebrowser/filebrowser/actions/workflows/main.yaml) [![Build](https://github.com/filebrowser/filebrowser/actions/workflows/ci.yaml/badge.svg)](https://github.com/filebrowser/filebrowser/actions/workflows/ci.yaml)
[![Go Report Card](https://goreportcard.com/badge/github.com/filebrowser/filebrowser/v2)](https://goreportcard.com/report/github.com/filebrowser/filebrowser/v2) [![Go Report Card](https://goreportcard.com/badge/github.com/filebrowser/filebrowser/v2)](https://goreportcard.com/report/github.com/filebrowser/filebrowser/v2)
[![Version](https://img.shields.io/github/release/filebrowser/filebrowser.svg)](https://github.com/filebrowser/filebrowser/releases/latest) [![Version](https://img.shields.io/github/release/filebrowser/filebrowser.svg)](https://github.com/filebrowser/filebrowser/releases/latest)
@@ -19,7 +19,7 @@ This project is a finished product which fulfills its goal: be a single binary w
- It can take a while until someone gets back to you. Please be patient. - It can take a while until someone gets back to you. Please be patient.
- [Issues](https://github.com/filebrowser/filebrowser/issues) are meant to track bugs. Unrelated issues will be converted into [discussions](https://github.com/filebrowser/filebrowser/discussions). - [Issues](https://github.com/filebrowser/filebrowser/issues) are meant to track bugs. Unrelated issues will be converted into [discussions](https://github.com/filebrowser/filebrowser/discussions).
- No new features will be implemented by maintainers. Pull requests for new features will be reviewed on a case by case basis. - No new features will be implemented by maintainers. Pull requests for new features will be reviewed on a case by case basis.
- The priority is triaging issues, addressing security issues, and fixing bug fixes. - The priority is triaging issues, addressing security issues and reviewing pull requests meant to solve bugs.
## Contributing ## Contributing

View File

@@ -31,6 +31,7 @@ func addConfigFlags(flags *pflag.FlagSet) {
addServerFlags(flags) addServerFlags(flags)
addUserFlags(flags) addUserFlags(flags)
flags.BoolP("signup", "s", false, "allow users to signup") flags.BoolP("signup", "s", false, "allow users to signup")
flags.Bool("hide-login-button", false, "hide login button from public pages")
flags.Bool("create-user-dir", false, "generate user's home directory automatically") flags.Bool("create-user-dir", false, "generate user's home directory automatically")
flags.Uint("minimum-password-length", settings.DefaultMinimumPasswordLength, "minimum password length for new users") flags.Uint("minimum-password-length", settings.DefaultMinimumPasswordLength, "minimum password length for new users")
flags.String("shell", "", "shell command to which other commands should be appended") flags.String("shell", "", "shell command to which other commands should be appended")
@@ -192,9 +193,10 @@ func printSettings(ser *settings.Server, set *settings.Settings, auther auth.Aut
w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0) w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0)
fmt.Fprintf(w, "Sign up:\t%t\n", set.Signup) fmt.Fprintf(w, "Sign up:\t%t\n", set.Signup)
fmt.Fprintf(w, "Hide Login Button:\t%t\n", set.HideLoginButton)
fmt.Fprintf(w, "Create User Dir:\t%t\n", set.CreateUserDir) fmt.Fprintf(w, "Create User Dir:\t%t\n", set.CreateUserDir)
fmt.Fprintf(w, "Minimum Password Length:\t%d\n", set.MinimumPasswordLength) fmt.Fprintf(w, "Minimum Password Length:\t%d\n", set.MinimumPasswordLength)
fmt.Fprintf(w, "Auth method:\t%s\n", set.AuthMethod) fmt.Fprintf(w, "Auth Method:\t%s\n", set.AuthMethod)
fmt.Fprintf(w, "Shell:\t%s\t\n", strings.Join(set.Shell, " ")) fmt.Fprintf(w, "Shell:\t%s\t\n", strings.Join(set.Shell, " "))
fmt.Fprintln(w, "\nBranding:") fmt.Fprintln(w, "\nBranding:")
fmt.Fprintf(w, "\tName:\t%s\n", set.Branding.Name) fmt.Fprintf(w, "\tName:\t%s\n", set.Branding.Name)
@@ -215,6 +217,7 @@ func printSettings(ser *settings.Server, set *settings.Settings, auther auth.Aut
fmt.Fprintf(w, "\tExec Enabled:\t%t\n", ser.EnableExec) fmt.Fprintf(w, "\tExec Enabled:\t%t\n", ser.EnableExec)
fmt.Fprintln(w, "\nDefaults:") fmt.Fprintln(w, "\nDefaults:")
fmt.Fprintf(w, "\tScope:\t%s\n", set.Defaults.Scope) fmt.Fprintf(w, "\tScope:\t%s\n", set.Defaults.Scope)
fmt.Fprintf(w, "\tHideDotfiles:\t%t\n", set.Defaults.HideDotfiles)
fmt.Fprintf(w, "\tLocale:\t%s\n", set.Defaults.Locale) fmt.Fprintf(w, "\tLocale:\t%s\n", set.Defaults.Locale)
fmt.Fprintf(w, "\tView mode:\t%s\n", set.Defaults.ViewMode) fmt.Fprintf(w, "\tView mode:\t%s\n", set.Defaults.ViewMode)
fmt.Fprintf(w, "\tSingle Click:\t%t\n", set.Defaults.SingleClick) fmt.Fprintf(w, "\tSingle Click:\t%t\n", set.Defaults.SingleClick)

View File

@@ -41,6 +41,11 @@ override the options.`,
return err return err
} }
hideLoginButton, err := getBool(flags, "hide-login-button")
if err != nil {
return err
}
createUserDir, err := getBool(flags, "create-user-dir") createUserDir, err := getBool(flags, "create-user-dir")
if err != nil { if err != nil {
return err return err
@@ -84,6 +89,7 @@ override the options.`,
s := &settings.Settings{ s := &settings.Settings{
Key: key, Key: key,
Signup: signup, Signup: signup,
HideLoginButton: hideLoginButton,
CreateUserDir: createUserDir, CreateUserDir: createUserDir,
MinimumPasswordLength: minLength, MinimumPasswordLength: minLength,
Shell: convertCmdStrToCmdArray(shell), Shell: convertCmdStrToCmdArray(shell),

View File

@@ -50,6 +50,8 @@ you want to change. Other options will remain unchanged.`,
ser.Port, err = getString(flags, flag.Name) ser.Port, err = getString(flags, flag.Name)
case "log": case "log":
ser.Log, err = getString(flags, flag.Name) ser.Log, err = getString(flags, flag.Name)
case "hide-login-button":
set.HideLoginButton, err = getBool(flags, flag.Name)
case "signup": case "signup":
set.Signup, err = getBool(flags, flag.Name) set.Signup, err = getBool(flags, flag.Name)
case "auth.method": case "auth.method":

View File

@@ -21,7 +21,7 @@ func init() {
func printToc(names []string) { func printToc(names []string) {
for i, name := range names { for i, name := range names {
name = strings.TrimSuffix(name, filepath.Ext(name)) name = strings.TrimSuffix(name, filepath.Ext(name))
name = strings.Replace(name, "-", " ", -1) name = strings.ReplaceAll(name, "-", " ")
names[i] = name names[i] = name
} }
@@ -29,7 +29,7 @@ func printToc(names []string) {
toc := "" toc := ""
for _, name := range names { for _, name := range names {
toc += "* [" + name + "](cli/" + strings.Replace(name, " ", "-", -1) + ".md)\n" toc += "* [" + name + "](cli/" + strings.ReplaceAll(name, " ", "-") + ".md)\n"
} }
fmt.Println(toc) fmt.Println(toc)
@@ -84,7 +84,7 @@ func generateDocs(cmd *cobra.Command, dir string) error {
} }
} }
basename := strings.Replace(cmd.CommandPath(), " ", "-", -1) + ".md" basename := strings.ReplaceAll(cmd.CommandPath(), " ", "-") + ".md"
filename := filepath.Join(dir, basename) filename := filepath.Join(dir, basename)
f, err := os.Create(filename) f, err := os.Create(filename)
if err != nil { if err != nil {

View File

@@ -420,6 +420,7 @@ func quickSetup(flags *pflag.FlagSet, d pythonData) error {
set := &settings.Settings{ set := &settings.Settings{
Key: generateKey(), Key: generateKey(),
Signup: false, Signup: false,
HideLoginButton: true,
CreateUserDir: false, CreateUserDir: false,
MinimumPasswordLength: settings.DefaultMinimumPasswordLength, MinimumPasswordLength: settings.DefaultMinimumPasswordLength,
UserHomeBasePath: settings.DefaultUsersHomeBasePath, UserHomeBasePath: settings.DefaultUsersHomeBasePath,
@@ -533,8 +534,7 @@ func initConfig() {
v.SetEnvPrefix("FB") v.SetEnvPrefix("FB")
v.AutomaticEnv() v.AutomaticEnv()
v.SetEnvKeyReplacer(strings.NewReplacer(".", "_")) v.SetEnvKeyReplacer(strings.NewReplacer(".", "_", "-", "_"))
v.SetEnvKeyReplacer(strings.NewReplacer("-", "_"))
if err := v.ReadInConfig(); err != nil { if err := v.ReadInConfig(); err != nil {
var configParseError v.ConfigParseError var configParseError v.ConfigParseError

View File

@@ -135,6 +135,8 @@ func getUserDefaults(flags *pflag.FlagSet, defaults *settings.UserDefaults, all
defaults.Sorting.By, err = getString(flags, flag.Name) defaults.Sorting.By, err = getString(flags, flag.Name)
case "sorting.asc": case "sorting.asc":
defaults.Sorting.Asc, err = getBool(flags, flag.Name) defaults.Sorting.Asc, err = getBool(flags, flag.Name)
case "hideDotfiles":
defaults.HideDotfiles, err = getBool(flags, flag.Name)
} }
if err != nil { if err != nil {
visitErr = err visitErr = err

View File

@@ -23,16 +23,8 @@ import (
const dbPerms = 0640 const dbPerms = 0640
func returnErr(err error) error {
if err != nil {
return err
}
return nil
}
func getString(flags *pflag.FlagSet, flag string) (string, error) { func getString(flags *pflag.FlagSet, flag string) (string, error) {
s, err := flags.GetString(flag) return flags.GetString(flag)
return s, returnErr(err)
} }
func getMode(flags *pflag.FlagSet, flag string) (fs.FileMode, error) { func getMode(flags *pflag.FlagSet, flag string) (fs.FileMode, error) {
@@ -48,13 +40,11 @@ func getMode(flags *pflag.FlagSet, flag string) (fs.FileMode, error) {
} }
func getBool(flags *pflag.FlagSet, flag string) (bool, error) { func getBool(flags *pflag.FlagSet, flag string) (bool, error) {
b, err := flags.GetBool(flag) return flags.GetBool(flag)
return b, returnErr(err)
} }
func getUint(flags *pflag.FlagSet, flag string) (uint, error) { func getUint(flags *pflag.FlagSet, flag string) (uint, error) {
b, err := flags.GetUint(flag) return flags.GetUint(flag)
return b, returnErr(err)
} }
func generateKey() []byte { func generateKey() []byte {

View File

@@ -1,34 +0,0 @@
module.exports = {
rules: {
'body-leading-blank': [1, 'always'],
'body-max-line-length': [2, 'always', 100],
'footer-leading-blank': [1, 'always'],
'footer-max-line-length': [2, 'always', 100],
'header-max-length': [2, 'always', 100],
'scope-case': [2, 'always', 'lower-case'],
'subject-case': [
2,
'never',
['sentence-case', 'start-case', 'pascal-case', 'upper-case'],
],
'subject-full-stop': [2, 'never', '.'],
'type-case': [2, 'always', 'lower-case'],
'type-empty': [2, 'never'],
'type-enum': [
2,
'always',
[
'feat',
'fix',
'perf',
'revert',
'refactor',
'build',
'ci',
'test',
'chore',
'docs',
],
],
},
};

View File

@@ -0,0 +1,47 @@
<template>
<div
class="context-menu"
ref="contextMenu"
v-show="show"
:style="{
top: `${props.pos.y}px`,
left: `${left}px`,
}"
>
<slot />
</div>
</template>
<script setup lang="ts">
import { ref, watch, computed, onUnmounted } from "vue";
const emit = defineEmits(["hide"]);
const props = defineProps<{ show: boolean; pos: { x: number; y: number } }>();
const contextMenu = ref<HTMLElement | null>(null);
const left = computed(() => {
return Math.min(
props.pos.x,
window.innerWidth - (contextMenu.value?.clientWidth ?? 0)
);
});
const hideContextMenu = () => {
emit("hide");
};
watch(
() => props.show,
(val) => {
if (val) {
document.addEventListener("click", hideContextMenu);
} else {
document.removeEventListener("click", hideContextMenu);
}
}
);
onUnmounted(() => {
document.removeEventListener("click", hideContextMenu);
});
</script>

View File

@@ -63,6 +63,7 @@
</template> </template>
<template v-else> <template v-else>
<router-link <router-link
v-if="!hideLoginButton"
class="action" class="action"
to="/login" to="/login"
:aria-label="$t('sidebar.login')" :aria-label="$t('sidebar.login')"
@@ -124,6 +125,7 @@ import * as auth from "@/utils/auth";
import { import {
version, version,
signup, signup,
hideLoginButton,
disableExternal, disableExternal,
disableUsedPercentage, disableUsedPercentage,
noAuth, noAuth,
@@ -153,6 +155,7 @@ export default {
return this.currentPromptName === "sidebar"; return this.currentPromptName === "sidebar";
}, },
signup: () => signup, signup: () => signup,
hideLoginButton: () => hideLoginButton,
version: () => version, version: () => version,
disableExternal: () => disableExternal, disableExternal: () => disableExternal,
disableUsedPercentage: () => disableUsedPercentage, disableUsedPercentage: () => disableUsedPercentage,

View File

@@ -20,6 +20,7 @@
:aria-label="name" :aria-label="name"
:aria-selected="isSelected" :aria-selected="isSelected"
:data-ext="getExtension(name).toLowerCase()" :data-ext="getExtension(name).toLowerCase()"
@contextmenu="contextMenu"
> >
<div> <div>
<img <img
@@ -239,6 +240,17 @@ const itemClick = (event: Event | KeyboardEvent) => {
else click(event); else click(event);
}; };
const contextMenu = (event: MouseEvent) => {
event.preventDefault();
if (
fileStore.selected.length === 0 ||
event.ctrlKey ||
fileStore.selected.indexOf(props.index) === -1
) {
click(event);
}
};
const click = (event: Event | KeyboardEvent) => { const click = (event: Event | KeyboardEvent) => {
if (!singleClick.value && fileStore.selectedCount !== 0) if (!singleClick.value && fileStore.selectedCount !== 0)
event.preventDefault(); event.preventDefault();

View File

@@ -5,6 +5,7 @@
</div> </div>
<div class="card-content"> <div class="card-content">
<p>{{ $t("prompts.moveMessage") }}</p>
<file-list <file-list
ref="fileList" ref="fileList"
@update:selected="(val) => (dest = val)" @update:selected="(val) => (dest = val)"

View File

@@ -0,0 +1,21 @@
.context-menu {
position: absolute;
background: var(--surfacePrimary);
min-width: 180px;
max-width: 220px;
border: 1px solid var(--borderSecondary);
box-shadow: 0 2px 4px var(--borderPrimary);
z-index: 999;
}
.context-menu .action {
display: block;
width: 100%;
border-radius: 0;
display: flex;
align-items: center;
}
.context-menu .action .counter {
left: 1.75em;
}

View File

@@ -17,6 +17,7 @@
@import "./mobile.css"; @import "./mobile.css";
@import "./epubReader.css"; @import "./epubReader.css";
@import "./mdPreview.css"; @import "./mdPreview.css";
@import "./context-menu.css";
/* For testing only /* For testing only
:focus { :focus {
@@ -459,4 +460,4 @@ html[dir="rtl"] .card-content .small + input {
html[dir="rtl"] .card.floating .card-content .file-list { html[dir="rtl"] .card.floating .card-content .file-list {
direction: ltr; direction: ltr;
text-align: left; text-align: left;
} }

View File

@@ -166,6 +166,7 @@
"allowNew": "إنشاء ملفات و مجلدات جديدة", "allowNew": "إنشاء ملفات و مجلدات جديدة",
"allowPublish": "نشر مقالات و صفحات جديدة", "allowPublish": "نشر مقالات و صفحات جديدة",
"allowSignup": "اسمح للمستخدمين بالاشتراك", "allowSignup": "اسمح للمستخدمين بالاشتراك",
"hideLoginButton": "Hide the login button from public pages",
"avoidChanges": "(أتركه فارغاً إن لم ترد تغييره)", "avoidChanges": "(أتركه فارغاً إن لم ترد تغييره)",
"branding": "الشعار", "branding": "الشعار",
"brandingDirectoryPath": "مسار مجلد الشعار", "brandingDirectoryPath": "مسار مجلد الشعار",

View File

@@ -166,6 +166,7 @@
"allowNew": "Crear nous fitxers i carpetes", "allowNew": "Crear nous fitxers i carpetes",
"allowPublish": "Publicar nous posts i pàgines", "allowPublish": "Publicar nous posts i pàgines",
"allowSignup": "Permetre registre d'usuaris", "allowSignup": "Permetre registre d'usuaris",
"hideLoginButton": "Hide the login button from public pages",
"avoidChanges": "(deixar en blanc per evitar canvis)", "avoidChanges": "(deixar en blanc per evitar canvis)",
"branding": "Marca", "branding": "Marca",
"brandingDirectoryPath": "Ruta de la carpeta de personalització de marca", "brandingDirectoryPath": "Ruta de la carpeta de personalització de marca",

View File

@@ -166,6 +166,7 @@
"allowNew": "Vytvářet nové soubory a adresáře", "allowNew": "Vytvářet nové soubory a adresáře",
"allowPublish": "Publikovat nové příspěvky a stránky", "allowPublish": "Publikovat nové příspěvky a stránky",
"allowSignup": "Povolit uživatelům registraci", "allowSignup": "Povolit uživatelům registraci",
"hideLoginButton": "Hide the login button from public pages",
"avoidChanges": "(ponechte prázdné pro zabránění změnám)", "avoidChanges": "(ponechte prázdné pro zabránění změnám)",
"branding": "Branding", "branding": "Branding",
"brandingDirectoryPath": "Cesta ke složce s brandingem", "brandingDirectoryPath": "Cesta ke složce s brandingem",

View File

@@ -166,6 +166,7 @@
"allowNew": "Erstellen neuer Dateien und Ordner", "allowNew": "Erstellen neuer Dateien und Ordner",
"allowPublish": "Veröffentlichen von neuen Beiträgen und Seiten", "allowPublish": "Veröffentlichen von neuen Beiträgen und Seiten",
"allowSignup": "Erlaube Benutzern sich zu registrieren", "allowSignup": "Erlaube Benutzern sich zu registrieren",
"hideLoginButton": "Hide the login button from public pages",
"avoidChanges": "(leer lassen, um Änderungen zu vermeiden)", "avoidChanges": "(leer lassen, um Änderungen zu vermeiden)",
"branding": "Design", "branding": "Design",
"brandingDirectoryPath": "Designverzeichnispfad", "brandingDirectoryPath": "Designverzeichnispfad",

View File

@@ -166,6 +166,7 @@
"allowNew": "Δημιουργία νέων αρχείων και φακέλων", "allowNew": "Δημιουργία νέων αρχείων και φακέλων",
"allowPublish": "Δημοσίευση νέων αναρτήσεων και σελίδων", "allowPublish": "Δημοσίευση νέων αναρτήσεων και σελίδων",
"allowSignup": "Να επιτρέπεται η εγγραφή νέων χρηστών", "allowSignup": "Να επιτρέπεται η εγγραφή νέων χρηστών",
"hideLoginButton": "Hide the login button from public pages",
"avoidChanges": "(αφήστε το κενό για αποφυγή αλλαγών)", "avoidChanges": "(αφήστε το κενό για αποφυγή αλλαγών)",
"branding": "Εξατομίκευση", "branding": "Εξατομίκευση",
"brandingDirectoryPath": "Διαδρομή φακέλου εξατομίκευσης", "brandingDirectoryPath": "Διαδρομή φακέλου εξατομίκευσης",

View File

@@ -166,6 +166,7 @@
"allowNew": "Create new files and directories", "allowNew": "Create new files and directories",
"allowPublish": "Publish new posts and pages", "allowPublish": "Publish new posts and pages",
"allowSignup": "Allow users to signup", "allowSignup": "Allow users to signup",
"hideLoginButton": "Hide the login button from public pages",
"avoidChanges": "(leave blank to avoid changes)", "avoidChanges": "(leave blank to avoid changes)",
"branding": "Branding", "branding": "Branding",
"brandingDirectoryPath": "Branding directory path", "brandingDirectoryPath": "Branding directory path",

View File

@@ -166,6 +166,7 @@
"allowNew": "Crear nuevos archivos y carpetas", "allowNew": "Crear nuevos archivos y carpetas",
"allowPublish": "Publicar nuevos posts y páginas", "allowPublish": "Publicar nuevos posts y páginas",
"allowSignup": "Permitir registro de usuarios", "allowSignup": "Permitir registro de usuarios",
"hideLoginButton": "Hide the login button from public pages",
"avoidChanges": "(dejar en blanco para evitar cambios)", "avoidChanges": "(dejar en blanco para evitar cambios)",
"branding": "Marca", "branding": "Marca",
"brandingDirectoryPath": "Ruta de la carpeta de personalizacion de marca", "brandingDirectoryPath": "Ruta de la carpeta de personalizacion de marca",

View File

@@ -166,6 +166,7 @@
"allowNew": "ایجاد فایلها و پوشه های جدید", "allowNew": "ایجاد فایلها و پوشه های جدید",
"allowPublish": "انتشار پست ها و صفحات جدید", "allowPublish": "انتشار پست ها و صفحات جدید",
"allowSignup": "اجاره دادن به کاربران برای ثبت نام", "allowSignup": "اجاره دادن به کاربران برای ثبت نام",
"hideLoginButton": "Hide the login button from public pages",
"avoidChanges": "(خالی بگذارید تا تغییر ایجاد نشود)", "avoidChanges": "(خالی بگذارید تا تغییر ایجاد نشود)",
"branding": "برندسازی", "branding": "برندسازی",
"brandingDirectoryPath": "مسیر پوشه برند", "brandingDirectoryPath": "مسیر پوشه برند",

View File

@@ -166,6 +166,7 @@
"allowNew": "Créer de nouveaux fichiers et dossiers", "allowNew": "Créer de nouveaux fichiers et dossiers",
"allowPublish": "Publier de nouveaux posts et pages", "allowPublish": "Publier de nouveaux posts et pages",
"allowSignup": "Autoriser les utilisateur·ices à s'inscrire", "allowSignup": "Autoriser les utilisateur·ices à s'inscrire",
"hideLoginButton": "Hide the login button from public pages",
"avoidChanges": "(Laisser vide pour conserver l'actuel)", "avoidChanges": "(Laisser vide pour conserver l'actuel)",
"branding": "Image de marque", "branding": "Image de marque",
"brandingDirectoryPath": "Chemin du dossier d'image de marque", "brandingDirectoryPath": "Chemin du dossier d'image de marque",

View File

@@ -166,6 +166,7 @@
"allowNew": "יצירת קבצים ותיקיות חדשות", "allowNew": "יצירת קבצים ותיקיות חדשות",
"allowPublish": "פרסום פוסטים ודפים חדשים", "allowPublish": "פרסום פוסטים ודפים חדשים",
"allowSignup": "אפשר למשתמשים חדשים להירשם", "allowSignup": "אפשר למשתמשים חדשים להירשם",
"hideLoginButton": "Hide the login button from public pages",
"avoidChanges": "(השאר ריק כדי למנוע שינויים)", "avoidChanges": "(השאר ריק כדי למנוע שינויים)",
"branding": "מיתוג", "branding": "מיתוג",
"brandingDirectoryPath": "נתיב תיקיית מיתוג", "brandingDirectoryPath": "נתיב תיקיית מיתוג",

View File

@@ -166,6 +166,7 @@
"allowNew": "Stvori nove datoteke i mape", "allowNew": "Stvori nove datoteke i mape",
"allowPublish": "Objavi nove objave i stranice", "allowPublish": "Objavi nove objave i stranice",
"allowSignup": "Dopusti registraciju korisnicima", "allowSignup": "Dopusti registraciju korisnicima",
"hideLoginButton": "Hide the login button from public pages",
"avoidChanges": "(ostavite prazno kako biste izbjegli promjene)", "avoidChanges": "(ostavite prazno kako biste izbjegli promjene)",
"branding": "Brendiranje", "branding": "Brendiranje",
"brandingDirectoryPath": "Put brendiranja", "brandingDirectoryPath": "Put brendiranja",

View File

@@ -166,6 +166,7 @@
"allowNew": "Új fájlok és mappák létrehozása", "allowNew": "Új fájlok és mappák létrehozása",
"allowPublish": "Új bejegyzések és oldalak létrehozása", "allowPublish": "Új bejegyzések és oldalak létrehozása",
"allowSignup": "Felhasználók regisztrációjának engedélyezése", "allowSignup": "Felhasználók regisztrációjának engedélyezése",
"hideLoginButton": "Hide the login button from public pages",
"avoidChanges": "(üresen hagyva nincs változás)", "avoidChanges": "(üresen hagyva nincs változás)",
"branding": "Márkázás", "branding": "Márkázás",
"brandingDirectoryPath": "Márkázás mappaútvonala", "brandingDirectoryPath": "Márkázás mappaútvonala",

View File

@@ -166,6 +166,7 @@
"allowNew": "Búa til ný skjöl og möppur", "allowNew": "Búa til ný skjöl og möppur",
"allowPublish": "Gefa út nýjar færslur og síður", "allowPublish": "Gefa út nýjar færslur og síður",
"allowSignup": "Leyfa nýjum notendum að skrá sig", "allowSignup": "Leyfa nýjum notendum að skrá sig",
"hideLoginButton": "Hide the login button from public pages",
"avoidChanges": "(engar breytingar ef ekkert er skrifað)", "avoidChanges": "(engar breytingar ef ekkert er skrifað)",
"branding": "Útlit", "branding": "Útlit",
"brandingDirectoryPath": "Mappa fyrir branding-skjöl", "brandingDirectoryPath": "Mappa fyrir branding-skjöl",

View File

@@ -166,6 +166,7 @@
"allowNew": "Crea nuovi files o cartelle", "allowNew": "Crea nuovi files o cartelle",
"allowPublish": "Pubblica nuovi post e pagine", "allowPublish": "Pubblica nuovi post e pagine",
"allowSignup": "Permetti agli utenti di registrarsi", "allowSignup": "Permetti agli utenti di registrarsi",
"hideLoginButton": "Hide the login button from public pages",
"avoidChanges": "(lascia vuoto per evitare cambiamenti)", "avoidChanges": "(lascia vuoto per evitare cambiamenti)",
"branding": "Branding", "branding": "Branding",
"brandingDirectoryPath": "Directory del branding", "brandingDirectoryPath": "Directory del branding",

View File

@@ -166,6 +166,7 @@
"allowNew": "ファイルやフォルダーの新規作成", "allowNew": "ファイルやフォルダーの新規作成",
"allowPublish": "新しい投稿やページの公開", "allowPublish": "新しい投稿やページの公開",
"allowSignup": "ユーザーの新規登録を許可", "allowSignup": "ユーザーの新規登録を許可",
"hideLoginButton": "Hide the login button from public pages",
"avoidChanges": "(変更しない場合は空白のままにしてください)", "avoidChanges": "(変更しない場合は空白のままにしてください)",
"branding": "ブランディング", "branding": "ブランディング",
"brandingDirectoryPath": "ブランディングのディレクトリへのパス", "brandingDirectoryPath": "ブランディングのディレクトリへのパス",

View File

@@ -166,6 +166,7 @@
"allowNew": "파일/디렉토리 생성 허용", "allowNew": "파일/디렉토리 생성 허용",
"allowPublish": "새 포스트/페이지 생성 허용", "allowPublish": "새 포스트/페이지 생성 허용",
"allowSignup": "사용자 가입 허용", "allowSignup": "사용자 가입 허용",
"hideLoginButton": "Hide the login button from public pages",
"avoidChanges": "(수정하지 않으면 비워두세요)", "avoidChanges": "(수정하지 않으면 비워두세요)",
"branding": "브랜딩", "branding": "브랜딩",
"brandingDirectoryPath": "브랜드 디렉토리 경로", "brandingDirectoryPath": "브랜드 디렉토리 경로",

View File

@@ -166,6 +166,7 @@
"allowNew": "Nieuwe bestanden of mappen aanmaken", "allowNew": "Nieuwe bestanden of mappen aanmaken",
"allowPublish": "Publiceer nieuwe berichten en pagina's", "allowPublish": "Publiceer nieuwe berichten en pagina's",
"allowSignup": "Sta gebruikers toe om zich te registreren", "allowSignup": "Sta gebruikers toe om zich te registreren",
"hideLoginButton": "Hide the login button from public pages",
"avoidChanges": "(laat leeg om wijzigingen te voorkomen)", "avoidChanges": "(laat leeg om wijzigingen te voorkomen)",
"branding": "Branding", "branding": "Branding",
"brandingDirectoryPath": "Branding directory path", "brandingDirectoryPath": "Branding directory path",

View File

@@ -166,6 +166,7 @@
"allowNew": "Opprett nye filer og direktorater", "allowNew": "Opprett nye filer og direktorater",
"allowPublish": "Publiser nye innlegg og sider", "allowPublish": "Publiser nye innlegg og sider",
"allowSignup": "Tilat brukere å registrere seg", "allowSignup": "Tilat brukere å registrere seg",
"hideLoginButton": "Hide the login button from public pages",
"avoidChanges": "(la stå tomt for å unngå endringer)", "avoidChanges": "(la stå tomt for å unngå endringer)",
"branding": "Merkevarebygging", "branding": "Merkevarebygging",
"brandingDirectoryPath": "Bane for merkevarekatalog", "brandingDirectoryPath": "Bane for merkevarekatalog",

View File

@@ -166,6 +166,7 @@
"allowNew": "Tworzenie nowych plików lub folderów", "allowNew": "Tworzenie nowych plików lub folderów",
"allowPublish": "Tworzenie nowych wpisów i stron", "allowPublish": "Tworzenie nowych wpisów i stron",
"allowSignup": "Pozwól użytkownikom na rejestrację", "allowSignup": "Pozwól użytkownikom na rejestrację",
"hideLoginButton": "Ukryj przycisk logowania na stronach publicznych",
"avoidChanges": "(pozostaw puste, aby uniknąć zmian)", "avoidChanges": "(pozostaw puste, aby uniknąć zmian)",
"branding": "Personalizacja", "branding": "Personalizacja",
"brandingDirectoryPath": "Ścieżka do folderu personalizacji", "brandingDirectoryPath": "Ścieżka do folderu personalizacji",

View File

@@ -166,6 +166,7 @@
"allowNew": "Criar novos arquivos e pastas", "allowNew": "Criar novos arquivos e pastas",
"allowPublish": "Publicar novas páginas e conteúdos", "allowPublish": "Publicar novas páginas e conteúdos",
"allowSignup": "Permitir cadastro de usuários", "allowSignup": "Permitir cadastro de usuários",
"hideLoginButton": "Hide the login button from public pages",
"avoidChanges": "(deixe em branco para manter)", "avoidChanges": "(deixe em branco para manter)",
"branding": "Customização", "branding": "Customização",
"brandingDirectoryPath": "Diretório de customização", "brandingDirectoryPath": "Diretório de customização",

View File

@@ -166,6 +166,7 @@
"allowNew": "Criar novos ficheiros e pastas", "allowNew": "Criar novos ficheiros e pastas",
"allowPublish": "Publicar novas páginas e conteúdos", "allowPublish": "Publicar novas páginas e conteúdos",
"allowSignup": "Permitir que os utilizadores criem contas", "allowSignup": "Permitir que os utilizadores criem contas",
"hideLoginButton": "Hide the login button from public pages",
"avoidChanges": "(deixe em branco para manter)", "avoidChanges": "(deixe em branco para manter)",
"branding": "Marca", "branding": "Marca",
"brandingDirectoryPath": "Caminho da pasta de marca", "brandingDirectoryPath": "Caminho da pasta de marca",

View File

@@ -166,6 +166,7 @@
"allowNew": "Crează noi fișiere sau directoare", "allowNew": "Crează noi fișiere sau directoare",
"allowPublish": "Publică noi pagini și postări", "allowPublish": "Publică noi pagini și postări",
"allowSignup": "Permite utilizatorilor să se înregistreze", "allowSignup": "Permite utilizatorilor să se înregistreze",
"hideLoginButton": "Hide the login button from public pages",
"avoidChanges": "(lasă gol pentru a nu schimba)", "avoidChanges": "(lasă gol pentru a nu schimba)",
"branding": "Branding", "branding": "Branding",
"brandingDirectoryPath": "Calea către directorul de branding", "brandingDirectoryPath": "Calea către directorul de branding",

View File

@@ -166,6 +166,7 @@
"allowNew": "Создание новых файлов или каталогов", "allowNew": "Создание новых файлов или каталогов",
"allowPublish": "Публикация новых записей и страниц", "allowPublish": "Публикация новых записей и страниц",
"allowSignup": "Разрешить пользователям регистрироваться", "allowSignup": "Разрешить пользователям регистрироваться",
"hideLoginButton": "Hide the login button from public pages",
"avoidChanges": "(оставьте поле пустым, чтобы избежать изменений)", "avoidChanges": "(оставьте поле пустым, чтобы избежать изменений)",
"branding": "Брендинг", "branding": "Брендинг",
"brandingDirectoryPath": "Путь к каталогу брендов", "brandingDirectoryPath": "Путь к каталогу брендов",

View File

@@ -166,6 +166,7 @@
"allowNew": "Vytvárať nové súbory a priečinky", "allowNew": "Vytvárať nové súbory a priečinky",
"allowPublish": "Zverejňovať nové príspevky a stránky", "allowPublish": "Zverejňovať nové príspevky a stránky",
"allowSignup": "Povoliť registráciu používateľov", "allowSignup": "Povoliť registráciu používateľov",
"hideLoginButton": "Hide the login button from public pages",
"avoidChanges": "(nechajte prázdne, aby sa nezmenilo)", "avoidChanges": "(nechajte prázdne, aby sa nezmenilo)",
"branding": "Vlastný vzhľad", "branding": "Vlastný vzhľad",
"brandingDirectoryPath": "Cesta k priečinku s vlastným vzhľadom", "brandingDirectoryPath": "Cesta k priečinku s vlastným vzhľadom",

View File

@@ -166,6 +166,7 @@
"allowNew": "Skapa nya filer eller mappar", "allowNew": "Skapa nya filer eller mappar",
"allowPublish": "Publicera nya inlägg och sidor", "allowPublish": "Publicera nya inlägg och sidor",
"allowSignup": "Tillåt användare att registrera sig", "allowSignup": "Tillåt användare att registrera sig",
"hideLoginButton": "Hide the login button from public pages",
"avoidChanges": "(lämna blankt för att undvika ändringar)", "avoidChanges": "(lämna blankt för att undvika ändringar)",
"branding": "Varumärke", "branding": "Varumärke",
"brandingDirectoryPath": "Sökväg till varumärkes katalog", "brandingDirectoryPath": "Sökväg till varumärkes katalog",

View File

@@ -166,6 +166,7 @@
"allowNew": "Yeni dosyalar ve dizinler oluşturun", "allowNew": "Yeni dosyalar ve dizinler oluşturun",
"allowPublish": "Yeni linkler ve sayfaları yayınlayın", "allowPublish": "Yeni linkler ve sayfaları yayınlayın",
"allowSignup": "Kullanıcıların kaydolmasına izin ver", "allowSignup": "Kullanıcıların kaydolmasına izin ver",
"hideLoginButton": "Hide the login button from public pages",
"avoidChanges": "(değişiklikleri önlemek için boş bırakın)", "avoidChanges": "(değişiklikleri önlemek için boş bırakın)",
"branding": "Marka", "branding": "Marka",
"brandingDirectoryPath": "Marka dizin yolu", "brandingDirectoryPath": "Marka dizin yolu",

View File

@@ -166,6 +166,7 @@
"allowNew": "Створення нових файлів або каталогів", "allowNew": "Створення нових файлів або каталогів",
"allowPublish": "Публікація нових записів та сторінок", "allowPublish": "Публікація нових записів та сторінок",
"allowSignup": "Дозволити користувачам реєструватися", "allowSignup": "Дозволити користувачам реєструватися",
"hideLoginButton": "Hide the login button from public pages",
"avoidChanges": "(залишіть поле порожнім, щоб уникнути змін)", "avoidChanges": "(залишіть поле порожнім, щоб уникнути змін)",
"branding": "Брендинг", "branding": "Брендинг",
"brandingDirectoryPath": "Шлях до каталогу брендів", "brandingDirectoryPath": "Шлях до каталогу брендів",

View File

@@ -166,6 +166,7 @@
"allowNew": "Tạo tệp và thư mục mới", "allowNew": "Tạo tệp và thư mục mới",
"allowPublish": "Xuất bản bài viết và trang mới", "allowPublish": "Xuất bản bài viết và trang mới",
"allowSignup": "Cho phép người dùng đăng ký", "allowSignup": "Cho phép người dùng đăng ký",
"hideLoginButton": "Hide the login button from public pages",
"avoidChanges": "(để trống để tránh thay đổi)", "avoidChanges": "(để trống để tránh thay đổi)",
"branding": "Thương hiệu", "branding": "Thương hiệu",
"brandingDirectoryPath": "Đường dẫn thư mục thương hiệu", "brandingDirectoryPath": "Đường dẫn thư mục thương hiệu",

View File

@@ -166,6 +166,7 @@
"allowNew": "创建新文件和文件夹", "allowNew": "创建新文件和文件夹",
"allowPublish": "发布新的帖子与页面", "allowPublish": "发布新的帖子与页面",
"allowSignup": "允许用户注册", "allowSignup": "允许用户注册",
"hideLoginButton": "Hide the login button from public pages",
"avoidChanges": "(留空以避免更改)", "avoidChanges": "(留空以避免更改)",
"branding": "品牌", "branding": "品牌",
"brandingDirectoryPath": "品牌信息文件夹路径", "brandingDirectoryPath": "品牌信息文件夹路径",

View File

@@ -166,6 +166,7 @@
"allowNew": "建立新檔案和目錄", "allowNew": "建立新檔案和目錄",
"allowPublish": "發佈新的貼文與頁面", "allowPublish": "發佈新的貼文與頁面",
"allowSignup": "允許使用者註冊", "allowSignup": "允許使用者註冊",
"hideLoginButton": "Hide the login button from public pages",
"avoidChanges": "(留空以避免更改)", "avoidChanges": "(留空以避免更改)",
"branding": "品牌", "branding": "品牌",
"brandingDirectoryPath": "品牌資訊資料夾路徑", "brandingDirectoryPath": "品牌資訊資料夾路徑",

View File

@@ -1,6 +1,7 @@
interface ISettings { interface ISettings {
signup: boolean; signup: boolean;
createUserDir: boolean; createUserDir: boolean;
hideLoginButton: boolean;
minimumPasswordLength: number; minimumPasswordLength: number;
userHomeBasePath: string; userHomeBasePath: string;
defaults: SettingsDefaults; defaults: SettingsDefaults;

View File

@@ -18,6 +18,7 @@ const enableExec: boolean = window.FileBrowser.EnableExec;
const tusSettings = window.FileBrowser.TusSettings; const tusSettings = window.FileBrowser.TusSettings;
const origin = window.location.origin; const origin = window.location.origin;
const tusEndpoint = `/api/tus`; const tusEndpoint = `/api/tus`;
const hideLoginButton = window.FileBrowser.HideLoginButton;
export { export {
name, name,
@@ -39,4 +40,5 @@ export {
tusSettings, tusSettings,
origin, origin,
tusEndpoint, tusEndpoint,
hideLoginButton,
}; };

View File

@@ -207,7 +207,10 @@
<h2 v-if="fileStore.req?.numDirs ?? false"> <h2 v-if="fileStore.req?.numDirs ?? false">
{{ t("files.folders") }} {{ t("files.folders") }}
</h2> </h2>
<div v-if="fileStore.req?.numDirs ?? false"> <div
v-if="fileStore.req?.numDirs ?? false"
@contextmenu="showContextMenu"
>
<item <item
v-for="item in dirs" v-for="item in dirs"
:key="base64(item.name)" :key="base64(item.name)"
@@ -223,8 +226,13 @@
</item> </item>
</div> </div>
<h2 v-if="fileStore.req?.numFiles ?? false">{{ t("files.files") }}</h2> <h2 v-if="fileStore.req?.numFiles ?? false">
<div v-if="fileStore.req?.numFiles ?? false"> {{ t("files.files") }}
</h2>
<div
v-if="fileStore.req?.numFiles ?? false"
@contextmenu="showContextMenu"
>
<item <item
v-for="item in files" v-for="item in files"
:key="base64(item.name)" :key="base64(item.name)"
@@ -239,6 +247,53 @@
> >
</item> </item>
</div> </div>
<context-menu
:show="isContextMenuVisible"
:pos="contextMenuPos"
@hide="hideContextMenu"
>
<action
v-if="headerButtons.share"
icon="share"
:label="t('buttons.share')"
show="share"
/>
<action
v-if="headerButtons.rename"
icon="mode_edit"
:label="t('buttons.rename')"
show="rename"
/>
<action
v-if="headerButtons.copy"
id="copy-button"
icon="content_copy"
:label="t('buttons.copyFile')"
show="copy"
/>
<action
v-if="headerButtons.move"
id="move-button"
icon="forward"
:label="t('buttons.moveFile')"
show="move"
/>
<action
v-if="headerButtons.delete"
id="delete-button"
icon="delete"
:label="t('buttons.delete')"
show="delete"
/>
<action
v-if="headerButtons.download"
icon="file_download"
:label="t('buttons.download')"
@action="download"
:counter="fileStore.selectedCount"
/>
<action icon="info" :label="t('buttons.info')" show="info" />
</context-menu>
<input <input
style="display: none" style="display: none"
@@ -291,6 +346,7 @@ import HeaderBar from "@/components/header/HeaderBar.vue";
import Action from "@/components/header/Action.vue"; import Action from "@/components/header/Action.vue";
import Search from "@/components/Search.vue"; import Search from "@/components/Search.vue";
import Item from "@/components/files/ListingItem.vue"; import Item from "@/components/files/ListingItem.vue";
import ContextMenu from "@/components/ContextMenu.vue";
import { import {
computed, computed,
inject, inject,
@@ -310,6 +366,8 @@ const columnWidth = ref<number>(280);
const dragCounter = ref<number>(0); const dragCounter = ref<number>(0);
const width = ref<number>(window.innerWidth); const width = ref<number>(window.innerWidth);
const itemWeight = ref<number>(0); const itemWeight = ref<number>(0);
const isContextMenuVisible = ref<boolean>(false);
const contextMenuPos = ref<{ x: number; y: number }>({ x: 0, y: 0 });
const $showError = inject<IToastError>("$showError")!; const $showError = inject<IToastError>("$showError")!;
@@ -438,7 +496,7 @@ watch(req, () => {
onMounted(() => { onMounted(() => {
// Check the columns size for the first time. // Check the columns size for the first time.
colunmsResize(); columnsResize();
// How much every listing item affects the window height // How much every listing item affects the window height
setItemWeight(); setItemWeight();
@@ -642,7 +700,7 @@ const paste = (event: Event) => {
action(overwrite, rename); action(overwrite, rename);
}; };
const colunmsResize = () => { const columnsResize = () => {
// Update the columns size based on the window width. // Update the columns size based on the window width.
const items_ = css(["#listing.mosaic .item", ".mosaic#listing .item"]); const items_ = css(["#listing.mosaic .item", ".mosaic#listing .item"]);
if (items_ === null) return; if (items_ === null) return;
@@ -850,7 +908,7 @@ const toggleMultipleSelection = () => {
}; };
const windowsResize = throttle(() => { const windowsResize = throttle(() => {
colunmsResize(); columnsResize();
width.value = window.innerWidth; width.value = window.innerWidth;
// Listing element is not displayed // Listing element is not displayed
@@ -977,4 +1035,17 @@ const revealPreviousItem = () => {
return true; return true;
}; };
const showContextMenu = (event: MouseEvent) => {
event.preventDefault();
isContextMenuVisible.value = true;
contextMenuPos.value = {
x: event.clientX + 8,
y: event.clientY + Math.floor(window.scrollY),
};
};
const hideContextMenu = () => {
isContextMenuVisible.value = false;
};
</script> </script>

View File

@@ -18,6 +18,11 @@
{{ t("settings.createUserDir") }} {{ t("settings.createUserDir") }}
</p> </p>
<p>
<input type="checkbox" v-model="settings.hideLoginButton" />
{{ t("settings.hideLoginButton") }}
</p>
<p> <p>
<label class="small">{{ t("settings.userHomeBasePath") }}</label> <label class="small">{{ t("settings.userHomeBasePath") }}</label>
<input <input

View File

@@ -124,12 +124,12 @@ func createPreview(imgSvc ImgService, fileCache FileCache,
options []img.Option options []img.Option
) )
switch { switch previewSize {
case previewSize == PreviewSizeBig: case PreviewSizeBig:
width = 1080 width = 1080
height = 1080 height = 1080
options = append(options, img.WithMode(img.ResizeModeFit), img.WithQuality(img.QualityMedium)) options = append(options, img.WithMode(img.ResizeModeFit), img.WithQuality(img.QualityMedium))
case previewSize == PreviewSizeThumb: case PreviewSizeThumb:
width = 256 width = 256
height = 256 height = 256
options = append(options, img.WithMode(img.ResizeModeFill), img.WithQuality(img.QualityLow), img.WithFormat(img.FormatJpeg)) options = append(options, img.WithMode(img.ResizeModeFill), img.WithQuality(img.QualityLow), img.WithFormat(img.FormatJpeg))

View File

@@ -98,8 +98,8 @@ var publicShareHandler = withHashFile(func(w http.ResponseWriter, r *http.Reques
file := d.raw.(*files.FileInfo) file := d.raw.(*files.FileInfo)
if file.IsDir { if file.IsDir {
file.Listing.Sorting = files.Sorting{By: "name", Asc: false} file.Sorting = files.Sorting{By: "name", Asc: false}
file.Listing.ApplySort() file.ApplySort()
return renderJSON(w, r, file) return renderJSON(w, r, file)
} }

View File

@@ -32,7 +32,7 @@ func parseQueryFiles(r *http.Request, f *files.FileInfo, _ *users.User) ([]strin
fileSlice = append(fileSlice, f.Path) fileSlice = append(fileSlice, f.Path)
} else { } else {
for _, name := range names { for _, name := range names {
name, err := url.QueryUnescape(strings.Replace(name, "+", "%2B", -1)) //nolint:govet name, err := url.QueryUnescape(strings.ReplaceAll(name, "+", "%2B"))
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@@ -37,8 +37,8 @@ var resourceGetHandler = withUser(func(w http.ResponseWriter, r *http.Request, d
} }
if file.IsDir { if file.IsDir {
file.Listing.Sorting = d.user.Sorting file.Sorting = d.user.Sorting
file.Listing.ApplySort() file.ApplySort()
return renderJSON(w, r, file) return renderJSON(w, r, file)
} }

View File

@@ -10,6 +10,7 @@ import (
type settingsData struct { type settingsData struct {
Signup bool `json:"signup"` Signup bool `json:"signup"`
HideLoginButton bool `json:"hideLoginButton"`
CreateUserDir bool `json:"createUserDir"` CreateUserDir bool `json:"createUserDir"`
MinimumPasswordLength uint `json:"minimumPasswordLength"` MinimumPasswordLength uint `json:"minimumPasswordLength"`
UserHomeBasePath string `json:"userHomeBasePath"` UserHomeBasePath string `json:"userHomeBasePath"`
@@ -24,6 +25,7 @@ type settingsData struct {
var settingsGetHandler = withAdmin(func(w http.ResponseWriter, r *http.Request, d *data) (int, error) { var settingsGetHandler = withAdmin(func(w http.ResponseWriter, r *http.Request, d *data) (int, error) {
data := &settingsData{ data := &settingsData{
Signup: d.settings.Signup, Signup: d.settings.Signup,
HideLoginButton: d.settings.HideLoginButton,
CreateUserDir: d.settings.CreateUserDir, CreateUserDir: d.settings.CreateUserDir,
MinimumPasswordLength: d.settings.MinimumPasswordLength, MinimumPasswordLength: d.settings.MinimumPasswordLength,
UserHomeBasePath: d.settings.UserHomeBasePath, UserHomeBasePath: d.settings.UserHomeBasePath,
@@ -55,6 +57,7 @@ var settingsPutHandler = withAdmin(func(_ http.ResponseWriter, r *http.Request,
d.settings.Tus = req.Tus d.settings.Tus = req.Tus
d.settings.Shell = req.Shell d.settings.Shell = req.Shell
d.settings.Commands = req.Commands d.settings.Commands = req.Commands
d.settings.HideLoginButton = req.HideLoginButton
err = d.store.Settings.Save(d.settings) err = d.store.Settings.Save(d.settings)
return errToStatus(err), err return errToStatus(err), err

View File

@@ -46,6 +46,7 @@ func handleWithStaticData(w http.ResponseWriter, _ *http.Request, d *data, fSys
"ResizePreview": d.server.ResizePreview, "ResizePreview": d.server.ResizePreview,
"EnableExec": d.server.EnableExec, "EnableExec": d.server.EnableExec,
"TusSettings": d.settings.Tus, "TusSettings": d.settings.Tus,
"HideLoginButton": d.settings.HideLoginButton,
} }
if d.settings.Branding.Files != "" { if d.settings.Branding.Files != "" {

View File

@@ -48,8 +48,8 @@ func parseSearch(value string) *searchOptions {
} }
// removes the options from the value // removes the options from the value
value = strings.Replace(value, "case:insensitive", "", -1) value = strings.ReplaceAll(value, "case:insensitive", "")
value = strings.Replace(value, "case:sensitive", "", -1) value = strings.ReplaceAll(value, "case:sensitive", "")
value = strings.TrimSpace(value) value = strings.TrimSpace(value)
types := typeRegexp.FindAllStringSubmatch(value, -1) types := typeRegexp.FindAllStringSubmatch(value, -1)

View File

@@ -42,7 +42,7 @@ func (s *Settings) MakeUserDir(username, userScope, serverRoot string) (string,
func cleanUsername(s string) string { func cleanUsername(s string) string {
// Remove any trailing space to avoid ending on - // Remove any trailing space to avoid ending on -
s = strings.Trim(s, " ") s = strings.Trim(s, " ")
s = strings.Replace(s, "..", "", -1) s = strings.ReplaceAll(s, "..", "")
// Replace all characters which not in the list `0-9A-Za-z@_\-.` with a dash // Replace all characters which not in the list `0-9A-Za-z@_\-.` with a dash
s = invalidFilenameChars.ReplaceAllString(s, "-") s = invalidFilenameChars.ReplaceAllString(s, "-")

View File

@@ -22,6 +22,7 @@ type AuthMethod string
type Settings struct { type Settings struct {
Key []byte `json:"key"` Key []byte `json:"key"`
Signup bool `json:"signup"` Signup bool `json:"signup"`
HideLoginButton bool `json:"hideLoginButton"`
CreateUserDir bool `json:"createUserDir"` CreateUserDir bool `json:"createUserDir"`
UserHomeBasePath string `json:"userHomeBasePath"` UserHomeBasePath string `json:"userHomeBasePath"`
Defaults UserDefaults `json:"defaults"` Defaults UserDefaults `json:"defaults"`
@@ -34,6 +35,7 @@ type Settings struct {
MinimumPasswordLength uint `json:"minimumPasswordLength"` MinimumPasswordLength uint `json:"minimumPasswordLength"`
FileMode fs.FileMode `json:"fileMode"` FileMode fs.FileMode `json:"fileMode"`
DirMode fs.FileMode `json:"dirMode"` DirMode fs.FileMode `json:"dirMode"`
HideDotfiles bool `json:"hideDotfiles"`
} }
// GetRules implements rules.Provider. // GetRules implements rules.Provider.