Last active
October 8, 2023 10:20
-
-
Save calpa/42a9d05ff0f1665e630b64f9e0ee8427 to your computer and use it in GitHub Desktop.
IPFS Uploader
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<template> | |
<div class="mb-4"> | |
<el-input v-model="token" placeholder="API Token" type="password" /> | |
<p class="text-sm"> | |
If you don't have an API Token, you can get it from | |
<a | |
href="https://web3.storage/tokens/" | |
class="text-blue-400" | |
target="_blank" | |
> | |
https://web3.storage/tokens/ | |
</a> | |
</p> | |
</div> | |
<el-tabs v-model="activeTab" type="border-card" @tab-click="handleClick"> | |
<el-tab-pane label="Upload" name="Upload"> | |
<file-pond | |
:disabled="!token" | |
name="file" | |
ref="pond" | |
class-name="my-pond" | |
allow-multiple="true" | |
:files="files" | |
@init="handleFilePondInit" | |
@processfile="handleProcessFile" | |
@processfiles="handleAllFilesProcessed" | |
maxParallelUploads="10" | |
check-validity="true" | |
allow-remove="false" | |
allow-revert="false" | |
/> | |
</el-tab-pane> | |
<el-tab-pane label="List" name="List"> | |
<el-table :data="images" v-loading="loading"> | |
<!-- <el-table-column prop="updated" label="Updated" /> --> | |
<el-table-column prop="cid" label="cid" /> | |
<el-table-column label="Preview"> | |
<!-- <el-table-column prop="name" label="name" /> --> | |
<template #default="scope"> | |
<el-image :src="getImageSrc(scope.row)" fit="contain" /> | |
</template> | |
</el-table-column> | |
<el-table-column label="Operations"> | |
<template #default="scope"> | |
<el-button @click="handleCopy(scope.$index, scope.row)" | |
>Copy</el-button | |
> | |
</template> | |
</el-table-column> | |
</el-table> | |
</el-tab-pane> | |
</el-tabs> | |
<!-- <div>{{ token }}</div> --> | |
</template> | |
<script lang="ts"> | |
import { defineComponent } from "vue"; | |
import vueFilePond, { setOptions } from "vue-filepond"; | |
// Import plugins | |
import FilePondPluginFileValidateType from "filepond-plugin-file-validate-type"; | |
import FilePondPluginImagePreview from "filepond-plugin-image-preview"; | |
// Import styles | |
import "filepond/dist/filepond.min.css"; | |
import "filepond-plugin-image-preview/dist/filepond-plugin-image-preview.min.css"; | |
import { ElAlert, ElMessage } from "element-plus"; | |
import { type TabsPaneContext } from "element-plus"; | |
import axios from "axios"; | |
// Create FilePond component | |
const FilePond = vueFilePond( | |
FilePondPluginFileValidateType, | |
FilePondPluginImagePreview | |
); | |
export default defineComponent({ | |
name: "app", | |
data: function () { | |
return { | |
cids: [], | |
token: "", | |
activeTab: "Upload", | |
loading: true, | |
images: [], | |
}; | |
}, | |
watch: { | |
token(val) { | |
const self = this; | |
setOptions({ | |
server: { | |
url: "https://api.web3.storage", | |
process: ( | |
fieldName, | |
file, | |
metadata, | |
load, | |
error, | |
progress, | |
abort, | |
transfer, | |
options | |
) => { | |
// fieldName is the name of the input field | |
// file is the actual file object to send | |
const formData = new FormData(); | |
formData.append(fieldName, file, file.name); | |
axios | |
.post("https://api.web3.storage/upload", formData, { | |
headers: { | |
"Content-Type": "multipart/form-data", | |
Authorization: `Bearer ${self.token}`, | |
}, | |
}) | |
.then((response) => { | |
load(response.data); | |
}); | |
// Should expose an abort method so the request can be cancelled | |
return { | |
abort: () => { | |
// This function is entered if the user has tapped the cancel button | |
// request.abort(); | |
// Let FilePond know the request has been cancelled | |
abort(); | |
}, | |
}; | |
}, | |
// process: { | |
// url: "./upload", | |
// method: "POST", | |
// headers: { | |
// "Content-Type": "application/x-www-form-urlencoded", | |
// Authorization: `Bearer ${val}`, | |
// }, | |
// }, | |
}, | |
}); | |
}, | |
}, | |
methods: { | |
getImageSrc(row: any) { | |
return `https://w3s.link/ipfs/${row.cid}`; | |
}, | |
handleCopy(index: number, row: any) { | |
// console.log(index, row); | |
const url = `https://w3s.link/ipfs/${row.cid}`; | |
navigator.clipboard.writeText(url); | |
}, | |
async handleClick(tab: TabsPaneContext, event: Event) { | |
if (tab.paneName === "List") { | |
await this.getLatestImages(); | |
} | |
}, | |
async getLatestImages() { | |
const token = this.token; | |
this.loading = true; | |
const { data } = await axios.get( | |
"https://api.web3.storage/user/uploads?size=100", | |
{ | |
headers: { | |
Authorization: `Bearer ${token}`, | |
}, | |
} | |
); | |
this.loading = false; | |
this.images = data; | |
}, | |
handleFilePondInit() { | |
console.log("FilePond has initialized"); | |
// this.$refs.pond.getFiles(); | |
}, | |
handleProcessFile() { | |
console.log("FilePond has processed a file"); | |
}, | |
handleAllFilesProcessed() { | |
ElMessage.success("All files in the list have been processed"); | |
}, | |
}, | |
components: { | |
FilePond, | |
}, | |
}); | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment