Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26,335 changes: 26,256 additions & 79 deletions package-lock.json

Large diffs are not rendered by default.

13 changes: 8 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "org.vechain.sync2",
"version": "2.0.3",
"version": "2.0.4",
"description": "VeChain Sync2",
"productName": "Sync2",
"cordovaId": "org.vechain.sync2",
Expand All @@ -10,27 +10,30 @@
"scripts": {
"lint": "eslint --ext .js,.ts,.vue ./",
"test": "echo \"No test specified\" && exit 0",
"install": "electron-rebuild"
"install": "electron-rebuild",
"web_mode": "quasar dev",
"electron_mode": "quasar dev -m electron"
},
"dependencies": {
"electron-context-menu": "^2.5.0",
"electron-updater": "^4.3.8",
"ipfs-http-client": "^56.0.3",
"node-hid": "^2.1.1"
},
"devDependencies": {
"@electron/remote": "^1.0.4",
"@ledgerhq/hw-transport-node-hid-noevents": "^5.46.0",
"@ledgerhq/hw-transport-webhid": "^5.46.0",
"@types/ledgerhq__hw-transport": "^4.21.3",
"@vechain/hw-app-vet": "^0.2.0",
"@electron/remote": "^1.0.4",
"@quasar/app": "^1.9.6",
"@quasar/extras": "^1.9.13",
"@types/color": "^3.0.1",
"@types/ledgerhq__hw-transport": "^4.21.3",
"@types/node": "^10.17.15",
"@typescript-eslint/eslint-plugin": "^2.17.0",
"@typescript-eslint/parser": "^2.17.0",
"@vechain/connex-driver": "^2.0.10",
"@vechain/connex-framework": "^2.0.10",
"@vechain/hw-app-vet": "^0.2.0",
"@vechain/picasso": "^2.0.1",
"asmcrypto.js": "^2.3.2",
"axios": "^0.21.1",
Expand Down
6 changes: 5 additions & 1 deletion src/boot/services/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ import * as Blockchain from './blockchain'
import * as Config from './config'
import * as Wallet from './wallet'
import * as Activity from './activity'
import * as IPFS from './ipfs'
import { groupBy } from 'src/utils/array'

type Service = {
bc: ReturnType<typeof Blockchain.build>
config: ReturnType<typeof Config.build>
wallet: ReturnType<typeof Wallet.build>
activity: ReturnType<typeof Activity.build>
ipfs: ReturnType<typeof IPFS.build>
}

declare module 'vue/types/vue' {
Expand All @@ -25,6 +27,7 @@ export default boot(async ({ Vue }) => {
const config = Config.build(storage)
const wallet = Wallet.build(storage)
const activity = Activity.build(storage)
const ipfs = IPFS.build()

const getActiveNodes = async () => {
const [all, activeMap] = await Promise.all([config.node.all(), config.node.activeMap()])
Expand Down Expand Up @@ -59,7 +62,8 @@ export default boot(async ({ Vue }) => {
bc,
config,
wallet,
activity
activity,
ipfs
}
}
}
Expand Down
42 changes: 42 additions & 0 deletions src/boot/services/ipfs/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { create } from 'ipfs-http-client'

export function build() {
return {
async uploadFileToIpfs(fileInBase64: string) {
const client = create({ protocol: 'https', host: 'ipfs.infura.io', port: 5001, apiPath: '/api/v0' })
const cid = await client.add(fileInBase64)
const url = `https://ipfs.infura.io/ipfs/${cid.path}`
return { url, cid }
},

async getInfoFromIPFS(ipfsPath: string) {
const responseProxy = await fetch(ipfsPath)
const response = await fetch(responseProxy.url)

const reader = response.body?.getReader()
let receivedLength = 0
const chunks = []
if (reader) {
while (true) {
const { done, value } = await reader.read()
if (done) {
break
}
if (value) {
chunks.push(value)
receivedLength += value?.length
}
}
}

const chunksAll = new Uint8Array(receivedLength)
let position = 0
for (const chunk of chunks) {
chunksAll.set(chunk, position)
position += chunk.length
}
const base64String = new TextDecoder('utf-8').decode(chunksAll)
return base64String
}
}
}
34 changes: 34 additions & 0 deletions src/css/app.sass
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,37 @@ body

img
pointer-events: none

.uploadLabel
border: 1px solid #ccc
display: inline-block
padding: 7px 15px
cursor: pointer
border-radius: 5px


.uploadLabelBlue
border: 1px solid #ccc
display: inline-block
padding: 7px 15px
cursor: pointer
border-radius: 5px
background-color: blue
color: #ffffff

.uploadButton
display: none

.center-upload
display: flex
flex-direction: column
align-items: center
.wrap-string
max-width: map-get($sizes, "sm")
text-overflow: ellipsis
white-space: nowrap
overflow: hidden

.spinner-upload
display: flex
justify-content: center
14 changes: 14 additions & 0 deletions src/i18n/en-us/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ export default {
action_upgrade: 'Upgrade Now',
action_backup_now: 'Backup Now',
action_settings: 'Settings',
action_ipfs: 'IPFS',
action_activities: 'Activities',
action_create: 'Create Now',
msg_upgrade: 'New version is ready :)',
Expand Down Expand Up @@ -111,6 +112,19 @@ export default {
msg_password_changed: 'Password changed',
action_user_guide: 'User Guide'
},
ipfs: {
title: 'IPFS SERVICE',
action_ipfs_upload: 'Upload file',
action_ipfs_storage: 'Show history uploads',
action_images_list: 'Uploaded files to IPFS',
start_upload: 'Upload file to IPFS',
show_file: 'Show file',
delete_file: 'Delete',
select_file: 'Select file'
},
uploadForm: {
title: 'Upload file'
},
nodes: {
title_add_dialog: 'Add Node',
msg_node_added: 'Node added',
Expand Down
14 changes: 14 additions & 0 deletions src/i18n/zh-cn/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ export default {
action_upgrade: '立即升级',
action_backup_now: '立即备份',
action_settings: '设置',
action_ipfs: 'IPFS SERVICE',
action_activities: '操作记录',
action_create: '现在创建',
msg_upgrade: '新版本已经就绪',
Expand Down Expand Up @@ -110,6 +111,19 @@ export default {
msg_password_changed: '密码已修改',
action_user_guide: '用户指南'
},
ipfs: {
title: 'IPFS SERVICE',
action_ipfs_upload: 'Upload file',
action_ipfs_storage: 'Show history uploads',
action_images_list: 'Uploaded images to IPFS',
start_upload: 'Upload file to IPFS',
show_file: 'Show file',
delete_file: 'Delete',
select_file: 'Select file'
},
uploadForm: {
title: 'Upload file'
},
nodes: {
title_add_dialog: '添加节点',
msg_node_added: '节点已添加',
Expand Down
5 changes: 5 additions & 0 deletions src/models.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,4 +91,9 @@ declare namespace M {
message?: string
messageClass?: string
}

interface IPFSdata {
hash: string,
url: string
}
}
110 changes: 110 additions & 0 deletions src/pages/ImageBoard.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
<template>
<div class="column fit">
<page-toolbar :title="$t('ipfs.action_images_list')" />
<page-content class="col">
<q-list
v-if="listImages.length>0"
padding
>
<template v-for="(item, index) in listImages">

<q-item :key="index">

<span> {{index + 1}} &nbsp;&nbsp;</span>
<q-item-section side>
<q-btn
class="w50 q-mx-auto"
color="primary"
:label="$t('ipfs.show_file')"
@click="getImageData(item.url)"
/>
</q-item-section>
<q-item-section>

<q-item-label
lines="1"
@click="copyCid(item.hash)"
>{{'Click to copy'}}</q-item-label>
<q-item-label class="wrap-string">
<a
v-bind:href="
item.url"
target="_blank"
>{{'Link to IPFS'}}</a>
</q-item-label>
</q-item-section>
<q-item-section>
<q-btn
class="w50 q-mx-auto"
color="deep-orange"
:label="$t('ipfs.delete_file')"
@click="deleteHash(item.hash)"
/>
</q-item-section>

</q-item>

</template>
</q-list>
<img
v-if="base64FileData"
:src="base64FileData"
/>

</page-content>
</div>
</template>
<script lang="ts">
import Vue from 'vue'
import PageContent from 'components/PageContent.vue'
import PageToolbar from 'components/PageToolbar.vue'
import ImageWidget from 'pages/ImageWidget.vue'

export default Vue.extend({
components: { PageContent, PageToolbar },
data: () => {
return {
activeSymbols: null as string[] | null,
base64FileData: '',
cids: []
}
},
methods: {
async getImageData(pathToIpfs: string) {
try {
await this.$dialog<string>({ component: ImageWidget, pathToImageIpfs: pathToIpfs })
} catch { }
},
copyCid(cid: string) {
navigator.clipboard.writeText(cid)
alert('Copied the CID hash: ' + cid)
},
deleteHash(hash: string) {
this.cids = this.cids.filter(cid => cid !== hash)
localStorage.setItem('CID', JSON.stringify(this.cids))
alert('You deleted hash locally only, the file stored in IPFS as usual')
}
},
asyncComputed: {

listImages: {
async get(): Promise<M.IPFSdata[]> {
const images: M.IPFSdata[] = []
const cidsStr = localStorage.getItem('CID')
if (cidsStr) {
this.cids = JSON.parse(cidsStr) || []
this.cids.reverse().map(cid => images.push({ hash: cid, url: `https://ipfs.infura.io/ipfs/${cid}` }))
}
return Promise.resolve(images)
},
default: []
}
},
async beforeDestroy() {
if (this.activeSymbols) {
await this.$svc.config.token.saveActiveSymbols(this.activeSymbols)
}
}

})
</script>
Loading