laravel-vue-file-share/resources/js/Components/custom/DownloadButton.vue

144 lines
4.3 KiB
Vue

<script setup>
import { ArrowDownTrayIcon } from "@heroicons/vue/24/outline";
import { usePage } from "@inertiajs/vue3";
import { onMounted, ref } from "vue";
const page = usePage();
// define props
const props = defineProps({
getall: {
type: Boolean,
default: false,
required: false,
},
selected: {
type: Array,
required: false,
},
});
const isShared = ref(false);
// determine whether this is a shared folder or not
onMounted(() => {
const regex = new RegExp("shared.*", "i");
const shared = regex.test(page.url);
if (shared) isShared.value = true;
});
// define download function
const download = () => {
// do nothing if nothing selected
if (!props.getall && props.selected.length === 0) return;
// create a URL parameter string based on conditions
const parameters = new URLSearchParams();
// append value of all
parameters.append("all", props.getall);
// append selected Id's
props.selected.forEach((selectedFile) => {
parameters.append("Ids[]", selectedFile);
});
// then append parent_id (current directory)
parameters.append("parent_id", page.props.folder.id);
// define opts
const opts = {
"Content-Type": "application/json",
Accept: "application/json",
};
// fetch download link
fetch(route("file.download") + `?${parameters.toString()}`, opts)
// then get response
.then((res) => {
return res.json();
})
// then get the json
.then((json) => {
// if response contains no link, return - shouldn't be happening
if (!json.url) return;
// else create a link to the document for download
const link = document.createElement("a");
link.href = json.url;
link.download = json.filename;
// then access it
link.click();
});
};
// define downloadShared function
const downloadShared = () => {
// do nothing if nothing selected
if (!props.getall && props.selected.length === 0) return;
// create a URL parameter string based on conditions
const parameters = new URLSearchParams();
// append value of all
parameters.append("all", props.getall);
// append selected Id's
props.selected.forEach((selectedFile) => {
parameters.append("Ids[]", selectedFile);
});
// then append parent_id (current directory) (if one exists)
if (page.props.folder) parameters.append("parent_id", page.props.folder.id);
// define opts
const opts = {
"Content-Type": "application/json",
Accept: "application/json",
};
let dlLink = "";
// determine via URL if this page is shared-with-*
const regex1 = new RegExp("shared-with.*", "i");
const sharedWith = regex1.test(page.url);
if (sharedWith) {
dlLink = route("file.downloadSharedWith");
} else {
// determine via URL if this page is shared-by-*
const regex2 = new RegExp("shared-by.*", "i");
const sharedBy = regex2.test(page.url);
if (sharedBy) {
dlLink = route("file.downloadSharedBy");
}
}
// fetch download link
fetch(dlLink + `?${parameters.toString()}`, opts)
// then get response
.then((res) => {
return res.json();
})
// then get the json
.then((json) => {
// if response contains no link, return - shouldn't be happening
if (!json.url) return;
// else create a link to the document for download
const link = document.createElement("a");
link.href = json.url;
link.download = json.filename;
// then access it
link.click();
});
};
</script>
<template>
<button
v-if="isShared"
@click="downloadShared()"
class="border-gray-700 border px-3 py-2 rounded hover:border-sky-600 hover:bg-sky-600 flex flex justify-center items-center gap-2"
>
<ArrowDownTrayIcon class="h-5 w-5" aria-hidden="true" /> Download
</button>
<button
v-else
@click="download()"
class="border-gray-700 border px-3 py-2 rounded hover:border-sky-600 hover:bg-sky-600 flex flex justify-center items-center gap-2"
>
<ArrowDownTrayIcon class="h-5 w-5" aria-hidden="true" /> Download
</button>
</template>