diff --git a/README.md b/README.md index 93ae9aa..8a1871b 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ -# Safehold - Ellcrys Desktop Client +# SafeHold - Ellcrys Desktop Client -Safehold is the official desktop client that allows users to join the Ellcrys network, manage their Ellcrys accounts, send and receive -the native cryptocurrency and more. Safehold provides a beautiful graphic user interface that allows all categories of users experience and interact with the network easily. +SafeHold is the official desktop client that allows users to join the Ellcrys network, manage their Ellcrys accounts, send and receive +the native cryptocurrency and more. SafeHold provides a beautiful graphic user interface that allows all categories of users experience and interact with the network easily. ## Installation @@ -9,7 +9,7 @@ the native cryptocurrency and more. Safehold provides a beautiful graphic user i ## Development -Safehold is actively being developed by the Ellcrys team. It will continue to mature as the protocol itself gains more features and improvements. +SafeHold is actively being developed by the Ellcrys team. It will continue to mature as the protocol itself gains more features and improvements. ### Install Dependencies @@ -21,16 +21,17 @@ npm install ### Embedded ELLD -Internally, Safehold embeds and execute a copy of [ELLD](https://github.com/ellcrys/elld) (our official CLI network client) to gain access to all features supported by the protocol. During development, you will need to add pre-built binaries into the [binaries](https://github.com/ellcrys/safehold/tree/master/binaries) directory where it will be picked up by the build script and embedded into the build. +Internally, SafeHold embeds and execute a copy of [ELLD](https://github.com/ellcrys/elld) (our official CLI network client) to gain access to all features supported by the protocol. During development, you will need to add pre-built binaries into the [binaries](https://github.com/ellcrys/safehold/tree/master/binaries) directory where it will be picked up by the build script and embedded into the build. ```bash -env TARGET=darwin npm run dev -# TARGET = darwin, linux or windows +env npm run dev +#env npm run dev-linux +#env npm run dev-win ``` ## SetUp Development Environment -You will need to start up two terminals to run the build processes for vue-electron and typescript compilation. +You will need to start up two terminals for vue-electron and typescript compilation. **Build vue-electron** @@ -45,37 +46,11 @@ npm run compile // On terminal 2 ``` ## Build - To create a production build, run the following command: ```bash +npm install cpy-cli -g npm run build -``` - -## Troubleshooting - -``` -sh: cpy: command not found -``` - -#### Solution - -To solve the above error, you need to install `cpy-cli` globally with nom. - -- code `npm install cpy-cli -g` - -``` -An unhandled error occurred inside electron-rebuild - CXX(target) Release/obj.target/bignum/bignum.o -../bignum.cc:9:10: fatal error: 'openssl/bn.h' file not found -#include -``` - -#### Solution : - -(Mac) - -``` -brew update -brew upgrade openssl +# npm run build-win +# npm run build-linux ``` diff --git a/build/icons/icon.ico b/build/icons/icon.ico index ddf3101..c042e4a 100644 Binary files a/build/icons/icon.ico and b/build/icons/icon.ico differ diff --git a/dev/core/analytics.ts b/dev/core/analytics.ts new file mode 100644 index 0000000..8e5b31d --- /dev/null +++ b/dev/core/analytics.ts @@ -0,0 +1,37 @@ +import { app } from "electron"; +const ua = require("universal-analytics"); +const uuid = require("uuid/v4"); +const { JSONStorage } = require("node-localstorage"); +const nodeStorage = new JSONStorage(app.getPath("userData")); + +// Retrieve the userId value, and if it's not there, assign it a new uuid. +const userId = nodeStorage.getItem("userId") || uuid(); +nodeStorage.setItem("userId", userId); + +const usr = ua("UA-101346362-5", userId); + +export default function trackEvent( + category: string, + action: string, + label?: string, + value?: any, +) { + usr.event({ + ec: category, + ea: action, + el: label, + ev: value, + }).send(); +} + +export function exceptionEvent(desc: string, fatal?: boolean) { + usr.exception(desc, fatal); +} + +export function timingEvent(category: string, variable: string, time: number) { + usr.timing(category, variable, time); +} + +export function trackPage(path: string) { + usr.pageview(path); +} diff --git a/dev/core/app.ts b/dev/core/app.ts index 2154db9..23f9033 100644 --- a/dev/core/app.ts +++ b/dev/core/app.ts @@ -30,6 +30,11 @@ import { } from "../.."; import { kdf } from "../utilities/crypto"; import Account from "./account"; +import trackEvent, { + exceptionEvent, + timingEvent, + trackPage, +} from "./analytics"; import AverageBlockTime from "./average_block_time"; import { Base } from "./base"; import ChannelCodes from "./channel_codes"; @@ -43,6 +48,9 @@ import Transactions from "./transactions"; import Wallet from "./wallet"; const moment = require("moment"); +(global as any).trackEvent = trackEvent; +(global as any).trackPage = trackPage; + /** * Returns the file path of the wallet * @returns {string} @@ -152,6 +160,8 @@ export default class App extends Base { win.webContents.send(ChannelCodes.AppLaunched, { hasWallet: mHasWallet, }); + + trackEvent("App", "run"); } /** @@ -195,6 +205,7 @@ export default class App extends Base { public stop() { if (this.elld) { this.elld.stop(); + trackEvent("App", "stopped"); } } @@ -257,6 +268,7 @@ export default class App extends Base { } i++; } + trackEvent("Wallet", "restore"); return resolve(); }); } @@ -373,9 +385,7 @@ export default class App extends Base { Interval.clear("runUnconfirmedTx"); const dbOps = DBOps.fromDB(this.db); - const txCheck = await dbOps.find({ _type: "txPool" }); - const Spells = this.elld.getSpell(); for (const t of txCheck) { @@ -505,6 +515,7 @@ export default class App extends Base { await this.makeWallet(secInfo); this.kdfPass = secInfo.kdfPass; if (this.win) { + trackEvent("Wallet", "new"); return this.send( this.win, ChannelCodes.WalletCreated, @@ -529,7 +540,11 @@ export default class App extends Base { if (this.win) { try { + const now = moment().unix(); await this.execELLD(); + // prettier-ignore + timingEvent("App", "elld:started:timed", now - moment().unix() * 1000); + trackEvent("App", "elld:started"); Menu.setApplicationMenu( makeMenu(app, { afterAuth: true, @@ -540,14 +555,17 @@ export default class App extends Base { await this.startBgProcesses(); this.applyPreferences(); this.normalizeWindow(); + trackEvent("Wallet", "loaded"); // prettier-ignore return this.send(this.win, ChannelCodes.WalletLoaded, null); } catch (error) { + exceptionEvent("WalletLoad failed"); log.error("Failed to load wallet", error.message); } } } catch (error) { if (this.win) { + log.error("Failed to load wallet", error.message); return this.sendError(this.win, { code: ErrCodes.FailedToLoadWallet.code, msg: ErrCodes.FailedToLoadWallet.msg, @@ -593,12 +611,14 @@ export default class App extends Base { // Request to start the miner ipcMain.on(ChannelCodes.MinerStart, () => { + trackEvent("App", "miner:started"); this.preference.set(PrefMinerOn, true); this.elld.getSpell().miner.start(); }); // Request to stop the miner ipcMain.on(ChannelCodes.MinerStop, async () => { + trackEvent("App", "miner:stopped"); this.preference.set(PrefMinerOn, false); this.elld.getSpell().miner.stop(); }); @@ -647,6 +667,7 @@ export default class App extends Base { ChannelCodes.AccountRedirect, newAcct.getAddress().toString(), ); + trackEvent("Account", "created"); } catch (err) { this.wallet.removeAccount(newAcct); return this.sendError(this.win, { @@ -711,6 +732,7 @@ export default class App extends Base { hash: txHash.id.toString(), }); + trackEvent("App:Tx", "sent"); return this.send( this.win, ChannelCodes.TransactionSend, @@ -718,6 +740,8 @@ export default class App extends Base { ); } catch (error) { const jsonErr = JSON.parse(error.data); + trackEvent("App:Tx", "failed", "error", error.data); + exceptionEvent("App:Tx:Send"); return this.send( this.win, @@ -955,6 +979,7 @@ export default class App extends Base { // Request to force account resynchronization ipcMain.on(ChannelCodes.AccountsReSync, async (e) => { + trackEvent("Account", "resync"); await this.transactions.clearCursors(); }); } @@ -995,6 +1020,7 @@ export default class App extends Base { .then(resolve) .catch(reject); } catch (error) { + trackEvent("App", "elld:exec:failed"); if (this.win) { this.sendError(this.win, { code: ErrCodes.FailedToLoadElldObject.code, @@ -1027,6 +1053,7 @@ export default class App extends Base { }); }); } catch (error) { + trackEvent("Wallet", "persist:failed"); return reject(error); } }); diff --git a/dev/core/elld.ts b/dev/core/elld.ts index 9917a83..a22e9c2 100644 --- a/dev/core/elld.ts +++ b/dev/core/elld.ts @@ -126,9 +126,8 @@ export default class Elld { ELLD_RPC_PASSWORD: rpcPass, }; - console.log(env); - - const elld = spawn("elld", args, { shell: true, cwd: this.execPath, env }); + const command = (process.platform === "win32") ? "elld" : "./elld"; + const elld = spawn(command, args, { cwd: this.execPath, env }); this.elld = elld; // hook a callback to stdout diff --git a/dev/core/menu.ts b/dev/core/menu.ts index 94f06bd..286a306 100644 --- a/dev/core/menu.ts +++ b/dev/core/menu.ts @@ -26,10 +26,6 @@ export function makeBaseMenuTemplate(app: Electron.App, opts: IMenuOpts) { { label: "Application data", click: showAppDir(app) }, ], }, - { - role: "quit", - click: opts.onQuit, - }, ], }, { @@ -135,11 +131,20 @@ interface IMenuOpts { // prettier-ignore export const makeMenu = (app: Electron.App, opts: IMenuOpts) => { const template = makeBaseMenuTemplate(app, opts); + if (opts.afterAuth) { - template.splice(3, 0, { label: "View", submenu: [{ role: "togglefullscreen" }]}); (template[1].submenu as MenuItemConstructorOptions[]).push({ type: "separator" }); + template.splice(3, 0, { label: "View", submenu: [{ role: "togglefullscreen" }]}); (template[1].submenu as MenuItemConstructorOptions[]) - .push({ label: "New Account", click: opts.onNewAccount }); + .push({ label: "New Account", click: opts.onNewAccount }); } + + const t = (process.platform === "darwin") ? 1 : 0; + (template[t].submenu as MenuItemConstructorOptions[]).push({ type: "separator" }); + (template[t].submenu as MenuItemConstructorOptions[]).push({ + role: "quit", + click: opts.onQuit, + }); + return Menu.buildFromTemplate(template as any); }; diff --git a/dev/index.ejs b/dev/index.ejs index dcdf871..8b1078f 100644 --- a/dev/index.ejs +++ b/dev/index.ejs @@ -3,7 +3,7 @@ - Safehold <%= process.env.APP_VERSION %> + SafeHold <%= process.env.APP_VERSION %> <% if (htmlWebpackPlugin.options.nodeModules) { %> diff --git a/dev/renderer/assets/css/app.scss b/dev/renderer/assets/css/app.scss index d3b3b4f..c54e1e0 100755 --- a/dev/renderer/assets/css/app.scss +++ b/dev/renderer/assets/css/app.scss @@ -309,7 +309,8 @@ body { #password-strength-bar-list { clear: both; list-style: none; - margin-top: -5px; + position: relative; + top: -8px; margin-bottom: 0; li { @@ -437,6 +438,9 @@ body { background: rgba(0, 0, 0, .9); position: fixed; z-index: 10000; + display: flex; + align-items: center; + justify-content: center; .modal-pane.big { width: 800px; @@ -444,12 +448,15 @@ body { margin-top: 100px; } + .modal-pane.h10pct { + margin-top: 10%; + } + .modal-pane { - width: 500px; + width: auto; height: 300px; border-radius: 6px; margin: auto; - margin-top: 100px; background: #fbfcff; position: relative; @@ -512,7 +519,7 @@ body { .modal-flex { display: table; - margin-top: 30px; + // margin-top: 30px; } .flex-layout { @@ -528,6 +535,11 @@ body { flex: 1; } + +} + +.modal-overlay .modal-override-warning { + width: 500px; } .modal-overlay.loader { @@ -615,7 +627,7 @@ body { font-size: 14px; margin-left: 50px; margin-top: 20px; - min-width: 150px; + min-width: 120px; padding: 4px 15px; cursor: pointer; padding-top: 5px; @@ -762,10 +774,9 @@ body { } + #main-split .split-right.index-bg { height: 100vh; - background: url("../img/image.png"); - background-size: cover; .about { background: #0D1422; @@ -819,6 +830,24 @@ body { } } +#main-split .split-right .step1 { + background: url("../img/image.png"); + background-size: cover; + height: 100vh; +} + +#main-split .split-right .step2 { + background: url("../img/image2.png"); + background-size: cover; + height: 100vh; +} + +#main-split .split-right .step3 { + background: url("../img/image3.png"); + background-size: cover; + height: 100vh; +} + #main-split .split-right-nav { border: 0px solid #09f; border-spacing: 20px 0; diff --git a/dev/renderer/assets/css/dashboard.scss b/dev/renderer/assets/css/dashboard.scss index f5c7cda..3246b4e 100644 --- a/dev/renderer/assets/css/dashboard.scss +++ b/dev/renderer/assets/css/dashboard.scss @@ -603,7 +603,6 @@ body { border: 0px solid #09f; display: table; margin: auto; - margin-top: 40px; width: 661px; } @@ -902,6 +901,25 @@ body { +#learn-safehold .small { + display: none; + font-size: inherit; + font-weight: inherit; +} + +@media screen and (max-width: 1132px) { + + #learn-safehold .large { + display: none; + } + + #learn-safehold .small { + display: block; + } +} + + + #learn-safehold p, #learn-safehold hr, #learn-safehold a { @@ -958,24 +976,24 @@ body { @media screen and (max-width: 1480px) { - #learn-safehold { - display: none; - } + // #learn-safehold { + // display: none; + // } } @media screen and (max-width: 1366px) { - #learn-safehold { - display: block; - } + // #learn-safehold { + // display: block; + // } } @media screen and (max-width: 1296px) { - #learn-safehold { - display: none; - } + // #learn-safehold { + // display: none; + // } } #top-icons .hide, @@ -1769,6 +1787,28 @@ body { } +#side-navigation-wrapper .side-nav .nav .icon:nth-child(1) { + display: block; +} + + + +#side-navigation-wrapper .side-nav .nav .icon:nth-child(2) { + display: none; +} + + +#side-navigation-wrapper .side-nav .nav:hover .icon:nth-child(1) { + display: none; +} + + + +#side-navigation-wrapper .side-nav .nav:hover .icon:nth-child(2) { + display: block; +} + + #side-navigation-wrapper .side-nav strong { margin-left: 15px; } @@ -1809,6 +1849,17 @@ body { +#side-navigation-wrapper .side-nav .active .icon:nth-child(1) { + display: none; +} + + + +#side-navigation-wrapper .side-nav .active .icon:nth-child(2) { + display: block; +} + + #side-navigation-wrapper .sub-nav-wrapper { diff --git a/dev/renderer/assets/css/onboarding.scss b/dev/renderer/assets/css/onboarding.scss index e1a38a4..adc1fd2 100644 --- a/dev/renderer/assets/css/onboarding.scss +++ b/dev/renderer/assets/css/onboarding.scss @@ -17,11 +17,7 @@ } .onboarding-main-split .split-left, -.onboarding-main-split .split-right { - - position: relative; - -} +.onboarding-main-split .split-right {} .onboarding-main-split .split-left { background-clip: content-box; @@ -61,25 +57,42 @@ .onboarding-main-split .split-right { - border: 0px solid red; - padding: 100px 90px; -} + display: flex; + flex-direction: column; + padding: 0 30px; + .item { + flex-grow: 1; + flex-basis: 45px; + } + .item.header { + padding-top: 50px; + padding-bottom: 40px; + padding-left: 25px; + } -.split-right-header, -.split-right-main, -.split-right-footer { - float: left; - width: 100%; + .item.content { + flex-grow: 15; + overflow: auto; + padding: 25px; + line-height: 25px; + } + + .item.footer { + padding: 15px; + } } + +.split-right-content {} + + .split-right-header { font-size: 28px; font-weight: bold; } - .split-right-outter-article { color: #323c47; display: block; @@ -163,12 +176,8 @@ } .split-right-footer { - border: 0px solid red; - bottom: 60px; - clear: both; height: 38px; - position: absolute; - width: 80%; + width: 100%; } @@ -201,7 +210,7 @@ .split-right-footer .page-switcher { border: 0px solid red; display: table; - margin-left: 30%; + margin-left: 20%; } .split-right-footer .page-switcher li { diff --git a/dev/renderer/assets/icon/Accounts.svg b/dev/renderer/assets/icon/Accounts.svg new file mode 100644 index 0000000..49927a3 --- /dev/null +++ b/dev/renderer/assets/icon/Accounts.svg @@ -0,0 +1,33 @@ + + + + Accounts + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dev/renderer/assets/icon/Log.svg b/dev/renderer/assets/icon/Log.svg new file mode 100644 index 0000000..86d4b1d --- /dev/null +++ b/dev/renderer/assets/icon/Log.svg @@ -0,0 +1,53 @@ + + + + Group 23 Copy 6 + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dev/renderer/assets/icon/Mining.svg b/dev/renderer/assets/icon/Mining.svg new file mode 100644 index 0000000..06dd69f --- /dev/null +++ b/dev/renderer/assets/icon/Mining.svg @@ -0,0 +1,38 @@ + + + + Group 9 Copy 7 + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dev/renderer/assets/icon/Overview.svg b/dev/renderer/assets/icon/Overview.svg new file mode 100644 index 0000000..b91928c --- /dev/null +++ b/dev/renderer/assets/icon/Overview.svg @@ -0,0 +1,46 @@ + + + + Rectangle Copy 4 + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dev/renderer/assets/icon/export_wallet.svg b/dev/renderer/assets/icon/export_wallet.svg new file mode 100644 index 0000000..7a4c059 --- /dev/null +++ b/dev/renderer/assets/icon/export_wallet.svg @@ -0,0 +1,33 @@ + + + + export_wallet copy 4 + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dev/renderer/assets/img/image.png b/dev/renderer/assets/img/image.png index e002670..88fa2d8 100644 Binary files a/dev/renderer/assets/img/image.png and b/dev/renderer/assets/img/image.png differ diff --git a/dev/renderer/assets/img/image2.png b/dev/renderer/assets/img/image2.png new file mode 100644 index 0000000..4f1a61d Binary files /dev/null and b/dev/renderer/assets/img/image2.png differ diff --git a/dev/renderer/assets/img/image3.png b/dev/renderer/assets/img/image3.png new file mode 100644 index 0000000..380863f Binary files /dev/null and b/dev/renderer/assets/img/image3.png differ diff --git a/dev/renderer/components/Index.vue b/dev/renderer/components/Index.vue index be367c2..f19cece 100644 --- a/dev/renderer/components/Index.vue +++ b/dev/renderer/components/Index.vue @@ -6,6 +6,7 @@ import ChannelCodes from '../../core/channel_codes'; import { ipcRenderer, remote } from 'electron'; import { ModalLoaderOpen } from './constants/events'; +import log from 'electron-log'; export default { data() { @@ -28,7 +29,7 @@ export default { // to the index page. // prettier-ignore onAppLaunched(event, msg) { - console.log("AppLaunched") + log.info("AppLaunched") if (msg.hasWallet) { return this.$router.replace('login') } return this.$router.replace("signup") }, diff --git a/dev/renderer/components/Login.vue b/dev/renderer/components/Login.vue index 1855275..7b295ba 100644 --- a/dev/renderer/components/Login.vue +++ b/dev/renderer/components/Login.vue @@ -15,21 +15,16 @@ remember your passphrase, but you know your 12-Word phrase, click the "Restore" button to recover your wallet.

-
+
@@ -72,18 +67,7 @@
-
-
-
-

Ellcrys - A Blockchain for Collaboration

-

- The Ellcrys Network is a blockchain system that allows - you to create, co-own and co-manage open source software - products and organizations without fear of censorship. -

-
-
-
+
@@ -95,15 +79,19 @@ import { ipcRenderer } from 'electron'; import ChannelCodes from '../../core/channel_codes'; import { kdf } from '../../utilities/crypto'; - +import SplashSlide from './SplashSlide.vue'; +import Mixin from './dashboard/Mixin'; import { ModalWalletOverrideWarningOpen, ModalLoaderOpen, ModalLoaderClose, } from './constants/events'; -import Mixin from './dashboard/Mixin'; + export default { mixins: [Mixin], + components: { + SplashSlide, + }, data() { return { passphrase: '', @@ -112,6 +100,7 @@ export default { }, created() { + this.trackPage(this.$route.path); this.onEvents(); }, @@ -154,6 +143,8 @@ export default { // The main process will receive the event and use the passphrase // to unlock the wallet and emit a WalletLoaded event. openWallet() { + this.errMsg = ''; + if (this.passphrase.trim() === '') { this.errMsg = 'Please enter your passphrase'; return; diff --git a/dev/renderer/components/SaveMnemonics.vue b/dev/renderer/components/SaveMnemonics.vue index 13a54d4..4ab9dd5 100644 --- a/dev/renderer/components/SaveMnemonics.vue +++ b/dev/renderer/components/SaveMnemonics.vue @@ -106,18 +106,7 @@
-
-
-
-

Ellcrys - A Blockchain for Collaboration

-

- The Ellcrys Network is a blockchain system that allows - you to create, co-own and co-manage open source software - products and organizations without fear of censorship. -

-
-
-
+
@@ -131,8 +120,14 @@ import { ipcRenderer } from 'electron'; import ChannelCodes from '../../core/channel_codes'; import * as bip39 from 'bip39'; import { ModalConfirmCopyOpen } from './constants/events'; +import Mixin from './dashboard/Mixin'; +import SplashSlide from './SplashSlide.vue'; export default { + mixins: [Mixin], + components: { + SplashSlide, + }, data() { return { seedWords: [], @@ -145,6 +140,7 @@ export default { // seed phrase. We also hook listeners to various // events from here. created() { + this.trackPage(this.$route.path); this.onEvents(); ipcRenderer.send(ChannelCodes.WalletGetEntropy); }, diff --git a/dev/renderer/components/SignUp.vue b/dev/renderer/components/SignUp.vue index e4344d2..f9fe953 100644 --- a/dev/renderer/components/SignUp.vue +++ b/dev/renderer/components/SignUp.vue @@ -18,7 +18,7 @@ -
{{errMsg}}
+
{{errMsg}}
@@ -29,7 +29,7 @@ you will not be able to unlock your wallet and since we don't store your passphrase we won't be able to help.

- +
  • @@ -94,18 +96,7 @@
-
-
-
-

Ellcrys - A Blockchain for Collaboration

-

- The Ellcrys Network is a blockchain system that allows - you to create, co-own and co-manage open source software - products and organizations without fear of censorship. -

-
-
-
+
@@ -120,9 +111,13 @@ import * as crypto from 'crypto'; import { kdf } from '../../utilities/crypto'; const zxcvbn = require('zxcvbn'); import Mixin from './dashboard/Mixin'; +import SplashSlide from './SplashSlide.vue'; export default { mixins: [Mixin], + components: { + SplashSlide, + }, data() { return { passphrase: '', @@ -133,6 +128,7 @@ export default { }, created() { + this.trackPage(this.$route.path); this.onEvents(); }, diff --git a/dev/renderer/components/SplashSlide.vue b/dev/renderer/components/SplashSlide.vue new file mode 100644 index 0000000..098806c --- /dev/null +++ b/dev/renderer/components/SplashSlide.vue @@ -0,0 +1,54 @@ + + + + diff --git a/dev/renderer/components/VerifyMnemonics.vue b/dev/renderer/components/VerifyMnemonics.vue index a5b5a02..e04dbea 100644 --- a/dev/renderer/components/VerifyMnemonics.vue +++ b/dev/renderer/components/VerifyMnemonics.vue @@ -38,56 +38,98 @@
-
{{ this.challengeWords[0] }}
-
{{ this.challengeWords[1] }}
-
{{ this.challengeWords[2] }}
-
{{ this.challengeWords[3] }}
-
{{ this.challengeWords[4] }}
-
{{ this.challengeWords[5] }}
-
{{ this.challengeWords[6] }}
-
{{ this.challengeWords[7] }}
-
{{ this.challengeWords[8] }}
-
{{ this.challengeWords[9] }}
+
+
+
{{ this.challengeWords[0] }}
+
+
+
{{ this.challengeWords[1] }}
+
+
+
{{ this.challengeWords[2] }}
+
+
+
+
+
{{ this.challengeWords[3] }}
+
+
+
{{ this.challengeWords[4] }}
+
+
+
{{ this.challengeWords[5] }}
+
+
+
+
+
{{ this.challengeWords[6] }}
+
+
+
{{ this.challengeWords[7] }}
+
+
+
{{ this.challengeWords[8] }}
+
+
+
+
+
{{ this.challengeWords[9] }}
+
+
+
{{ this.challengeWords[10] }}
+
+
+
{{ this.challengeWords[11] }}
+
+
@@ -111,18 +153,7 @@
-
-
-
-

Ellcrys - A Blockchain for Collaboration

-

- The Ellcrys Network is a blockchain system that allows - you to create, co-own and co-manage open source software - products and organizations without fear of censorship. -

-
-
-
+
@@ -139,10 +170,15 @@ const randomWords = require('./data/random-words.json'); import * as _ from 'lodash'; import log from 'electron-log'; import { ModalLoaderOpen } from './constants/events'; - +import Mixin from './dashboard/Mixin'; +import SplashSlide from './SplashSlide.vue'; const MaxAttempts = 4; export default { + components: { + SplashSlide, + }, + mixins: [Mixin], data() { return { hideAll: false, @@ -160,6 +196,7 @@ export default { // seed phrase. We also hook listeners to various // events from here. created() { + this.trackPage(this.$route.path); this.onEvents(); ipcRenderer.send(ChannelCodes.WalletGetEntropy); }, @@ -182,7 +219,7 @@ export default { // is received. We react to this event by converting the // returned seed into a list of mnenonic words and constructing // the verification challenge data where we pick 4 random seed - // words and mix with 6 other random words. The resulting 10 + // words and mix with 8 other random words. The resulting 12 // words will be used in the challenge. onDataWalletEntropy(event, seed) { this.seedWords = bip39.entropyToMnemonic(seed).split(' '); @@ -198,7 +235,7 @@ export default { // Shuffle the random words list and add // the first6 words to the challenge words list let shuffled = _.shuffle(randomWords.words); - for (let i = 0; i < 6; i++) { + for (let i = 0; i < 8; i++) { this.challengeWords.push(shuffled[i].toLowerCase()); } diff --git a/dev/renderer/components/dashboard/AccountView.vue b/dev/renderer/components/dashboard/AccountView.vue index 74de394..15a0f1d 100644 --- a/dev/renderer/components/dashboard/AccountView.vue +++ b/dev/renderer/components/dashboard/AccountView.vue @@ -62,13 +62,13 @@
Learn

- + >

@@ -167,7 +167,7 @@ {{ shortenTxHash(tx._id) }} {{ shortenAddress(tx.from) }} @@ -195,10 +195,8 @@ import * as _ from 'lodash'; import * as moment from 'moment'; import { IAccountOverviewData, IAccountData } from '../../../..'; import { ModalReceiveOpen, ModalSendOpen } from '../constants/events'; - -import * as carousel from '@chenfengyuan/vue-carousel'; - const copy = require('copy-to-clipboard'); +import * as VueCarousel from '@chenfengyuan/vue-carousel'; var refreshInt; @@ -206,7 +204,7 @@ export default { mixins: [Mixin], components: { - carousel, + VueCarousel, }, data() { return { @@ -246,6 +244,7 @@ export default { // - Request for the data of the account. // - Load all account in the wallet created() { + this.trackPage(this.$route.path); this.onEvents(); this.loadAccount(); ipcRenderer.send(ChannelCodes.AccountsGet); diff --git a/dev/renderer/components/dashboard/Dashboard.vue b/dev/renderer/components/dashboard/Dashboard.vue index ccb682e..515b48c 100644 --- a/dev/renderer/components/dashboard/Dashboard.vue +++ b/dev/renderer/components/dashboard/Dashboard.vue @@ -18,7 +18,7 @@ -
+
@@ -41,6 +41,7 @@ import { ModalOnBoardingOpen, } from '../constants/events'; import { IOverviewData } from '../../../..'; +import Mixin from './Mixin'; // refreshInt holds a reference to the // content refresh interval @@ -51,6 +52,8 @@ let refreshInt; const refreshDur = 15000; export default { + mixins: [Mixin], + components: { Sidebar, MinerView, @@ -81,6 +84,7 @@ export default { // It reacts by: // - listening for events of interest created() { + this.trackPage(this.$route.path); this.onEvents(); }, diff --git a/dev/renderer/components/dashboard/Header.vue b/dev/renderer/components/dashboard/Header.vue index 6d37be8..0c60833 100644 --- a/dev/renderer/components/dashboard/Header.vue +++ b/dev/renderer/components/dashboard/Header.vue @@ -2,25 +2,32 @@