feat: improved sharing prompt
parent
a809404ce1
commit
1819377897
|
@ -119,8 +119,8 @@ nav > div {
|
||||||
.dashboard p label {
|
.dashboard p label {
|
||||||
color: var(--textPrimary);
|
color: var(--textPrimary);
|
||||||
}
|
}
|
||||||
.card#share ul li input,
|
.card#share input,
|
||||||
.card#share ul li select,
|
.card#share select,
|
||||||
.input {
|
.input {
|
||||||
background: var(--surfaceSecondary);
|
background: var(--surfaceSecondary);
|
||||||
color: var(--textPrimary);
|
color: var(--textPrimary);
|
||||||
|
|
|
@ -4,61 +4,82 @@
|
||||||
<h2>{{ $t('buttons.share') }}</h2>
|
<h2>{{ $t('buttons.share') }}</h2>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card-content">
|
<template v-if="listing">
|
||||||
<ul>
|
<div class="card-content">
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th>#</th>
|
||||||
|
<th>{{ $t('settings.shareDuration') }}</th>
|
||||||
|
<th></th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
|
||||||
<li v-for="link in links" :key="link.hash">
|
<tr v-for="link in links" :key="link.hash">
|
||||||
<a :href="buildLink(link.hash)" target="_blank">
|
<td>{{ link.hash }}</td>
|
||||||
<template v-if="link.expire !== 0">{{ humanTime(link.expire) }}</template>
|
<td>
|
||||||
<template v-else>{{ $t('permanent') }}</template>
|
<template v-if="link.expire !== 0">{{ humanTime(link.expire) }}</template>
|
||||||
</a>
|
<template v-else>{{ $t('permanent') }}</template>
|
||||||
|
</td>
|
||||||
|
<td class="small">
|
||||||
|
<button class="action copy-clipboard"
|
||||||
|
:data-clipboard-text="buildLink(link.hash)"
|
||||||
|
:aria-label="$t('buttons.copyToClipboard')"
|
||||||
|
:title="$t('buttons.copyToClipboard')"><i class="material-icons">content_paste</i></button>
|
||||||
|
</td>
|
||||||
|
<td class="small">
|
||||||
|
<button class="action"
|
||||||
|
@click="deleteLink($event, link)"
|
||||||
|
:aria-label="$t('buttons.delete')"
|
||||||
|
:title="$t('buttons.delete')"><i class="material-icons">delete</i></button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
<button class="action"
|
<div class="card-action">
|
||||||
@click="deleteLink($event, link)"
|
<button class="button button--flat button--grey"
|
||||||
:aria-label="$t('buttons.delete')"
|
@click="$store.commit('closeHovers')"
|
||||||
:title="$t('buttons.delete')"><i class="material-icons">delete</i></button>
|
:aria-label="$t('buttons.close')"
|
||||||
|
:title="$t('buttons.close')">{{ $t('buttons.close') }}</button>
|
||||||
|
<button class="button button--flat button--blue"
|
||||||
|
@click="() => switchListing()"
|
||||||
|
:aria-label="$t('buttons.new')"
|
||||||
|
:title="$t('buttons.new')">{{ $t('buttons.new') }}</button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
<button class="action copy-clipboard"
|
<template v-else>
|
||||||
:data-clipboard-text="buildLink(link.hash)"
|
<div class="card-content">
|
||||||
:aria-label="$t('buttons.copyToClipboard')"
|
<p>{{ $t('settings.shareDuration') }}</p>
|
||||||
:title="$t('buttons.copyToClipboard')"><i class="material-icons">content_paste</i></button>
|
<div class="input-group input">
|
||||||
</li>
|
<input v-focus
|
||||||
|
type="number"
|
||||||
|
max="2147483647"
|
||||||
|
min="1"
|
||||||
|
@keyup.enter="submit"
|
||||||
|
v-model.trim="time">
|
||||||
|
<select class="right" v-model="unit" :aria-label="$t('time.unit')">
|
||||||
|
<option value="seconds">{{ $t('time.seconds') }}</option>
|
||||||
|
<option value="minutes">{{ $t('time.minutes') }}</option>
|
||||||
|
<option value="hours">{{ $t('time.hours') }}</option>
|
||||||
|
<option value="days">{{ $t('time.days') }}</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<p>{{ $t('prompts.optionalPassword') }}</p>
|
||||||
|
<input class="input input--block" type="password" v-model.trim="password">
|
||||||
|
</div>
|
||||||
|
|
||||||
<li v-if="!hasPermanent">
|
<div class="card-action">
|
||||||
<div>
|
<button class="button button--flat button--grey"
|
||||||
<input type="password" :placeholder="$t('prompts.optionalPassword')" v-model="passwordPermalink">
|
@click="() => switchListing()"
|
||||||
<a @click="getPermalink" :aria-label="$t('buttons.permalink')">{{ $t('buttons.permalink') }}</a>
|
:aria-label="$t('buttons.cancel')"
|
||||||
</div>
|
:title="$t('buttons.cancel')">{{ $t('buttons.cancel') }}</button>
|
||||||
</li>
|
<button class="button button--flat button--blue"
|
||||||
|
@click="submit"
|
||||||
<li>
|
:aria-label="$t('buttons.share')"
|
||||||
<input v-focus
|
:title="$t('buttons.share')">{{ $t('buttons.share') }}</button>
|
||||||
type="number"
|
</div>
|
||||||
max="2147483647"
|
</template>
|
||||||
min="0"
|
|
||||||
@keyup.enter="submit"
|
|
||||||
v-model.trim="time">
|
|
||||||
<select v-model="unit" :aria-label="$t('time.unit')">
|
|
||||||
<option value="seconds">{{ $t('time.seconds') }}</option>
|
|
||||||
<option value="minutes">{{ $t('time.minutes') }}</option>
|
|
||||||
<option value="hours">{{ $t('time.hours') }}</option>
|
|
||||||
<option value="days">{{ $t('time.days') }}</option>
|
|
||||||
</select>
|
|
||||||
<input type="password" :placeholder="$t('prompts.optionalPassword')" v-model="password">
|
|
||||||
<button class="action"
|
|
||||||
@click="submit"
|
|
||||||
:aria-label="$t('buttons.create')"
|
|
||||||
:title="$t('buttons.create')"><i class="material-icons">add</i></button>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="card-action">
|
|
||||||
<button class="button button--flat"
|
|
||||||
@click="$store.commit('closeHovers')"
|
|
||||||
:aria-label="$t('buttons.close')"
|
|
||||||
:title="$t('buttons.close')">{{ $t('buttons.close') }}</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -75,11 +96,10 @@ export default {
|
||||||
return {
|
return {
|
||||||
time: '',
|
time: '',
|
||||||
unit: 'hours',
|
unit: 'hours',
|
||||||
hasPermanent: false,
|
|
||||||
links: [],
|
links: [],
|
||||||
clip: null,
|
clip: null,
|
||||||
password: '',
|
password: '',
|
||||||
passwordPermalink: ''
|
listing: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -104,11 +124,8 @@ export default {
|
||||||
this.links = links
|
this.links = links
|
||||||
this.sort()
|
this.sort()
|
||||||
|
|
||||||
for (let link of this.links) {
|
if (this.links.length == 0) {
|
||||||
if (link.expire === 0) {
|
this.listing = false
|
||||||
this.hasPermanent = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.$showError(e)
|
this.$showError(e)
|
||||||
|
@ -125,22 +142,25 @@ export default {
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
submit: async function () {
|
submit: async function () {
|
||||||
if (!this.time) return
|
let isPermanent = !this.time || this.time == 0
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const res = await api.create(this.url, this.password, this.time, this.unit)
|
let res = null
|
||||||
|
|
||||||
|
if (isPermanent) {
|
||||||
|
res = await api.create(this.url, this.password)
|
||||||
|
} else {
|
||||||
|
res = await api.create(this.url, this.password, this.time, this.unit)
|
||||||
|
}
|
||||||
|
|
||||||
this.links.push(res)
|
this.links.push(res)
|
||||||
this.sort()
|
this.sort()
|
||||||
} catch (e) {
|
|
||||||
this.$showError(e)
|
this.time = ''
|
||||||
}
|
this.unit = 'hours'
|
||||||
},
|
this.password = ''
|
||||||
getPermalink: async function () {
|
|
||||||
try {
|
this.listing = true
|
||||||
const res = await api.create(this.url, this.passwordPermalink)
|
|
||||||
this.links.push(res)
|
|
||||||
this.sort()
|
|
||||||
this.hasPermanent = true
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.$showError(e)
|
this.$showError(e)
|
||||||
}
|
}
|
||||||
|
@ -149,8 +169,11 @@ export default {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
try {
|
try {
|
||||||
await api.remove(link.hash)
|
await api.remove(link.hash)
|
||||||
if (link.expire === 0) this.hasPermanent = false
|
|
||||||
this.links = this.links.filter(item => item.hash !== link.hash)
|
this.links = this.links.filter(item => item.hash !== link.hash)
|
||||||
|
|
||||||
|
if (this.links.length == 0) {
|
||||||
|
this.listing = false
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.$showError(e)
|
this.$showError(e)
|
||||||
}
|
}
|
||||||
|
@ -167,6 +190,13 @@ export default {
|
||||||
if (b.expire === 0) return 1
|
if (b.expire === 0) return 1
|
||||||
return new Date(a.expire) - new Date(b.expire)
|
return new Date(a.expire) - new Date(b.expire)
|
||||||
})
|
})
|
||||||
|
},
|
||||||
|
switchListing () {
|
||||||
|
if (this.links.length == 0 && !this.listing) {
|
||||||
|
this.$store.commit('closeHovers')
|
||||||
|
}
|
||||||
|
|
||||||
|
this.listing = !this.listing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,9 +70,4 @@
|
||||||
padding: .5em;
|
padding: .5em;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
animation: .2s opac forwards;
|
animation: .2s opac forwards;
|
||||||
}
|
}
|
||||||
|
|
||||||
.share__promt__card {
|
|
||||||
max-width: max-content !important;
|
|
||||||
width: auto !important;
|
|
||||||
}
|
|
|
@ -226,6 +226,18 @@ table tr>*:last-child {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.card#share .input-group {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card#share .input-group * {
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card#share .input-group input {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
.overlay {
|
.overlay {
|
||||||
background-color: rgba(0, 0, 0, 0.5);
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
position: fixed;
|
position: fixed;
|
||||||
|
|
|
@ -6,7 +6,6 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"path"
|
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -91,17 +90,6 @@ var sharePostHandler = withPermShare(func(w http.ResponseWriter, r *http.Request
|
||||||
defer r.Body.Close()
|
defer r.Body.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
if body.Expires == "" {
|
|
||||||
var err error
|
|
||||||
s, err = d.store.Share.GetPermanent(r.URL.Path, d.user.ID)
|
|
||||||
if err == nil {
|
|
||||||
if _, err := w.Write([]byte(path.Join(d.server.BaseURL, "/share/", s.Hash))); err != nil {
|
|
||||||
return http.StatusInternalServerError, err
|
|
||||||
}
|
|
||||||
return 0, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bytes := make([]byte, 6)
|
bytes := make([]byte, 6)
|
||||||
_, err := rand.Read(bytes)
|
_, err := rand.Read(bytes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
Loading…
Reference in New Issue