feat: add option to copy download links from shares (#2442)

This commit is contained in:
Yeicor 2023-05-01 13:07:01 +02:00 committed by GitHub
parent 1a5b999545
commit a4ef02a47b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 51 additions and 3 deletions

View File

@ -32,6 +32,16 @@
<i class="material-icons">content_paste</i> <i class="material-icons">content_paste</i>
</button> </button>
</td> </td>
<td class="small" v-if="hasDownloadLink()">
<button
class="action copy-clipboard"
:data-clipboard-text="buildDownloadLink(link)"
:aria-label="$t('buttons.copyDownloadLinkToClipboard')"
:title="$t('buttons.copyDownloadLinkToClipboard')"
>
<i class="material-icons">content_paste_go</i>
</button>
</td>
<td class="small"> <td class="small">
<button <button
class="action" class="action"
@ -117,7 +127,7 @@
<script> <script>
import { mapState, mapGetters } from "vuex"; import { mapState, mapGetters } from "vuex";
import { share as api } from "@/api"; import { share as api, pub as pub_api } from "@/api";
import moment from "moment"; import moment from "moment";
import Clipboard from "clipboard"; import Clipboard from "clipboard";
@ -215,6 +225,14 @@ export default {
buildLink(share) { buildLink(share) {
return api.getShareURL(share); return api.getShareURL(share);
}, },
hasDownloadLink() {
return (
this.selected.length === 1 && !this.req.items[this.selected[0]].isDir
);
},
buildDownloadLink(share) {
return pub_api.getDownloadURL(share);
},
sort() { sort() {
this.links = this.links.sort((a, b) => { this.links = this.links.sort((a, b) => {
if (a.expire === 0) return -1; if (a.expire === 0) return -1;

View File

@ -5,6 +5,7 @@
"copy": "Copy", "copy": "Copy",
"copyFile": "Copy file", "copyFile": "Copy file",
"copyToClipboard": "Copy to clipboard", "copyToClipboard": "Copy to clipboard",
"copyDownloadLinkToClipboard": "Copy download link to clipboard",
"create": "Create", "create": "Create",
"delete": "Delete", "delete": "Delete",
"download": "Download", "download": "Download",

View File

@ -10,6 +10,15 @@
@action="download" @action="download"
:counter="selectedCount" :counter="selectedCount"
/> />
<button
v-if="isSingleFile()"
class="action copy-clipboard"
:data-clipboard-text="linkSelected()"
:aria-label="$t('buttons.copyDownloadLinkToClipboard')"
:title="$t('buttons.copyDownloadLinkToClipboard')"
>
<i class="material-icons">content_paste</i>
</button>
<action <action
icon="check_circle" icon="check_circle"
:label="$t('buttons.selectMultiple')" :label="$t('buttons.selectMultiple')"
@ -182,6 +191,7 @@ import Breadcrumbs from "@/components/Breadcrumbs";
import Errors from "@/views/Errors"; import Errors from "@/views/Errors";
import QrcodeVue from "qrcode.vue"; import QrcodeVue from "qrcode.vue";
import Item from "@/components/files/ListingItem"; import Item from "@/components/files/ListingItem";
import Clipboard from "clipboard";
export default { export default {
name: "share", name: "share",
@ -200,6 +210,7 @@ export default {
attemptedPasswordLogin: false, attemptedPasswordLogin: false,
hash: null, hash: null,
token: null, token: null,
clip: null,
}), }),
watch: { watch: {
$route: function () { $route: function () {
@ -215,13 +226,18 @@ export default {
}, },
mounted() { mounted() {
window.addEventListener("keydown", this.keyEvent); window.addEventListener("keydown", this.keyEvent);
this.clip = new Clipboard(".copy-clipboard");
this.clip.on("success", () => {
this.$showSuccess(this.$t("success.linkCopied"));
});
}, },
beforeDestroy() { beforeDestroy() {
window.removeEventListener("keydown", this.keyEvent); window.removeEventListener("keydown", this.keyEvent);
this.clip.destroy();
}, },
computed: { computed: {
...mapState(["req", "loading", "multiple", "selected"]), ...mapState(["req", "loading", "multiple", "selected"]),
...mapGetters(["selectedCount", "selectedCount"]), ...mapGetters(["selectedCount"]),
icon: function () { icon: function () {
if (this.req.isDir) return "folder"; if (this.req.isDir) return "folder";
if (this.req.type === "image") return "insert_photo"; if (this.req.type === "image") return "insert_photo";
@ -300,8 +316,13 @@ export default {
toggleMultipleSelection() { toggleMultipleSelection() {
this.$store.commit("multiple", !this.multiple); this.$store.commit("multiple", !this.multiple);
}, },
isSingleFile: function () {
return (
this.selectedCount === 1 && !this.req.items[this.selected[0]].isDir
);
},
download() { download() {
if (this.selectedCount === 1 && !this.req.items[this.selected[0]].isDir) { if (this.isSingleFile()) {
api.download( api.download(
null, null,
this.hash, this.hash,
@ -326,6 +347,14 @@ export default {
}, },
}); });
}, },
linkSelected: function () {
return this.isSingleFile()
? api.getDownloadURL({
hash: this.hash,
path: this.req.items[this.selected[0]].path,
})
: "";
},
}, },
}; };
</script> </script>