├── .editorconfig ├── .eslintignore ├── .eslintrc.js ├── .gitignore ├── .postcssrc.js ├── .stylintrc ├── README.md ├── app-icon.png ├── app-splashscreen.png ├── babel.config.js ├── package-lock.json ├── package.json ├── quasar.conf.js ├── quasar.extensions.json ├── src-electron ├── electron-flag.d.ts ├── icons │ ├── icon.icns │ ├── icon.ico │ └── linux-512x512.png └── main-process │ ├── electron-main.dev.js │ └── electron-main.js ├── src ├── App.vue ├── assets │ ├── bg.png │ ├── bg.svg │ ├── man_working_on_computer.svg │ ├── quasar-logo-full.svg │ ├── sad.svg │ └── travel.svg ├── boot │ ├── .gitkeep │ ├── axios.js │ ├── bootstrap.js │ ├── i18n.js │ ├── lightbox.js │ ├── moment.js │ ├── profile.js │ └── storage.js ├── components │ ├── .gitkeep │ ├── FileMenu.vue │ ├── FilesList.vue │ ├── NoteListItem.vue │ ├── NotebookMenu.vue │ ├── NotesList.vue │ ├── Onboarding.vue │ ├── SubmitContent.vue │ └── Uploader.js ├── css │ ├── app.scss │ └── quasar.variables.scss ├── i18n │ ├── en-us │ │ └── index.js │ └── index.js ├── index.template.html ├── layouts │ ├── Empty.vue │ ├── Files.vue │ ├── MyLayout.vue │ ├── Notes.vue │ └── Outside.vue ├── pages │ ├── EditNote.vue │ ├── Error404.vue │ ├── FileBrowser.vue │ ├── Index.vue │ ├── Login.vue │ ├── NotesDashboard.vue │ ├── Profile.vue │ └── outside │ │ ├── Home.vue │ │ ├── MockNoteEdit.vue │ │ └── ViewNote.vue ├── router │ ├── index.js │ └── routes.js ├── services │ ├── balances.js │ ├── encryption.js │ ├── erc20.js │ ├── files.js │ └── posts.js ├── statics │ ├── app-logo-128x128.png │ ├── icons │ │ ├── apple-icon-120x120.png │ │ ├── apple-icon-152x152.png │ │ ├── apple-icon-167x167.png │ │ ├── apple-icon-180x180.png │ │ ├── favicon-16x16.png │ │ ├── favicon-32x32.png │ │ ├── favicon-96x96.png │ │ ├── favicon.ico │ │ ├── icon-128x128.png │ │ ├── icon-192x192.png │ │ ├── icon-256x256.png │ │ ├── icon-384x384.png │ │ ├── icon-512x512.png │ │ ├── ms-icon-144x144.png │ │ └── safari-pinned-tab.svg │ ├── outside │ │ ├── astronaut.svg │ │ ├── galaxy.jpg │ │ ├── leftbox.svg │ │ ├── locked_computer.svg │ │ ├── man_laptop.svg │ │ ├── rightbox.svg │ │ └── woman_server.svg │ └── ux │ │ ├── eth.svg │ │ ├── icons │ │ ├── folder-cloud.svg │ │ ├── home.svg │ │ ├── note.svg │ │ ├── photo.svg │ │ └── share.svg │ │ ├── mountain-climbing.svg │ │ ├── neo.svg │ │ ├── nuls.svg │ │ ├── solana.svg │ │ ├── unlock.svg │ │ ├── verified-woman.svg │ │ └── working-bg.svg └── store │ ├── index.js │ ├── module-example │ ├── actions.js │ ├── getters.js │ ├── index.js │ ├── mutations.js │ └── state.js │ └── store-flag.d.ts └── yarn.lock /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | /dist 2 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | // module.exports = { 2 | // root: true, 3 | 4 | // parserOptions: { 5 | // parser: 'babel-eslint', 6 | // sourceType: 'module' 7 | // }, 8 | 9 | // env: { 10 | // browser: true 11 | // }, 12 | 13 | // extends: [ 14 | // // https://github.com/vuejs/eslint-plugin-vue#priority-a-essential-error-prevention 15 | // // consider switching to `plugin:vue/strongly-recommended` or `plugin:vue/recommended` for stricter rules. 16 | // 'plugin:vue/essential', 17 | // '@vue/standard' 18 | // ], 19 | 20 | // // required to lint *.vue files 21 | // plugins: [ 22 | // 'vue' 23 | // ], 24 | 25 | // globals: { 26 | // 'ga': true, // Google Analytics 27 | // 'cordova': true, 28 | // '__statics': true, 29 | // 'process': true, 30 | // 'Capacitor': true, 31 | // 'chrome': true 32 | // }, 33 | 34 | // // add your custom rules here 35 | // rules: { 36 | // // allow async-await 37 | // 'generator-star-spacing': 'off', 38 | // // allow paren-less arrow functions 39 | // 'arrow-parens': 'off', 40 | // 'one-var': 'off', 41 | 42 | // 'import/first': 'off', 43 | // 'import/named': 'error', 44 | // 'import/namespace': 'error', 45 | // 'import/default': 'error', 46 | // 'import/export': 'error', 47 | // 'import/extensions': 'off', 48 | // 'import/no-unresolved': 'off', 49 | // 'import/no-extraneous-dependencies': 'off', 50 | // 'prefer-promise-reject-errors': 'off', 51 | 52 | // // allow debugger during development only 53 | // 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off' 54 | // } 55 | // } 56 | // http://eslint.org/docs/user-guide/configuring 57 | 58 | module.exports = { 59 | root: true, 60 | parser: 'babel-eslint', 61 | parserOptions: { 62 | sourceType: 'module' 63 | }, 64 | env: { 65 | browser: true, 66 | }, 67 | // https://github.com/standard/standard/blob/master/docs/RULES-en.md 68 | extends: 'standard', 69 | // required to lint *.vue files 70 | plugins: [ 71 | 'html' 72 | ], 73 | // add your custom rules here 74 | 'rules': { 75 | // allow paren-less arrow functions 76 | 'arrow-parens': 0, 77 | // allow async-await 78 | 'generator-star-spacing': 0, 79 | // allow debugger during development 80 | 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0 81 | } 82 | } 83 | 84 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .quasar 2 | .DS_Store 3 | .thumbs.db 4 | node_modules 5 | /dist 6 | /src-cordova/node_modules 7 | /src-cordova/platforms 8 | /src-cordova/plugins 9 | /src-cordova/www 10 | /src-bex/www 11 | /src-bex/js/core 12 | npm-debug.log* 13 | yarn-debug.log* 14 | yarn-error.log* 15 | 16 | # Editor directories and files 17 | .idea 18 | .vscode 19 | *.suo 20 | *.ntvs* 21 | *.njsproj 22 | *.sln 23 | -------------------------------------------------------------------------------- /.postcssrc.js: -------------------------------------------------------------------------------- 1 | // https://github.com/michael-ciniawsky/postcss-load-config 2 | 3 | module.exports = { 4 | plugins: [ 5 | // to edit target browsers: use "browserslist" field in package.json 6 | require('autoprefixer') 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /.stylintrc: -------------------------------------------------------------------------------- 1 | { 2 | "blocks": "never", 3 | "brackets": "never", 4 | "colons": "never", 5 | "colors": "always", 6 | "commaSpace": "always", 7 | "commentSpace": "always", 8 | "cssLiteral": "never", 9 | "depthLimit": false, 10 | "duplicates": true, 11 | "efficient": "always", 12 | "extendPref": false, 13 | "globalDupe": true, 14 | "indentPref": 2, 15 | "leadingZero": "never", 16 | "maxErrors": false, 17 | "maxWarnings": false, 18 | "mixed": false, 19 | "namingConvention": false, 20 | "namingConventionStrict": false, 21 | "none": "never", 22 | "noImportant": false, 23 | "parenSpace": "never", 24 | "placeholder": false, 25 | "prefixVarsWithDollar": "always", 26 | "quotePref": "single", 27 | "semicolons": "never", 28 | "sortOrder": false, 29 | "stackedProperties": "never", 30 | "trailingWhitespace": "never", 31 | "universal": "never", 32 | "valid": true, 33 | "zeroUnits": "never", 34 | "zIndexNormalize": false 35 | } 36 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # My Aleph.im (myaleph) 2 | 3 | Aleph.im account manager 4 | 5 | ## Install the dependencies 6 | ```bash 7 | yarn 8 | ``` 9 | 10 | ### Start the app in development mode (hot-code reloading, error reporting, etc.) 11 | ```bash 12 | quasar dev 13 | ``` 14 | 15 | ### Lint the files 16 | ```bash 17 | yarn run lint 18 | ``` 19 | 20 | ### Build the app for production 21 | ```bash 22 | quasar build 23 | ``` 24 | 25 | ### Customize the configuration 26 | See [Configuring quasar.conf.js](https://quasar.dev/quasar-cli/quasar-conf-js). 27 | -------------------------------------------------------------------------------- /app-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aleph-im/myaleph/3384cdbea5ea80175b8f1e4587fd52abecd53e7f/app-icon.png -------------------------------------------------------------------------------- /app-splashscreen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aleph-im/myaleph/3384cdbea5ea80175b8f1e4587fd52abecd53e7f/app-splashscreen.png -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@quasar/babel-preset-app' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "myaleph", 3 | "version": "0.0.1", 4 | "description": "Aleph.im account manager", 5 | "productName": "My Aleph.im", 6 | "cordovaId": "im.aleph.my", 7 | "capacitorId": "", 8 | "author": "Moshe Malawach ", 9 | "private": true, 10 | "scripts": { 11 | "lint": "eslint --ext .js,.vue src", 12 | "test": "echo \"No test specified\" && exit 0" 13 | }, 14 | "dependencies": { 15 | "@quasar/extras": "^1.9.15", 16 | "@solana/web3.js": "^0.90.5", 17 | "@toast-ui/vue-editor": "^1.1.1", 18 | "aleph-js": "^0.4.2", 19 | "avalanche": "^3.1.0", 20 | "axios": "^0.18.1", 21 | "bip32": "^2.0.4", 22 | "bip39": "^3.0.2", 23 | "bootstrap": "^4.3.1", 24 | "bootstrap-vue": "^2.1.0", 25 | "downscale": "^1.0.6", 26 | "eciesjs": "^0.3.1", 27 | "ethers": "^5.5.3", 28 | "fuse.js": "^3.4.6", 29 | "quasar": "^1.15.2", 30 | "secp256k1": "^3.7.1", 31 | "vue-easy-lightbox": "^0.8.1", 32 | "vue-i18n": "^8.0.0", 33 | "vue-markdown": "^2.2.4", 34 | "vue-moment": "^4.0.0", 35 | "vue-typer": "^1.2.0" 36 | }, 37 | "devDependencies": { 38 | "@quasar/app": "^1.9.6", 39 | "@quasar/quasar-app-extension-icon-genie": "^1.1.3", 40 | "@vue/eslint-config-standard": "^4.0.0", 41 | "babel-eslint": "^10.0.1", 42 | "devtron": "^1.4.0", 43 | "electron": "^5.0.0", 44 | "electron-debug": "^3.0.0", 45 | "electron-devtools-installer": "^2.2.4", 46 | "eslint": "^5.10.0", 47 | "eslint-loader": "^2.1.1", 48 | "eslint-plugin-vue": "^5.0.0" 49 | }, 50 | "engines": { 51 | "node": ">= 8.9.0", 52 | "npm": ">= 5.6.0", 53 | "yarn": ">= 1.6.0" 54 | }, 55 | "browserslist": [ 56 | "last 1 version, not dead, ie >= 11" 57 | ] 58 | } 59 | -------------------------------------------------------------------------------- /quasar.conf.js: -------------------------------------------------------------------------------- 1 | // Configuration for your app 2 | // https://quasar.dev/quasar-cli/quasar-conf-js 3 | 4 | module.exports = function (ctx) { 5 | return { 6 | // app boot file (/src/boot) 7 | // --> boot files are part of "main.js" 8 | // https://quasar.dev/quasar-cli/cli-documentation/boot-files 9 | boot: [ 10 | 'i18n', 11 | 'axios', 12 | // 'bootstrap', 13 | 'lightbox', 14 | 'moment', 15 | 'profile', 16 | 'storage' 17 | ], 18 | 19 | // https://quasar.dev/quasar-cli/quasar-conf-js#Property%3A-css 20 | css: [ 21 | 'app.scss' 22 | ], 23 | 24 | // https://github.com/quasarframework/quasar/tree/dev/extras 25 | extras: [ 26 | // 'ionicons-v4', 27 | // 'mdi-v4', 28 | 'fontawesome-v5', 29 | // 'eva-icons', 30 | // 'themify', 31 | // 'roboto-font-latin-ext', // this or either 'roboto-font', NEVER both! 32 | 33 | 'roboto-font', // optional, you are not bound to it 34 | 'material-icons' // optional, you are not bound to it 35 | ], 36 | 37 | // https://quasar.dev/quasar-cli/quasar-conf-js#Property%3A-framework 38 | framework: { 39 | // iconSet: 'ionicons-v4', // Quasar icon set 40 | // lang: 'de', // Quasar language pack 41 | 42 | // Possible values for "all": 43 | // * 'auto' - Auto-import needed Quasar components & directives 44 | // (slightly higher compile time; next to minimum bundle size; most convenient) 45 | // * false - Manually specify what to import 46 | // (fastest compile time; minimum bundle size; most tedious) 47 | // * true - Import everything from Quasar 48 | // (not treeshaking Quasar; biggest bundle size; convenient) 49 | all: 'auto', 50 | 51 | components: [], 52 | directives: [], 53 | 54 | // Quasar plugins 55 | plugins: [ 56 | 'LocalStorage', 57 | 'SessionStorage', 58 | 'Notify', 59 | 'Dialog', 60 | 'LoadingBar' 61 | ], 62 | 63 | config: { 64 | loadingBar: { 65 | color: 'secondary', 66 | size: '2px', 67 | position: 'top', 68 | skipHijack: true 69 | } 70 | }, 71 | 72 | cssAddon: true 73 | }, 74 | 75 | // https://quasar.dev/quasar-cli/cli-documentation/supporting-ie 76 | supportIE: false, 77 | 78 | // https://quasar.dev/quasar-cli/quasar-conf-js#Property%3A-build 79 | build: { 80 | scopeHoisting: true //, 81 | // vueRouterMode: 'history' 82 | // showProgress: false, 83 | // gzip: true, 84 | // analyze: true, 85 | // preloadChunks: false, 86 | // extractCSS: false, 87 | 88 | // https://quasar.dev/quasar-cli/cli-documentation/handling-webpack 89 | // extendWebpack (cfg) { 90 | // cfg.module.rules.push({ 91 | // enforce: 'pre', 92 | // test: /\.(js|vue)$/, 93 | // loader: 'eslint-loader', 94 | // exclude: /node_modules/, 95 | // options: { 96 | // formatter: require('eslint').CLIEngine.getFormatter('stylish') 97 | // } 98 | // }) 99 | // } 100 | }, 101 | 102 | // https://quasar.dev/quasar-cli/quasar-conf-js#Property%3A-devServer 103 | devServer: { 104 | // https: true, 105 | // port: 8080, 106 | open: true // opens browser window automatically 107 | }, 108 | 109 | // animations: 'all', // --- includes all animations 110 | // https://quasar.dev/options/animations 111 | animations: [], 112 | 113 | // https://quasar.dev/quasar-cli/developing-ssr/configuring-ssr 114 | ssr: { 115 | pwa: false 116 | }, 117 | 118 | // https://quasar.dev/quasar-cli/developing-pwa/configuring-pwa 119 | pwa: { 120 | // workboxPluginMode: 'InjectManifest', 121 | // workboxOptions: {}, // only for NON InjectManifest 122 | manifest: { 123 | // name: 'My Aleph.im', 124 | // short_name: 'My Aleph.im', 125 | // description: 'Aleph.im account manager', 126 | display: 'standalone', 127 | orientation: 'portrait', 128 | background_color: '#ffffff', 129 | theme_color: '#027be3', 130 | icons: [ 131 | { 132 | 'src': 'statics/icons/icon-128x128.png', 133 | 'sizes': '128x128', 134 | 'type': 'image/png' 135 | }, 136 | { 137 | 'src': 'statics/icons/icon-192x192.png', 138 | 'sizes': '192x192', 139 | 'type': 'image/png' 140 | }, 141 | { 142 | 'src': 'statics/icons/icon-256x256.png', 143 | 'sizes': '256x256', 144 | 'type': 'image/png' 145 | }, 146 | { 147 | 'src': 'statics/icons/icon-384x384.png', 148 | 'sizes': '384x384', 149 | 'type': 'image/png' 150 | }, 151 | { 152 | 'src': 'statics/icons/icon-512x512.png', 153 | 'sizes': '512x512', 154 | 'type': 'image/png' 155 | } 156 | ] 157 | } 158 | }, 159 | 160 | // https://quasar.dev/quasar-cli/developing-cordova-apps/configuring-cordova 161 | cordova: { 162 | // id: 'im.aleph.my', 163 | // noIosLegacyBuildFlag: true, // uncomment only if you know what you are doing 164 | }, 165 | 166 | // https://quasar.dev/quasar-cli/developing-electron-apps/configuring-electron 167 | electron: { 168 | // bundler: 'builder', // or 'packager' 169 | 170 | extendWebpack (cfg) { 171 | // do something with Electron main process Webpack cfg 172 | // chainWebpack also available besides this extendWebpack 173 | }, 174 | 175 | packager: { 176 | // https://github.com/electron-userland/electron-packager/blob/master/docs/api.md#options 177 | 178 | // OS X / Mac App Store 179 | // appBundleId: '', 180 | // appCategoryType: '', 181 | // osxSign: '', 182 | // protocol: 'myapp://path', 183 | 184 | // Windows only 185 | // win32metadata: { ... } 186 | }, 187 | 188 | builder: { 189 | // https://www.electron.build/configuration/configuration 190 | 191 | // appId: 'myaleph' 192 | } 193 | } 194 | } 195 | } 196 | -------------------------------------------------------------------------------- /quasar.extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "@quasar/icon-genie": { 3 | "minify_dev": "pngcrush", 4 | "minify_build": "zopfli", 5 | "cordova": { 6 | "background_color": "#FFFFFF", 7 | "splashscreen_type": "generate" 8 | }, 9 | "build_always": false, 10 | "__internal": { 11 | "dev": { 12 | "spa": { 13 | "iconHash": "71a86653100f06a1f6b2545d2c4910ad" 14 | } 15 | }, 16 | "build": { 17 | "spa": { 18 | "iconHash": "71a86653100f06a1f6b2545d2c4910ad" 19 | } 20 | } 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /src-electron/electron-flag.d.ts: -------------------------------------------------------------------------------- 1 | // THIS FEATURE-FLAG FILE IS AUTOGENERATED, 2 | // REMOVAL OR CHANGES WILL CAUSE RELATED TYPES TO STOP WORKING 3 | import "quasar/dist/types/feature-flag"; 4 | 5 | declare module "quasar/dist/types/feature-flag" { 6 | interface QuasarFeatureFlags { 7 | electron: true; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src-electron/icons/icon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aleph-im/myaleph/3384cdbea5ea80175b8f1e4587fd52abecd53e7f/src-electron/icons/icon.icns -------------------------------------------------------------------------------- /src-electron/icons/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aleph-im/myaleph/3384cdbea5ea80175b8f1e4587fd52abecd53e7f/src-electron/icons/icon.ico -------------------------------------------------------------------------------- /src-electron/icons/linux-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aleph-im/myaleph/3384cdbea5ea80175b8f1e4587fd52abecd53e7f/src-electron/icons/linux-512x512.png -------------------------------------------------------------------------------- /src-electron/main-process/electron-main.dev.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is used specifically and only for development. It installs 3 | * `electron-debug` & `vue-devtools`. There shouldn't be any need to 4 | * modify this file, but it can be used to extend your development 5 | * environment. 6 | */ 7 | 8 | // Install `electron-debug` with `devtron` 9 | require('electron-debug')({ showDevTools: true }) 10 | 11 | // Install `vue-devtools` 12 | require('electron').app.on('ready', () => { 13 | let installExtension = require('electron-devtools-installer') 14 | installExtension.default(installExtension.VUEJS_DEVTOOLS) 15 | .then(() => {}) 16 | .catch(err => { 17 | console.log('Unable to install `vue-devtools`: \n', err) 18 | }) 19 | }) 20 | 21 | // Require `main` process to boot app 22 | require('./electron-main') 23 | -------------------------------------------------------------------------------- /src-electron/main-process/electron-main.js: -------------------------------------------------------------------------------- 1 | import { app, BrowserWindow } from 'electron' 2 | 3 | /** 4 | * Set `__statics` path to static files in production; 5 | * The reason we are setting it here is that the path needs to be evaluated at runtime 6 | */ 7 | if (process.env.PROD) { 8 | global.__statics = require('path').join(__dirname, 'statics').replace(/\\/g, '\\\\') 9 | } 10 | 11 | let mainWindow 12 | 13 | function createWindow () { 14 | /** 15 | * Initial window options 16 | */ 17 | mainWindow = new BrowserWindow({ 18 | width: 1000, 19 | height: 600, 20 | useContentSize: true, 21 | webPreferences: { 22 | nodeIntegration: true 23 | } 24 | }) 25 | 26 | mainWindow.loadURL(process.env.APP_URL) 27 | 28 | mainWindow.on('closed', () => { 29 | mainWindow = null 30 | }) 31 | } 32 | 33 | app.on('ready', createWindow) 34 | 35 | app.on('window-all-closed', () => { 36 | if (process.platform !== 'darwin') { 37 | app.quit() 38 | } 39 | }) 40 | 41 | app.on('activate', () => { 42 | if (mainWindow === null) { 43 | createWindow() 44 | } 45 | }) 46 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 36 | 37 | -------------------------------------------------------------------------------- /src/assets/bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aleph-im/myaleph/3384cdbea5ea80175b8f1e4587fd52abecd53e7f/src/assets/bg.png -------------------------------------------------------------------------------- /src/assets/man_working_on_computer.svg: -------------------------------------------------------------------------------- 1 | man working on computer -------------------------------------------------------------------------------- /src/assets/quasar-logo-full.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 43 | 45 | 46 | 48 | image/svg+xml 49 | 51 | 52 | 53 | 54 | 55 | 60 | 63 | 66 | 69 | 75 | 79 | 83 | 87 | 91 | 95 | 99 | 103 | 104 | 105 | 106 | 107 | 113 | 118 | 126 | 133 | 142 | 151 | 160 | 169 | 178 | 187 | 188 | 189 | 190 | 191 | 192 | -------------------------------------------------------------------------------- /src/assets/sad.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/boot/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aleph-im/myaleph/3384cdbea5ea80175b8f1e4587fd52abecd53e7f/src/boot/.gitkeep -------------------------------------------------------------------------------- /src/boot/axios.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import axios from 'axios' 3 | 4 | Vue.prototype.$axios = axios 5 | -------------------------------------------------------------------------------- /src/boot/bootstrap.js: -------------------------------------------------------------------------------- 1 | 2 | import Vue from 'vue' 3 | import BootstrapVue from 'bootstrap-vue' 4 | 5 | Vue.use(BootstrapVue) -------------------------------------------------------------------------------- /src/boot/i18n.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import VueI18n from 'vue-i18n' 3 | import messages from 'src/i18n' 4 | 5 | Vue.use(VueI18n) 6 | 7 | const i18n = new VueI18n({ 8 | locale: 'en-us', 9 | fallbackLocale: 'en-us', 10 | messages 11 | }) 12 | 13 | export default ({ app }) => { 14 | // Set i18n instance on app 15 | app.i18n = i18n 16 | } 17 | 18 | export { i18n } 19 | -------------------------------------------------------------------------------- /src/boot/lightbox.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Lightbox from 'vue-easy-lightbox' 3 | 4 | Vue.use(Lightbox) -------------------------------------------------------------------------------- /src/boot/moment.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | Vue.use(require('vue-moment')); 3 | // "async" is optional 4 | export default async ({ /* app, router, Vue, ... */ }) => { 5 | // something to do 6 | } 7 | -------------------------------------------------------------------------------- /src/boot/profile.js: -------------------------------------------------------------------------------- 1 | 2 | import Vue from 'vue' 3 | import {aggregates} from 'aleph-js' 4 | 5 | Vue.prototype.$fetch_profile = async function(address) { 6 | let profile = {} 7 | try { 8 | profile = await aggregates.fetch_profile(address, {api_server: this.$store.state.api_server}); 9 | } catch { 10 | 11 | } 12 | this.$store.commit('store_profile', { 13 | address: address, 14 | profile: profile 15 | }) 16 | } -------------------------------------------------------------------------------- /src/boot/storage.js: -------------------------------------------------------------------------------- 1 | import { LocalStorage, SessionStorage } from 'quasar' 2 | 3 | export default async ({ app /* app, router, Vue, ... */ }) => { 4 | let account = LocalStorage.getItem('account') 5 | if (account&&(account!='null')) { 6 | app.store.commit('set_account', account) 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/components/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aleph-im/myaleph/3384cdbea5ea80175b8f1e4587fd52abecd53e7f/src/components/.gitkeep -------------------------------------------------------------------------------- /src/components/FileMenu.vue: -------------------------------------------------------------------------------- 1 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /src/components/FilesList.vue: -------------------------------------------------------------------------------- 1 | 36 | 37 | -------------------------------------------------------------------------------- /src/components/NoteListItem.vue: -------------------------------------------------------------------------------- 1 | 20 | -------------------------------------------------------------------------------- /src/components/NotebookMenu.vue: -------------------------------------------------------------------------------- 1 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /src/components/NotesList.vue: -------------------------------------------------------------------------------- 1 | 121 | 122 | -------------------------------------------------------------------------------- /src/components/Onboarding.vue: -------------------------------------------------------------------------------- 1 | 114 | 115 | 168 | 169 | 276 | -------------------------------------------------------------------------------- /src/components/SubmitContent.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 17 | -------------------------------------------------------------------------------- /src/components/Uploader.js: -------------------------------------------------------------------------------- 1 | // MyUploader.js 2 | import { QUploaderBase } from 'quasar' 3 | import { storage_push_file, encryption, store } from 'aleph-js' 4 | import { mapState } from 'vuex' 5 | 6 | export default { 7 | name: 'aleph-uploader', 8 | 9 | mixins: [ QUploaderBase ], 10 | 11 | computed: { 12 | // [REQUIRED] 13 | // we're working on uploading files 14 | isUploading () { 15 | // return 16 | console.log("isUploading called") 17 | }, 18 | 19 | // [optional] 20 | // shows overlay on top of the 21 | // uploader signaling it's waiting 22 | // on something (blocks all controls) 23 | isBusy () { 24 | // return 25 | console.log("isBusy called") 26 | }, 27 | ... mapState([ 28 | // map this.count to store.state.count 29 | 'account', 30 | 'api_server', 31 | 'channel', 32 | 'balance_info', 33 | 'mb_per_aleph' 34 | ]) 35 | }, 36 | 37 | props: { 38 | 'encrypt': Boolean 39 | }, 40 | 41 | methods: { 42 | // [REQUIRED] 43 | // abort and clean up any process 44 | // that is in progress 45 | abort () { 46 | // ... 47 | }, 48 | 49 | // [REQUIRED] 50 | async upload () { 51 | if (this.canUpload === false) { 52 | return 53 | } 54 | 55 | const queue = this.queuedFiles.slice(0) 56 | const accepted_files = [] 57 | for (let file of queue) { 58 | console.log(queue) 59 | if (file.size >= 4194304){ 60 | this.__updateFile(file, 'failed', file.size * 0.3) 61 | this.$q.notify({ 62 | message: `File ${file.name} is bigger than 4mb, can't upload.`, 63 | color: "negative" 64 | }) 65 | continue 66 | } 67 | 68 | if (this.encrypt) { 69 | let reader = new FileReader() 70 | 71 | reader.readAsArrayBuffer(file) 72 | const result = await new Promise((resolve, reject) => { 73 | reader.onload = function(event) { 74 | resolve(reader.result) 75 | } 76 | }) 77 | file.original_size = file.size 78 | let content = await encryption.encrypt_for_self( 79 | this.account, result, {as_hex: false}) 80 | 81 | file.encrypted_size = content.length 82 | this.__updateFile(file, 'uploading', file.size * 0.3) 83 | 84 | let message = await store.submit( 85 | this.account.address, 86 | {fileobject: new Blob([content], {type: 'application/octet-stream'}), 87 | channel: this.channel, 88 | api_server: this.api_server, 89 | account: this.account}) 90 | 91 | // let file_hash = await storage_push_file( 92 | // myBlob, {api_server: this.api_server}) 93 | file.private = true 94 | file.message_hash = message.item_hash 95 | file.item_hash = message.content.item_hash 96 | file.item_type = message.content.item_type 97 | this.__updateFile(file, 'uploading', file.size * 0.7) 98 | this.__updateFile(file, 'uploaded') 99 | } else { 100 | let message = await store.submit( 101 | this.account.address, 102 | {fileobject: file, 103 | channel: this.channel, 104 | api_server: this.api_server, 105 | account: this.account}) 106 | 107 | this.uploadedSize += file.size 108 | this.__updateFile(file, 'uploading', file.size) 109 | this.__updateFile(file, 'uploaded') 110 | file.original_size = file.size 111 | file.private = false 112 | file.message_hash = message.item_hash 113 | file.item_hash = message.content.item_hash 114 | file.item_type = message.content.item_type 115 | } 116 | accepted_files.push(file) 117 | } 118 | this.$emit('uploaded', accepted_files) 119 | // this.queuedFiles = [] 120 | // if (this.xhrProps.batch(queue)) { 121 | // this.__runFactory(queue) 122 | // } 123 | // else { 124 | // queue.forEach(file => { 125 | // this.__runFactory([ file ]) 126 | // }) 127 | // } 128 | } 129 | } 130 | } -------------------------------------------------------------------------------- /src/css/app.scss: -------------------------------------------------------------------------------- 1 | // app global css in SCSS form 2 | 3 | // @import 'node_modules/bootstrap/scss/bootstrap'; 4 | // @import 'node_modules/bootstrap-vue/src/index.scss'; 5 | 6 | .text-mono { 7 | font-family: 'IBM Plex Mono', monospace; 8 | } 9 | 10 | .filename-col { 11 | overflow: hidden; 12 | text-overflow: ellipsis; 13 | white-space: nowrap; 14 | max-width: 30vw; 15 | } 16 | 17 | .thumbnail-col { 18 | width: 48px; 19 | padding-right: 0 !important; 20 | } -------------------------------------------------------------------------------- /src/css/quasar.variables.scss: -------------------------------------------------------------------------------- 1 | // Quasar SCSS (& Sass) Variables 2 | // -------------------------------------------------- 3 | // To customize the look and feel of this app, you can override 4 | // the Sass/SCSS variables found in Quasar's source Sass/SCSS files. 5 | 6 | // Check documentation for full list of Quasar variables 7 | 8 | // Your own variables (that are declared here) and Quasar's own 9 | // ones will be available out of the box in your .vue/.scss/.sass files 10 | 11 | // It's highly recommended to change the default colors 12 | // to match your app's branding. 13 | // Tip: Use the "Theme Builder" on Quasar's documentation website. 14 | 15 | $primary : #027BE3; 16 | $secondary : #26A69A; 17 | $accent : #9C27B0; 18 | 19 | $positive : #21BA45; 20 | $negative : #C10015; 21 | $info : #31CCEC; 22 | $warning : #F2C037; 23 | 24 | $typography-font-family: 'IBM Plex Sans', sans-serif; 25 | $text-weights: (thin: 100, light: 300, regular: 400, medium: 500, bold: 600, bolder: 900) !default 26 | -------------------------------------------------------------------------------- /src/i18n/en-us/index.js: -------------------------------------------------------------------------------- 1 | // This is just an example, 2 | // so you can safely delete all default props below 3 | const en = { 4 | public: { 5 | wallet: 'Wallet', 6 | wallets: 'Wallets', 7 | warning: 'Warning', 8 | amounts: 'Amounts', 9 | balance: 'Balance', 10 | balances: 'Balances', 11 | accounts: 'Accounts', 12 | total_balance: 'Total Balance', 13 | usable: 'Usable', 14 | available: 'Available', 15 | price: 'Price', 16 | staked: 'Staked', 17 | available_balance: 'Available Balance', 18 | consensus_locked_balance: 'Consensus Locked Balance', 19 | time_locked_balance: 'Time Locked Balance', 20 | time_locked: 'Time Locked', 21 | including_locked: '(incl. locked)' 22 | }, 23 | 24 | resource: { 25 | keystore_file: "Keystore File", 26 | encrypted_private_key: "Encrypted Private Key", 27 | mnemonics_words: "Mnemonic words", 28 | private_key: "Private Key", 29 | public_key: "Public Key", 30 | address: "Address", 31 | passphrase: "Passphrase", 32 | 33 | account_type_unsure: "Account type (if unsure, leave default)", 34 | 35 | actions: "Actions", 36 | 37 | amount: "Amount", 38 | validation_min_amount: "Please enter an amount above {min}.", 39 | valid_amount: "Valid amount requested: {amount}", 40 | insuficient_balance: "Available balance ({balance}) too low", 41 | available_balance: "Available balance:", 42 | remark: "Remark", 43 | valid_target: "Target seems valid", 44 | invalid_target: "Invalid Target", 45 | signed_transaction: "Signed Transaction", 46 | transaction_content: "Transaction Content", 47 | unsigned_raw_transaction: "Unsigned Raw Transaction", 48 | fee: "Fee", 49 | account_name: 'Account Name', 50 | 51 | max_amount: 'Maximum amount:' 52 | }, 53 | 54 | nav: { 55 | select: 'Select account', 56 | all: 'All', 57 | dashboard: 'Dashboard', 58 | accounts:'Accounts', 59 | actions:'Actions', 60 | addAccount:'Add an account', 61 | createAccount:'Create an account', 62 | configuredWallets: 'Configured Wallets' 63 | }, 64 | 65 | header: { 66 | lastBlock: 'Last Block' 67 | }, 68 | 69 | actions: { 70 | send: 'Send', 71 | request: 'Request', 72 | consolidate: 'Consolidate', 73 | rename: 'Rename', 74 | delete: 'Delete', 75 | backup: 'Backup', 76 | stake: 'Stake', 77 | regenerate: 'Re-generate', 78 | add_it: 'Add it', 79 | login: 'Log-In', 80 | logout: 'Log-Out', 81 | 82 | sign_transaction: 'Sign Transaction', 83 | broadcast_transaction: 'Broadcast Transaction', 84 | view_detail: 'view detail', 85 | save: 'Save' 86 | }, 87 | 88 | wallet: { 89 | wallet_value: 'Wallet Value', 90 | unspent_outputs: 'Unspent Outputs', 91 | current_staking: 'Current Staking' 92 | }, 93 | 94 | create: { 95 | new_text: ` 96 | This is a new private key, just generated for you. 97 | Please write it down, this is **important**. 98 | Without it, no way to access your content. 99 | `, 100 | import_text: ` 101 | Enter your private key to access your account. 102 | `, 103 | import_encrypted_text: ` 104 | Enter your encrypted private key and corresponding password to access your account. 105 | The resulting address should correspond to the one you are willing to import. 106 | `, 107 | import_keystore_text: ` 108 | Please upload your keystore file to import your account. 109 | `, 110 | heading: "Add new account", 111 | create: "Create new account", 112 | import_mnemonics: "Login by mnemonics", 113 | import_privkey: "Login by private key", 114 | import_encrypted_privkey: "Login by encrypted key", 115 | import_keystore: "Login by keystore", 116 | add_view_only: "Add view-only account" 117 | }, 118 | 119 | info: { 120 | date: 'Date', 121 | source: 'Source', 122 | target: 'Target', 123 | value: 'Value', 124 | fee: 'Fee' 125 | }, 126 | 127 | transfer: { 128 | target_address: 'Target address' 129 | }, 130 | 131 | notes: { 132 | unassigned_notebook: 'Not in a notebook' 133 | } 134 | }; 135 | export default en -------------------------------------------------------------------------------- /src/i18n/index.js: -------------------------------------------------------------------------------- 1 | import enUS from './en-us' 2 | 3 | export default { 4 | 'en-us': enUS 5 | } 6 | -------------------------------------------------------------------------------- /src/index.template.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <%= htmlWebpackPlugin.options.productName %> 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
21 | 22 | 23 | -------------------------------------------------------------------------------- /src/layouts/Empty.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 10 | -------------------------------------------------------------------------------- /src/layouts/Files.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 50 | -------------------------------------------------------------------------------- /src/layouts/Notes.vue: -------------------------------------------------------------------------------- 1 | 44 | 45 | 159 | -------------------------------------------------------------------------------- /src/layouts/Outside.vue: -------------------------------------------------------------------------------- 1 | 51 | 52 | 110 | 111 | -------------------------------------------------------------------------------- /src/pages/EditNote.vue: -------------------------------------------------------------------------------- 1 | 73 | 74 | 302 | 303 | -------------------------------------------------------------------------------- /src/pages/Error404.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 24 | -------------------------------------------------------------------------------- /src/pages/FileBrowser.vue: -------------------------------------------------------------------------------- 1 | 99 | 100 | 373 | -------------------------------------------------------------------------------- /src/pages/Index.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 48 | -------------------------------------------------------------------------------- /src/pages/NotesDashboard.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 54 | -------------------------------------------------------------------------------- /src/pages/Profile.vue: -------------------------------------------------------------------------------- 1 | 141 | 142 | 303 | 304 | -------------------------------------------------------------------------------- /src/pages/outside/MockNoteEdit.vue: -------------------------------------------------------------------------------- 1 | 54 | 55 | -------------------------------------------------------------------------------- /src/pages/outside/ViewNote.vue: -------------------------------------------------------------------------------- 1 | 41 | 42 | 139 | 140 | -------------------------------------------------------------------------------- /src/router/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import VueRouter from 'vue-router' 3 | 4 | import routes from './routes' 5 | 6 | Vue.use(VueRouter) 7 | 8 | /* 9 | * If not building with SSR mode, you can 10 | * directly export the Router instantiation 11 | */ 12 | 13 | export default function (/* { store, ssrContext } */) { 14 | const Router = new VueRouter({ 15 | scrollBehavior: () => ({ x: 0, y: 0 }), 16 | routes, 17 | 18 | // Leave these as is and change from quasar.conf.js instead! 19 | // quasar.conf.js -> build -> vueRouterMode 20 | // quasar.conf.js -> build -> publicPath 21 | mode: process.env.VUE_ROUTER_MODE, 22 | base: process.env.VUE_ROUTER_BASE 23 | }) 24 | 25 | return Router 26 | } 27 | -------------------------------------------------------------------------------- /src/router/routes.js: -------------------------------------------------------------------------------- 1 | 2 | const routes = [ 3 | { 4 | path: '/l', 5 | component: () => import('layouts/Outside.vue'), 6 | children: [ 7 | { 8 | name: 'landing', 9 | path: '', 10 | component: () => import('pages/outside/Home.vue') 11 | }, 12 | { 13 | name: 'outside-notes', 14 | path: 'n', 15 | component: () => import('layouts/Empty.vue'), 16 | children: [ 17 | { 18 | name: 'view-note', 19 | path: ':hash', 20 | component: () => import('pages/outside/ViewNote.vue'), 21 | props: true 22 | }, 23 | ] 24 | } 25 | ] 26 | }, 27 | { 28 | path: '/', 29 | component: () => import('layouts/MyLayout.vue'), 30 | children: [ 31 | { 32 | name: 'home', 33 | path: '', 34 | component: () => import('pages/Index.vue') 35 | }, 36 | { 37 | name: 'profile', 38 | path: '/p/mine', 39 | component: () => import('pages/Profile.vue') 40 | }, 41 | { 42 | name: 'profile', 43 | path: '/p/:address', 44 | component: () => import('pages/Profile.vue'), 45 | props: true 46 | }, 47 | { 48 | name: 'login', 49 | path: 'login', 50 | component: () => import('pages/Login.vue') 51 | }, 52 | { 53 | path: 'n', 54 | component: () => import('layouts/Notes.vue'), 55 | children: [ 56 | { 57 | name: 'notes', 58 | path: '', 59 | component: () => import('pages/NotesDashboard.vue') 60 | }, 61 | { 62 | name: 'edit-note', 63 | path: ':hash/edit', 64 | component: () => import('pages/EditNote.vue'), 65 | props: true 66 | }, 67 | { 68 | path: 'new', 69 | name: 'new-note', 70 | component: () => import('pages/EditNote.vue'), 71 | props: (route) => ({ notebook: route.query.notebook }) 72 | }, 73 | ] 74 | }, 75 | { 76 | path: 'f', 77 | component: () => import('layouts/Files.vue'), 78 | children: [ 79 | { 80 | name: 'files', 81 | path: '', 82 | component: () => import('pages/FileBrowser.vue') 83 | }, 84 | { 85 | name: 'folder', 86 | path: 'folder/:folder', 87 | component: () => import('pages/FileBrowser.vue'), 88 | props: true 89 | } 90 | ] 91 | } 92 | ] 93 | } 94 | ] 95 | 96 | // Always leave this as last one 97 | if (process.env.MODE !== 'ssr') { 98 | routes.push({ 99 | path: '*', 100 | component: () => import('pages/Error404.vue') 101 | }) 102 | } 103 | 104 | export default routes 105 | -------------------------------------------------------------------------------- /src/services/balances.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios' 2 | 3 | export async function get_nuls_balance_info(address, explorer_url) { 4 | let response = await axios.get(`${explorer_url}/addresses/${address}.json`) 5 | let balance_info = { 6 | 'ALEPH': 0, 7 | 'NULS': 0 8 | } 9 | if ((response.data.unspent_info.unspent_value !== undefined)) 10 | { 11 | balance_info['NULS'] = response.data.unspent_info.unspent_value / (10**8) 12 | } 13 | for (let holding of response.data.token_holdings) { 14 | balance_info[holding.symbol] = holding.balance / (10**holding.decimals) 15 | } 16 | return balance_info 17 | } 18 | 19 | export async function get_ethereum_balance_info(address, explorer_url) { 20 | let response = await axios.get(`${explorer_url}/getAddressInfo/${address}?apiKey=freekey`) 21 | 22 | let balance_info = { 23 | 'ALEPH': 0, 24 | 'ETH': 0 25 | } 26 | if ((response.data.ETH.balance !== undefined)) 27 | { 28 | balance_info['ETH'] = response.data.ETH.balance 29 | } 30 | if(response.data.tokens !== undefined) 31 | for (let holding of response.data.tokens) { 32 | let decimals = Number(holding.tokenInfo.decimals) 33 | balance_info[holding.tokenInfo.symbol] = holding.balance / (10**decimals) 34 | } 35 | return balance_info 36 | } 37 | 38 | export async function get_neo_balance_info(address, explorer_url) { 39 | let response = await axios.get( 40 | `${explorer_url}/api/main_net/v1/get_balance/${address}`) 41 | 42 | let balance_info = { 43 | 'ALEPH': 0, 44 | 'NEO': 0, 45 | 'GAS': 0 46 | } 47 | for (let holding of response.data.balance) { 48 | balance_info[holding.asset_symbol] = holding.amount 49 | } 50 | return balance_info 51 | } -------------------------------------------------------------------------------- /src/services/encryption.js: -------------------------------------------------------------------------------- 1 | import { encryption } from 'aleph-js' 2 | 3 | export async function encrypt_content_for_self(former, keys, account) { 4 | let curve = "secp256k1" 5 | if (account['type'] == 'NEO') 6 | curve = "secp256r1" 7 | return await encrypt_content( 8 | former, keys, account['public_key'], 9 | {'curve': curve}) 10 | } 11 | 12 | export async function encrypt_content( 13 | former, keys, public_key, { curve = "secp256k1" } = {}) { 14 | for (let key of keys) { 15 | if ((former[key] !== undefined) && (former[key] !== null)) { 16 | former[key] = await encryption.encrypt( 17 | public_key, former[key], {'curve': curve}) 18 | } 19 | } 20 | } 21 | 22 | export async function decrypt_content(former, keys, account) { 23 | for (let key of keys) { 24 | if ((former[key] !== undefined) && (former[key] !== null)) { 25 | try { 26 | former[key] = await encryption.decrypt(account, former[key]) 27 | } catch (e) { 28 | console.error("Can't decrypt field", key) 29 | } 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /src/services/erc20.js: -------------------------------------------------------------------------------- 1 | const ethers = require('ethers') 2 | 3 | // A Human-Readable ABI; any supported ABI format could be used 4 | const abi = [ 5 | // Read-Only Functions 6 | 'function balanceOf(address owner) view returns (uint256)', 7 | 'function decimals() view returns (uint8)', 8 | 'function symbol() view returns (string)', 9 | 10 | // Authenticated Functions 11 | 'function transfer(address to, uint amount) returns (boolean)', 12 | 13 | // Events 14 | 'event Transfer(address indexed from, address indexed to, uint amount)' 15 | ] 16 | 17 | export async function get_erc20_balance (provider, contract, address) { 18 | console.log(provider) 19 | const erc20 = new ethers.Contract(contract, abi, provider) 20 | console.log(erc20) 21 | const value = await erc20.functions.balanceOf(address) 22 | console.log(value) 23 | return value 24 | } 25 | -------------------------------------------------------------------------------- /src/services/files.js: -------------------------------------------------------------------------------- 1 | import { encryption, store } from 'aleph-js' 2 | var createObjectURL = (window.URL || window.webkitURL || {}).createObjectURL || function(){}; 3 | var revokeObjectURL = (window.URL || window.webkitURL || {}).revokeObjectURL || function(){}; 4 | 5 | export async function retrieve_file(filepost, account, api_server) { 6 | let content = await store.retrieve(filepost.content.hash, {api_server: api_server}) 7 | if (content !== null) { 8 | if (filepost.content.private) { 9 | content = await encryption.decrypt(account, content, {as_hex: false, as_string: false}) 10 | } 11 | 12 | const data = new Blob([content], {type: filepost.content.mimetype}) 13 | return data 14 | } else { 15 | return null 16 | } 17 | } 18 | 19 | export async function retrieve_file_url(filepost, account, api_server, 20 | {revoke_timeout = null} = {}) { 21 | const data = await retrieve_file(filepost, account, api_server) 22 | if (data !== null) { 23 | const objurl = createObjectURL(data) 24 | if (revoke_timeout) { 25 | setTimeout(function(){ 26 | // For Firefox it is necessary to delay revoking the ObjectURL 27 | revokeObjectURL(objurl); 28 | }, revoke_timeout); 29 | } 30 | 31 | return objurl 32 | } else { 33 | return null 34 | } 35 | } 36 | 37 | export async function navigate_to_file(filepost, account, api_server, 38 | {revoke_timeout = 1000, download = false} = {}) { 39 | const data = await retrieve_file(filepost, account, api_server) 40 | let link = document.createElement('a') 41 | link.href = createObjectURL(data) 42 | if (download) 43 | link.download=filepost.content.filename 44 | else { 45 | link.target='_blank' 46 | link.rel='nofollow' 47 | } 48 | link.click() 49 | if (revoke_timeout) { 50 | setTimeout(function(){ 51 | // For Firefox it is necessary to delay revoking the ObjectURL 52 | revokeObjectURL(link.href); 53 | }, revoke_timeout); 54 | } 55 | } -------------------------------------------------------------------------------- /src/services/posts.js: -------------------------------------------------------------------------------- 1 | 2 | import { encrypt_content_for_self, decrypt_content } from '../services/encryption.js' 3 | import { aggregates, posts, encryption, store } from 'aleph-js' 4 | 5 | export async function update_post(postitem, new_values, encrypted_fields, account, api_server, channel) { 6 | let post_content = {} 7 | Object.assign(post_content, postitem.content, new_values) 8 | 9 | let unencrypted_content = {} 10 | Object.assign(unencrypted_content, post_content) 11 | 12 | if ((post_content.private === undefined)||(post_content.private)) { 13 | post_content['private'] = true 14 | await encrypt_content_for_self(post_content, encrypted_fields, account) 15 | } 16 | 17 | let msg = await posts.submit( 18 | account.address, 'amend', post_content, 19 | {channel: channel, 20 | api_server: api_server, 21 | account: account, 22 | ref:postitem.hash}) 23 | msg.hash = postitem.hash 24 | msg.original_type = postitem.original_type 25 | msg.content = unencrypted_content 26 | msg.original_ref = postitem.original_ref 27 | return msg 28 | } -------------------------------------------------------------------------------- /src/statics/app-logo-128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aleph-im/myaleph/3384cdbea5ea80175b8f1e4587fd52abecd53e7f/src/statics/app-logo-128x128.png -------------------------------------------------------------------------------- /src/statics/icons/apple-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aleph-im/myaleph/3384cdbea5ea80175b8f1e4587fd52abecd53e7f/src/statics/icons/apple-icon-120x120.png -------------------------------------------------------------------------------- /src/statics/icons/apple-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aleph-im/myaleph/3384cdbea5ea80175b8f1e4587fd52abecd53e7f/src/statics/icons/apple-icon-152x152.png -------------------------------------------------------------------------------- /src/statics/icons/apple-icon-167x167.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aleph-im/myaleph/3384cdbea5ea80175b8f1e4587fd52abecd53e7f/src/statics/icons/apple-icon-167x167.png -------------------------------------------------------------------------------- /src/statics/icons/apple-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aleph-im/myaleph/3384cdbea5ea80175b8f1e4587fd52abecd53e7f/src/statics/icons/apple-icon-180x180.png -------------------------------------------------------------------------------- /src/statics/icons/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aleph-im/myaleph/3384cdbea5ea80175b8f1e4587fd52abecd53e7f/src/statics/icons/favicon-16x16.png -------------------------------------------------------------------------------- /src/statics/icons/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aleph-im/myaleph/3384cdbea5ea80175b8f1e4587fd52abecd53e7f/src/statics/icons/favicon-32x32.png -------------------------------------------------------------------------------- /src/statics/icons/favicon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aleph-im/myaleph/3384cdbea5ea80175b8f1e4587fd52abecd53e7f/src/statics/icons/favicon-96x96.png -------------------------------------------------------------------------------- /src/statics/icons/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aleph-im/myaleph/3384cdbea5ea80175b8f1e4587fd52abecd53e7f/src/statics/icons/favicon.ico -------------------------------------------------------------------------------- /src/statics/icons/icon-128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aleph-im/myaleph/3384cdbea5ea80175b8f1e4587fd52abecd53e7f/src/statics/icons/icon-128x128.png -------------------------------------------------------------------------------- /src/statics/icons/icon-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aleph-im/myaleph/3384cdbea5ea80175b8f1e4587fd52abecd53e7f/src/statics/icons/icon-192x192.png -------------------------------------------------------------------------------- /src/statics/icons/icon-256x256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aleph-im/myaleph/3384cdbea5ea80175b8f1e4587fd52abecd53e7f/src/statics/icons/icon-256x256.png -------------------------------------------------------------------------------- /src/statics/icons/icon-384x384.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aleph-im/myaleph/3384cdbea5ea80175b8f1e4587fd52abecd53e7f/src/statics/icons/icon-384x384.png -------------------------------------------------------------------------------- /src/statics/icons/icon-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aleph-im/myaleph/3384cdbea5ea80175b8f1e4587fd52abecd53e7f/src/statics/icons/icon-512x512.png -------------------------------------------------------------------------------- /src/statics/icons/ms-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aleph-im/myaleph/3384cdbea5ea80175b8f1e4587fd52abecd53e7f/src/statics/icons/ms-icon-144x144.png -------------------------------------------------------------------------------- /src/statics/icons/safari-pinned-tab.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/statics/outside/galaxy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aleph-im/myaleph/3384cdbea5ea80175b8f1e4587fd52abecd53e7f/src/statics/outside/galaxy.jpg -------------------------------------------------------------------------------- /src/statics/outside/leftbox.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 43 | 45 | 46 | 48 | image/svg+xml 49 | 51 | 52 | 53 | 54 | 55 | 60 | 63 | 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /src/statics/outside/rightbox.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 43 | 45 | 46 | 48 | image/svg+xml 49 | 51 | 52 | 53 | 54 | 55 | 60 | 63 | 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /src/statics/ux/eth.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/statics/ux/icons/folder-cloud.svg: -------------------------------------------------------------------------------- 1 | folder, file, storage, sort, cloud -------------------------------------------------------------------------------- /src/statics/ux/icons/home.svg: -------------------------------------------------------------------------------- 1 | map, pin, pointer, location, navigation, favourite, home -------------------------------------------------------------------------------- /src/statics/ux/icons/note.svg: -------------------------------------------------------------------------------- 1 | education, educate, school, college, notebook -------------------------------------------------------------------------------- /src/statics/ux/icons/photo.svg: -------------------------------------------------------------------------------- 1 | user, interface, agent, usability, image, gallery, photo -------------------------------------------------------------------------------- /src/statics/ux/icons/share.svg: -------------------------------------------------------------------------------- 1 | interface, user, usability, agent, share, send, transfer -------------------------------------------------------------------------------- /src/statics/ux/neo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/statics/ux/nuls.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/statics/ux/solana.svg: -------------------------------------------------------------------------------- 1 | 2 |