add(#8): add download button for individual files

This commit is contained in:
Salem Yaslem 2024-09-28 02:43:18 +03:00
parent dc764433ae
commit c8209c5799
3 changed files with 45 additions and 9 deletions

28
app.vue
View File

@ -115,9 +115,11 @@ function stepUp(path: string) {
<TreeView :filesList="filesList" :nav=true></TreeView>
<v-footer class="d-flex w-100 flex-column" style="position: absolute;bottom: 0;">
<div class="d-flex w-100 align-center">
<a href="https://github.com/xlmnxp/extractify.zip" target="_blank" class="text-subtitle-2" style="text-decoration: underline;text-decoration-style: dotted">Open Source Licenses</a>
<a href="https://github.com/xlmnxp/extractify.zip" target="_blank" class="text-subtitle-2"
style="text-decoration: underline;text-decoration-style: dotted">Open Source Licenses</a>
<v-spacer></v-spacer>
<v-btn class="mx-4" icon="mdi-github" variant="plain" size="small" href="https://github.com/xlmnxp/extractify.zip" target="_blank"></v-btn>
<v-btn class="mx-4" icon="mdi-github" variant="plain" size="small"
href="https://github.com/xlmnxp/extractify.zip" target="_blank"></v-btn>
</div>
</v-footer>
</v-navigation-drawer>
@ -162,8 +164,23 @@ function stepUp(path: string) {
<v-list :selected="[selectedPath]">
<v-row no-gutters>
<v-col cols="6" lg="2" md="3" sm="6" v-for="file of filesGridList" style="text-align: center;">
<v-list-item class="ma-2 pa-5 selectable" active-color="light-blue-darken-4" :value="file.path" rounded
@click="selectedPath = file.path">
<v-list-item class="position-relative ma-2 pa-5 selectable" active-color="light-blue-darken-4"
:value="file.path" rounded @click="selectedPath = file.path">
<v-menu v-if="!file.isFolder">
<template v-slot:activator="{ props }">
<v-btn class="position-absolute" style="right: 0; top: 0;" icon="mdi-dots-vertical" variant="text"
v-bind="props"></v-btn>
</template>
<v-list>
<v-list-item title="Download" aria-label="Download" icon="mdi-download"
@click="filesManager.downloadFile(file.path)">
<template v-slot:prepend>
<v-icon icon="mdi-download"></v-icon>
</template>
</v-list-item>
</v-list>
</v-menu>
<file-logo class="mb-2" :file="file" :key="file.path" />
<p>{{ file.name }}</p>
</v-list-item>
@ -190,7 +207,8 @@ function stepUp(path: string) {
<v-card-text class="font-weight-bold">
Extract and Explore compressed files online and securely.
<p class="text-subtitle-2 font-weight-regular text-medium-emphasis">
<v-icon class="mx-auto" size="1em" color="#007B4F">mdi-shield</v-icon> <strong>nothing</strong> leave
<v-icon class="mx-auto" size="1em" color="#007B4F">mdi-shield</v-icon> <strong>nothing</strong>
leave
your browser
</p>
</v-card-text>

View File

@ -5,6 +5,7 @@ import * as Comlink from "comlink";
// @ts-expect-error typescript can't find it when query it with ?worker
import SevenZipWorker from "./worker/7zip-manager?worker";
import { SevenZipManager, iFile } from "./worker/7zip-manager";
import mime from 'mime';
export const videoExtensions = ['mp4', 'avi', 'mov', 'mkv'];
export const imageExtensions = ['jpg', 'jpeg', 'png', 'gif', 'webp'];
@ -74,8 +75,25 @@ export class FilesManager {
return await this.remoteSevenZipManager.generateBlobUrl(JSON.stringify(this.getFile(path)) as any);
}
async getFileContent(path: string) {
async getFileContent(path: string, encoding: "utf8" | "binary" = "utf8") {
if (!this.remoteSevenZipManager) return;
return await this.remoteSevenZipManager.getFileContent(JSON.stringify(this.getFile(path)) as any);
return await this.remoteSevenZipManager.getFileContent(JSON.stringify(this.getFile(path)) as any, encoding);
}
async downloadFile(path: string) {
if (!this.remoteSevenZipManager) return;
const file = this.getFile(path);
const fileContent = await this.getFileContent(path, "binary");
if (!file) return;
const blob = new Blob([fileContent as any], { type: mime.getType(file.extension!) || "application/octet-stream" });
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = file.name;
a.click();
}
}

View File

@ -163,7 +163,7 @@ export class SevenZipManager {
}
// get content from buffer (Experimental)
async getFileContent(file: iFile) {
async getFileContent(file: iFile, encoding: "utf8" | "binary" = "utf8") {
if (!this.sevenZip) return;
file = typeof file === "string" ? JSON.parse(file) : file;
@ -172,7 +172,7 @@ export class SevenZipManager {
this.sevenZip.FS.chmod(file.path, 0o777);
// get file buffer
const buffer = this.sevenZip.FS.readFile(file.path, { encoding: "utf8" });
const buffer = this.sevenZip.FS.readFile(file.path, { encoding: encoding as any });
// remove the file after extract local blob url
this.sevenZip.FS.unlink(file.path);