· 5 years ago · May 22, 2020, 02:04 PM
1new Vue({
2 el: '#app',
3 data() {
4 return {
5 stampedFilesTableStateIsLoading: false,
6 stampedFilesTableMessage: null,
7
8 newDocument: null,
9 newDocumentIsLoading: false,
10 newDocumentMessage: null,
11
12 ipfs: {
13 connectionSuccess: false,
14 nodeVersion: null,
15 stampedFiles: null
16 }
17 }
18 },
19
20 computed: {
21 stampedFilesCount() {
22 return this.ipfs.stampedFiles ? this.ipfs.stampedFiles.length : 0
23 },
24 stampedFilesPinnedCount() {
25 return this.ipfs.stampedFiles ? this.ipfs.stampedFiles.filter(x => x.pinned).length : 0
26 },
27 stampedFilesStampedCount() {
28 return this.ipfs.stampedFiles ? this.ipfs.stampedFiles.filter(x => x.stamped).length : 0
29 }
30 },
31
32 async mounted() {
33 this.ipfs.connectionSuccess = false
34
35 await this.loadIpfsNodeVersion()
36 await this.loadIpfsStampedFiles()
37 console.log(this.ipfs.stampedFiles)
38
39 this.ipfs.connectionSuccess = true
40 },
41
42 methods: {
43 /** Custom sorting for the stamped files table */
44 stampedFilesTableCustomSort(a, b, key) {
45 if (key === 'pin') return a.pinned && !b.pinned ? 1 : -1
46 else if (key === 'ark') return a.stamped && !b.stamped ? 1 : -1
47 // Let b-table handle the sorting
48 return false
49 },
50
51 /**
52 *
53 * @param {string} route API route
54 * @param {'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE'} [method = 'GET'] HTTP method
55 * @param {object} [body] Request body, will be stringified if object
56 * @param {{ [header: string]: string }} [headers = {}] Request headers
57 * @param {object} [options = {}] Any fetch options to inject
58 * @param {boolean} [isJsonBody = true] Is the request body JSON
59 */
60 apiCall(route, method = 'GET', body, headers = {}, options = {}, isJsonBody = true) {
61 return fetch(route, {
62 method,
63 headers: {
64 ...headers,
65 ...(body && isJsonBody ? { 'content-type': 'application/json' } : {})
66 },
67 body: body ? (isJsonBody ? JSON.stringify(body) : body) : undefined,
68 ...options
69 })
70 .then(async res => {
71 const contentType = res.headers.get('content-type')
72 if (contentType && contentType.indexOf('application/json') !== -1) res.bodyJson = await res.json()
73 return res
74 })
75 .then(res => {
76 console.log(res)
77 if (!res.ok) {
78 console.log(res)
79 throw new Error(res.bodyJson ? res.bodyJson.message : res.statusText)
80 }
81 return res.bodyJson ? res.bodyJson : undefined
82 })
83 },
84
85 async loadIpfsNodeVersion() {
86 this.ipfs.nodeVersion = await this.apiCall('/ipfs/version')
87 },
88 async loadIpfsStampedFiles() {
89 this.stampedFilesTableStateIsLoading = true
90 try {
91 this.ipfs.stampedFiles = await this.apiCall('/ipfs/stampedFiles')
92 } catch (error) {
93 console.error(error)
94 this.stampedFilesTableMessage = error.message
95 } finally {
96 this.stampedFilesTableStateIsLoading = false
97 }
98 },
99
100 async deleteIpfsStampedFile({ cid }) {
101 if (
102 !confirm(
103 `Are you sure you want to delete the files in the directory "/stamped" ` +
104 `having the CID "${cid}" from the IPFS node ?\n\n` +
105 `WARNING: This does not unpin the file from the IPFS node if it is currently pinned. Unpin first.\n` +
106 `It will not remove the CID from the ARK Blockchain if applicable, as it is permanent.`
107 )
108 )
109 return
110
111 this.stampedFilesTableStateIsLoading = true
112
113 try {
114 // Remove the file from the IPFS node
115 await this.apiCall(`/ipfs/stampedFiles/${cid}`, 'DELETE')
116 // Remove the file from the local state
117 this.ipfs.stampedFiles = this.ipfs.stampedFiles.filter(x => x.cid !== cid)
118 this.stampedFilesTableMessage = null
119 } catch (error) {
120 console.error(error)
121 this.stampedFilesTableMessage = error.message
122 } finally {
123 this.stampedFilesTableStateIsLoading = false
124 }
125 },
126
127 async setIpfsStampedFilePinState({ cid, pinned }) {
128 if (
129 !confirm(
130 `Are you sure you want to ${pinned ? 'UNPIN' : 'PIN'} the file ` +
131 `having the CID "${cid}" from the IPFS node ?\n\n` +
132 `WARNING: Pinning is a global action in an IPFS node.\n` +
133 `It may affect a file having the same CID pin state but not in the "/stamped" directory.`
134 )
135 )
136 return
137
138 this.stampedFilesTableStateIsLoading = true
139
140 try {
141 // Toggle the pin state from the IPFS node
142 await this.apiCall(`/ipfs/stampedFiles/${cid}/pinState`, 'PATCH', { newPinState: !pinned })
143 // Toggle the pin state from the local state
144 this.ipfs.stampedFiles[this.ipfs.stampedFiles.findIndex(x => x.cid === cid)].pinned = !pinned
145 this.stampedFilesTableMessage = null
146 } catch (error) {
147 console.error(error)
148 this.stampedFilesTableMessage = error.message
149 } finally {
150 this.stampedFilesTableStateIsLoading = false
151 }
152 },
153
154 async addNewFile() {
155 this.newDocumentIsLoading = true
156 try {
157 const formData = new FormData()
158 formData.append('document', this.newDocument)
159 await this.apiCall(`/ipfs/stampedFiles/`, 'PUT', formData, undefined, undefined, false)
160 this.newDocument = null
161 this.newDocumentMessage = 'Your document was successfully added to the IPFS node.'
162
163 // Reload the files list
164 await this.loadIpfsStampedFiles()
165 this.stampedFilesTableMessage = null
166 } catch (err) {
167 console.error(err)
168 this.newDocumentMessage = err.message
169 } finally {
170 this.newDocumentIsLoading = false
171 }
172 },
173
174 async broadcastCid({ cid }) {
175 if (
176 !confirm(
177 `Are you sure you want to broadcast the IPFS CID "${cid}" to the ARK Blockchain ?\n\n` +
178 `WARNING: This is PERMANENT and cannot be undone. The CID will NOT BE REMOVABLE from the ARK Blockchain.`
179 )
180 )
181 return
182
183 this.stampedFilesTableStateIsLoading = true
184 try {
185 // Broadcast the IPFS CID on the ARK Blockchain
186 // await ark.broadcastIPFSTransaction(cid);
187 await this.apiCall(`/ark/broadcastCid/${cid}`, 'POST')
188 //
189 // await this.apiCall(`/ark/broadcastCid/${cid}`);
190 // Reload the files list
191 await this.loadIpfsStampedFiles()
192 this.stampedFilesTableMessage = null
193 } catch (error) {
194 console.error(error)
195 this.stampedFilesTableMessage = error.message
196 } finally {
197 this.stampedFilesTableStateIsLoading = false
198 }
199 },
200
201 async synchronizeIpfsDb() {
202 if (
203 !confirm(
204 `Are you sure you want to synchronize the IPFS database with the ARK blockchain IPFS CIDs ?\n\n` +
205 `WARNING: This may take some time.`
206 )
207 )
208 return
209
210 this.stampedFilesTableStateIsLoading = true
211 try {
212 // Broadcast the IPFS CID on the ARK Blockchain
213 await this.apiCall('/ipfs/stampedFiles/synchronizeDb', 'POST')
214
215 // Reload the files list
216 await this.loadIpfsStampedFiles()
217 this.stampedFilesTableMessage = null
218 } catch (error) {
219 console.error(error)
220 this.stampedFilesTableMessage = error.message
221 } finally {
222 this.stampedFilesTableStateIsLoading = false
223 }
224 }
225 }
226})