Merge pull request #1133 from ramiresviana/fixes-5
Some fixes and shared view improvementspull/1140/head
commit
dcbc3286e2
|
@ -191,10 +191,11 @@ table th {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.share__box, .share__box__download {
|
.share__box {
|
||||||
background: var(--surfaceSecondary) !important;
|
background: var(--surfacePrimary) !important;
|
||||||
color: var(--textPrimary);
|
color: var(--textPrimary);
|
||||||
}
|
}
|
||||||
.share__box__download {
|
|
||||||
border-bottom-color: var(--divider);
|
.share__box__element {
|
||||||
|
border-top-color: var(--divider);
|
||||||
}
|
}
|
|
@ -5,9 +5,7 @@
|
||||||
<i class="material-icons">close</i>
|
<i class="material-icons">close</i>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<div class="title">
|
<div class="title">{{ this.name }}</div>
|
||||||
<span>{{ this.name }}</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<preview-size-button v-if="isResizeEnabled && this.req.type === 'image'" @change-size="toggleSize" v-bind:size="fullSize" :disabled="loading"></preview-size-button>
|
<preview-size-button v-if="isResizeEnabled && this.req.type === 'image'" @change-size="toggleSize" v-bind:size="fullSize" :disabled="loading"></preview-size-button>
|
||||||
<button @click="openMore" id="more" :aria-label="$t('buttons.more')" :title="$t('buttons.more')" class="action">
|
<button @click="openMore" id="more" :aria-label="$t('buttons.more')" :title="$t('buttons.more')" class="action">
|
||||||
|
|
|
@ -1,29 +1,61 @@
|
||||||
.share__box {
|
.share {
|
||||||
text-align: center;
|
display: flex;
|
||||||
box-shadow: rgba(0, 0, 0, 0.06) 0px 1px 3px, rgba(0, 0, 0, 0.12) 0px 1px 2px;
|
flex-wrap: wrap;
|
||||||
background: #fff;
|
justify-content: center;
|
||||||
display: block;
|
align-items: flex-start;
|
||||||
border-radius: 0.2em;
|
|
||||||
width: 90%;
|
|
||||||
max-width: 25em;
|
|
||||||
margin: 6em auto;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.share__box__download {
|
@media (max-width: 736px) {
|
||||||
width: 100%;
|
.share {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.share__box {
|
||||||
|
box-shadow: rgba(0, 0, 0, 0.06) 0px 1px 3px, rgba(0, 0, 0, 0.12) 0px 1px 2px;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 0.2em;
|
||||||
|
margin: 5px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.share__box__header {
|
||||||
padding: 1em;
|
padding: 1em;
|
||||||
cursor: pointer;
|
text-align: center;
|
||||||
background: #ffffff;
|
}
|
||||||
color: rgba(0, 0, 0, 0.5);
|
|
||||||
border-bottom: 1px solid rgba(0, 0, 0, 0.05);
|
.share__box__icon i {
|
||||||
|
font-size: 10em;
|
||||||
|
color: #40c4ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.share__box__center {
|
||||||
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.share__box__info {
|
.share__box__info {
|
||||||
padding: 2em 3em;
|
flex: 1 1 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.share__box__title {
|
.share__box__element {
|
||||||
margin-top: .2em;
|
padding: 1em;
|
||||||
overflow: hidden;
|
border-top: 1px solid rgba(0, 0, 0, 0.1);
|
||||||
text-overflow: ellipsis;
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
|
||||||
|
.share__box__items {
|
||||||
|
text-align: left;
|
||||||
|
flex: 10 0 25em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.share__box__items #listing.list .item {
|
||||||
|
cursor: auto;
|
||||||
|
border-left: 0;
|
||||||
|
border-right: 0;
|
||||||
|
border-bottom: 0;
|
||||||
|
border-top: 1px solid rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.share__box__items #listing.list .item .name {
|
||||||
|
width: auto;
|
||||||
}
|
}
|
|
@ -119,18 +119,23 @@
|
||||||
|
|
||||||
#previewer .bar {
|
#previewer .bar {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
text-align: right;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
padding: 0.5em;
|
padding: 0.5em;
|
||||||
height: 3.7em;
|
height: 3.7em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#previewer .bar > * {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
#previewer .bar .title {
|
#previewer .bar .title {
|
||||||
margin-right: auto;
|
display: block;
|
||||||
|
flex: 1 1 auto;
|
||||||
padding: 0 1em;
|
padding: 0 1em;
|
||||||
line-height: 2.7em;
|
line-height: 2.3em;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
word-break: break-word;
|
text-overflow: ellipsis;
|
||||||
|
font-size: 1.2em;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -220,10 +225,6 @@
|
||||||
word-break: break-word;
|
word-break: break-word;
|
||||||
}
|
}
|
||||||
|
|
||||||
#previewer .title span {
|
|
||||||
font-size: 1.2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
#previewer .loading {
|
#previewer .loading {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
|
@ -1,29 +1,56 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="share" v-if="loaded">
|
<div class="share" v-if="loaded">
|
||||||
<a target="_blank" :href="link">
|
<div class="share__box share__box__info">
|
||||||
<div class="share__box">
|
<div class="share__box__header">
|
||||||
<div class="share__box__download" v-if="file.isDir">{{ $t('download.downloadFolder') }}</div>
|
{{ file.isDir ? $t('download.downloadFolder') : $t('download.downloadFile') }}
|
||||||
<div class="share__box__download" v-else>{{ $t('download.downloadFile') }}</div>
|
</div>
|
||||||
<div class="share__box__info">
|
<div class="share__box__element share__box__center share__box__icon">
|
||||||
<svg v-if="file.isDir" fill="#40c4ff" height="150" viewBox="0 0 24 24" width="150" xmlns="http://www.w3.org/2000/svg">
|
<i class="material-icons">{{ file.isDir ? 'folder' : 'insert_drive_file'}}</i>
|
||||||
<path d="M10 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2h-8l-2-2z"/>
|
</div>
|
||||||
<path d="M0 0h24v24H0z" fill="none"/>
|
<div class="share__box__element">
|
||||||
</svg>
|
<strong>{{ $t('prompts.displayName') }}</strong> {{ file.name }}
|
||||||
<svg v-else fill="#40c4ff" height="150" viewBox="0 0 24 24" width="150" xmlns="http://www.w3.org/2000/svg">
|
</div>
|
||||||
<path d="M6 2c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6H6zm7 7V3.5L18.5 9H13z"/>
|
<div class="share__box__element">
|
||||||
<path d="M0 0h24v24H0z" fill="none"/>
|
<strong>{{ $t('prompts.lastModified') }}:</strong> {{ humanTime }}
|
||||||
</svg>
|
</div>
|
||||||
<h1 class="share__box__title">{{ file.name }}</h1>
|
<div class="share__box__element">
|
||||||
|
<strong>{{ $t('prompts.size') }}:</strong> {{ humanSize }}
|
||||||
|
</div>
|
||||||
|
<div class="share__box__element share__box__center">
|
||||||
|
<a target="_blank" :href="link" class="button button--flat">{{ $t('buttons.download') }}</a>
|
||||||
|
</div>
|
||||||
|
<div class="share__box__element share__box__center">
|
||||||
<qrcode-vue :value="fullLink" size="200" level="M"></qrcode-vue>
|
<qrcode-vue :value="fullLink" size="200" level="M"></qrcode-vue>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
<div v-if="file.isDir" class="share__box share__box__items">
|
||||||
|
<div class="share__box__header" v-if="file.isDir">
|
||||||
|
{{ $t('files.files') }}
|
||||||
|
</div>
|
||||||
|
<div id="listing" class="list">
|
||||||
|
<div class="item" v-for="(item) in file.items.slice(0, this.showLimit)" :key="base64(item.name)">
|
||||||
|
<div>
|
||||||
|
<i class="material-icons">{{ item.isDir ? 'folder' : (item.type==='image') ? 'insert_photo' : 'insert_drive_file' }}</i>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p class="name">{{ item.name }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-if="file.items.length > showLimit" class="item">
|
||||||
|
<div>
|
||||||
|
<p class="name"> + {{ file.items.length - showLimit }} </p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { share as api } from '@/api'
|
import { share as api } from '@/api'
|
||||||
import { baseURL } from '@/utils/constants'
|
import { baseURL } from '@/utils/constants'
|
||||||
|
import filesize from 'filesize'
|
||||||
|
import moment from 'moment'
|
||||||
import QrcodeVue from 'qrcode.vue'
|
import QrcodeVue from 'qrcode.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -34,7 +61,8 @@ export default {
|
||||||
data: () => ({
|
data: () => ({
|
||||||
loaded: false,
|
loaded: false,
|
||||||
notFound: false,
|
notFound: false,
|
||||||
file: null
|
file: null,
|
||||||
|
showLimit: 500
|
||||||
}),
|
}),
|
||||||
watch: {
|
watch: {
|
||||||
'$route': 'fetchData'
|
'$route': 'fetchData'
|
||||||
|
@ -52,8 +80,21 @@ export default {
|
||||||
fullLink: function () {
|
fullLink: function () {
|
||||||
return window.location.origin + this.link
|
return window.location.origin + this.link
|
||||||
},
|
},
|
||||||
|
humanSize: function () {
|
||||||
|
if (this.file.isDir) {
|
||||||
|
return this.file.items.length
|
||||||
|
}
|
||||||
|
|
||||||
|
return filesize(this.file.size)
|
||||||
|
},
|
||||||
|
humanTime: function () {
|
||||||
|
return moment(this.file.modified).fromNow()
|
||||||
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
base64: function (name) {
|
||||||
|
return window.btoa(unescape(encodeURIComponent(name)))
|
||||||
|
},
|
||||||
fetchData: async function () {
|
fetchData: async function () {
|
||||||
try {
|
try {
|
||||||
this.file = await api.getHash(this.hash)
|
this.file = await api.getHash(this.hash)
|
||||||
|
|
|
@ -28,7 +28,7 @@ var withHashFile = func(fn handleFunc) handleFunc {
|
||||||
Fs: d.user.Fs,
|
Fs: d.user.Fs,
|
||||||
Path: link.Path,
|
Path: link.Path,
|
||||||
Modify: d.user.Perm.Modify,
|
Modify: d.user.Perm.Modify,
|
||||||
Expand: false,
|
Expand: true,
|
||||||
Checker: d,
|
Checker: d,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -54,7 +54,15 @@ func ifPathWithName(r *http.Request) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
var publicShareHandler = withHashFile(func(w http.ResponseWriter, r *http.Request, d *data) (int, error) {
|
var publicShareHandler = withHashFile(func(w http.ResponseWriter, r *http.Request, d *data) (int, error) {
|
||||||
return renderJSON(w, r, d.raw)
|
file := d.raw.(*files.FileInfo)
|
||||||
|
|
||||||
|
if file.IsDir {
|
||||||
|
file.Listing.Sorting = files.Sorting{By: "name", Asc: false}
|
||||||
|
file.Listing.ApplySort()
|
||||||
|
return renderJSON(w, r, file)
|
||||||
|
}
|
||||||
|
|
||||||
|
return renderJSON(w, r, file)
|
||||||
})
|
})
|
||||||
|
|
||||||
var publicDlHandler = withHashFile(func(w http.ResponseWriter, r *http.Request, d *data) (int, error) {
|
var publicDlHandler = withHashFile(func(w http.ResponseWriter, r *http.Request, d *data) (int, error) {
|
||||||
|
|
|
@ -116,6 +116,7 @@ func addFile(ar archiver.Writer, d *data, path, commonPath string) error {
|
||||||
}
|
}
|
||||||
defer file.Close()
|
defer file.Close()
|
||||||
|
|
||||||
|
if path != commonPath {
|
||||||
filename := strings.TrimPrefix(path, commonPath)
|
filename := strings.TrimPrefix(path, commonPath)
|
||||||
filename = strings.TrimPrefix(filename, "/")
|
filename = strings.TrimPrefix(filename, "/")
|
||||||
err = ar.Write(archiver.File{
|
err = ar.Write(archiver.File{
|
||||||
|
@ -128,6 +129,7 @@ func addFile(ar archiver.Writer, d *data, path, commonPath string) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if info.IsDir() {
|
if info.IsDir() {
|
||||||
names, err := file.Readdirnames(0)
|
names, err := file.Readdirnames(0)
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
@ -122,7 +123,7 @@ var resourcePostPutHandler = withUser(func(w http.ResponseWriter, r *http.Reques
|
||||||
}
|
}
|
||||||
|
|
||||||
err := d.RunHook(func() error {
|
err := d.RunHook(func() error {
|
||||||
dir, _ := filepath.Split(r.URL.Path)
|
dir, _ := path.Split(r.URL.Path)
|
||||||
err := d.user.Fs.MkdirAll(dir, 0775)
|
err := d.user.Fs.MkdirAll(dir, 0775)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -196,7 +197,8 @@ var resourcePatchHandler = withUser(func(w http.ResponseWriter, r *http.Request,
|
||||||
if !d.user.Perm.Rename {
|
if !d.user.Perm.Rename {
|
||||||
return errors.ErrPermissionDenied
|
return errors.ErrPermissionDenied
|
||||||
}
|
}
|
||||||
dst = filepath.Clean("/" + dst)
|
src = path.Clean("/" + src)
|
||||||
|
dst = path.Clean("/" + dst)
|
||||||
|
|
||||||
return d.user.Fs.Rename(src, dst)
|
return d.user.Fs.Rename(src, dst)
|
||||||
default:
|
default:
|
||||||
|
@ -221,20 +223,20 @@ func checkParent(src, dst string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func addVersionSuffix(path string, fs afero.Fs) string {
|
func addVersionSuffix(source string, fs afero.Fs) string {
|
||||||
counter := 1
|
counter := 1
|
||||||
dir, name := filepath.Split(path)
|
dir, name := path.Split(source)
|
||||||
ext := filepath.Ext(name)
|
ext := filepath.Ext(name)
|
||||||
base := strings.TrimSuffix(name, ext)
|
base := strings.TrimSuffix(name, ext)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
if _, err := fs.Stat(path); err != nil {
|
if _, err := fs.Stat(source); err != nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
renamed := fmt.Sprintf("%s(%d)%s", base, counter, ext)
|
renamed := fmt.Sprintf("%s(%d)%s", base, counter, ext)
|
||||||
path = filepath.ToSlash(dir) + renamed
|
source = path.Join(dir, renamed)
|
||||||
counter++
|
counter++
|
||||||
}
|
}
|
||||||
|
|
||||||
return path
|
return source
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue