Skip to content

Instantly share code, notes, and snippets.

@calpa
Last active October 8, 2023 10:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save calpa/42a9d05ff0f1665e630b64f9e0ee8427 to your computer and use it in GitHub Desktop.
Save calpa/42a9d05ff0f1665e630b64f9e0ee8427 to your computer and use it in GitHub Desktop.
IPFS Uploader
<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