From 18193778971e27d18b5a35df8c2d0e2953b48111 Mon Sep 17 00:00:00 2001 From: Ramires Viana <59319979+ramiresviana@users.noreply.github.com> Date: Tue, 16 Feb 2021 15:39:11 +0000 Subject: [PATCH] feat: improved sharing prompt --- frontend/public/themes/dark.css | 4 +- frontend/src/components/prompts/Share.vue | 172 +++++++++++++--------- frontend/src/css/_share.css | 7 +- frontend/src/css/dashboard.css | 12 ++ http/share.go | 12 -- 5 files changed, 116 insertions(+), 91 deletions(-) diff --git a/frontend/public/themes/dark.css b/frontend/public/themes/dark.css index 9a5be1f7..2a70351c 100644 --- a/frontend/public/themes/dark.css +++ b/frontend/public/themes/dark.css @@ -119,8 +119,8 @@ nav > div { .dashboard p label { color: var(--textPrimary); } -.card#share ul li input, -.card#share ul li select, +.card#share input, +.card#share select, .input { background: var(--surfaceSecondary); color: var(--textPrimary); diff --git a/frontend/src/components/prompts/Share.vue b/frontend/src/components/prompts/Share.vue index 043847d8..f4163975 100644 --- a/frontend/src/components/prompts/Share.vue +++ b/frontend/src/components/prompts/Share.vue @@ -4,61 +4,82 @@ <h2>{{ $t('buttons.share') }}</h2> </div> - <div class="card-content"> - <ul> + <template v-if="listing"> + <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"> - <a :href="buildLink(link.hash)" target="_blank"> - <template v-if="link.expire !== 0">{{ humanTime(link.expire) }}</template> - <template v-else>{{ $t('permanent') }}</template> - </a> + <tr v-for="link in links" :key="link.hash"> + <td>{{ link.hash }}</td> + <td> + <template v-if="link.expire !== 0">{{ humanTime(link.expire) }}</template> + <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" - @click="deleteLink($event, link)" - :aria-label="$t('buttons.delete')" - :title="$t('buttons.delete')"><i class="material-icons">delete</i></button> + <div class="card-action"> + <button class="button button--flat button--grey" + @click="$store.commit('closeHovers')" + :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" - :data-clipboard-text="buildLink(link.hash)" - :aria-label="$t('buttons.copyToClipboard')" - :title="$t('buttons.copyToClipboard')"><i class="material-icons">content_paste</i></button> - </li> + <template v-else> + <div class="card-content"> + <p>{{ $t('settings.shareDuration') }}</p> + <div class="input-group input"> + <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> - <input type="password" :placeholder="$t('prompts.optionalPassword')" v-model="passwordPermalink"> - <a @click="getPermalink" :aria-label="$t('buttons.permalink')">{{ $t('buttons.permalink') }}</a> - </div> - </li> - - <li> - <input v-focus - type="number" - max="2147483647" - 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 class="card-action"> + <button class="button button--flat button--grey" + @click="() => switchListing()" + :aria-label="$t('buttons.cancel')" + :title="$t('buttons.cancel')">{{ $t('buttons.cancel') }}</button> + <button class="button button--flat button--blue" + @click="submit" + :aria-label="$t('buttons.share')" + :title="$t('buttons.share')">{{ $t('buttons.share') }}</button> + </div> + </template> </div> </template> @@ -75,11 +96,10 @@ export default { return { time: '', unit: 'hours', - hasPermanent: false, links: [], clip: null, password: '', - passwordPermalink: '' + listing: true } }, computed: { @@ -104,11 +124,8 @@ export default { this.links = links this.sort() - for (let link of this.links) { - if (link.expire === 0) { - this.hasPermanent = true - break - } + if (this.links.length == 0) { + this.listing = false } } catch (e) { this.$showError(e) @@ -125,22 +142,25 @@ export default { }, methods: { submit: async function () { - if (!this.time) return + let isPermanent = !this.time || this.time == 0 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.sort() - } catch (e) { - this.$showError(e) - } - }, - getPermalink: async function () { - try { - const res = await api.create(this.url, this.passwordPermalink) - this.links.push(res) - this.sort() - this.hasPermanent = true + + this.time = '' + this.unit = 'hours' + this.password = '' + + this.listing = true } catch (e) { this.$showError(e) } @@ -149,8 +169,11 @@ export default { event.preventDefault() try { await api.remove(link.hash) - if (link.expire === 0) this.hasPermanent = false this.links = this.links.filter(item => item.hash !== link.hash) + + if (this.links.length == 0) { + this.listing = false + } } catch (e) { this.$showError(e) } @@ -167,6 +190,13 @@ export default { if (b.expire === 0) return 1 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 } } } diff --git a/frontend/src/css/_share.css b/frontend/src/css/_share.css index c043a73c..a5f2d35f 100644 --- a/frontend/src/css/_share.css +++ b/frontend/src/css/_share.css @@ -70,9 +70,4 @@ padding: .5em; text-align: center; animation: .2s opac forwards; -} - -.share__promt__card { - max-width: max-content !important; - width: auto !important; -} +} \ No newline at end of file diff --git a/frontend/src/css/dashboard.css b/frontend/src/css/dashboard.css index b29e907f..52a8d41e 100644 --- a/frontend/src/css/dashboard.css +++ b/frontend/src/css/dashboard.css @@ -226,6 +226,18 @@ table tr>*:last-child { opacity: 1; } +.card#share .input-group { + display: flex; +} + +.card#share .input-group * { + border: none; +} + +.card#share .input-group input { + flex: 1; +} + .overlay { background-color: rgba(0, 0, 0, 0.5); position: fixed; diff --git a/http/share.go b/http/share.go index 9ee28587..d813500e 100644 --- a/http/share.go +++ b/http/share.go @@ -6,7 +6,6 @@ import ( "encoding/json" "fmt" "net/http" - "path" "sort" "strconv" "strings" @@ -91,17 +90,6 @@ var sharePostHandler = withPermShare(func(w http.ResponseWriter, r *http.Request 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) _, err := rand.Read(bytes) if err != nil {