diff --git a/CHANGELOG.md b/CHANGELOG.md
index a4f335b6cb..141a40e2cd 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -64,6 +64,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- [\#1894](https://github.com/cosmos/voyager/issues/1894) Added favicons for all the browsers and devices @jbibla
- [\#1865](https://github.com/cosmos/voyager/issues/1865) Added Vuex blocks module @sabau
- [\#1928](https://github.com/cosmos/voyager/issues/1928) Added Browserstack reference to README @sabau
+- [\#1866](https://github.com/cosmos/voyager/issues/1866) Added blocks to network page and a page for viewing individual blocks @jbibla
### Changed
diff --git a/app/src/renderer/components/common/TmConnectedNetwork.vue b/app/src/renderer/components/common/TmConnectedNetwork.vue
index ada51eda26..2b10a5c674 100644
--- a/app/src/renderer/components/common/TmConnectedNetwork.vue
+++ b/app/src/renderer/components/common/TmConnectedNetwork.vue
@@ -14,10 +14,10 @@
-
Block #{{ block }} Block #{{ block }} @ {{ date }}
@@ -46,10 +46,10 @@ export default {
}
},
computed: {
- date() {
- const time = moment(this.time)
- return time.format(
- `${moment().isSame(time, `day`) ? `` : `YYYY/MM/DD `}HH:mm`
+ date({ time } = this) {
+ const momentTime = moment(time)
+ return momentTime.format(
+ `${moment().isSame(momentTime, `day`) ? `` : `MMM Do YYYY `}HH:mm:ss`
)
}
}
@@ -64,7 +64,7 @@ export default {
border: 1px solid var(--bc-dim);
background: var(--app-fg);
width: 100%;
- font-weight: 400;
+ font-weight: 300;
}
.tm-li-tx:hover {
diff --git a/app/src/renderer/components/wallet/LiCoin.vue b/app/src/renderer/components/wallet/LiCoin.vue
index 6a47ea6871..fe6e059cf1 100644
--- a/app/src/renderer/components/wallet/LiCoin.vue
+++ b/app/src/renderer/components/wallet/LiCoin.vue
@@ -53,7 +53,6 @@ export default {
margin-bottom: 0.5rem;
border: 1px solid var(--bc-dim);
background: var(--app-fg);
- min-width: 45rem;
}
.li-coin:hover {
diff --git a/app/src/renderer/connectors/lcdClient.js b/app/src/renderer/connectors/lcdClient.js
index abfeb0b7b1..d8a3d66b8f 100644
--- a/app/src/renderer/connectors/lcdClient.js
+++ b/app/src/renderer/connectors/lcdClient.js
@@ -202,6 +202,9 @@ const Client = (axios, remoteLcdURL) => {
]).then(([depositorTxs, proposerTxs]) =>
[].concat(depositorTxs, proposerTxs)
)
+ },
+ getBlock: function(blockHeight) {
+ return req(`GET`, `/blocks/${blockHeight}`)()
}
}
}
diff --git a/app/src/renderer/routes.js b/app/src/renderer/routes.js
index 41d22330c0..bbe8fda265 100644
--- a/app/src/renderer/routes.js
+++ b/app/src/renderer/routes.js
@@ -85,6 +85,11 @@ export default [
name: `network`,
component: require(`./components/network/PageNetwork`).default
},
+ {
+ path: `/blocks/:height`,
+ name: `block`,
+ component: require(`./components/network/PageBlock`).default
+ },
{ path: `/404`, component: require(`./components/common/Page404`).default },
{ path: `*`, component: require(`./components/common/Page404`).default }
]
diff --git a/app/src/renderer/styles/table.css b/app/src/renderer/styles/table.css
index c39153dc68..1fb870fd97 100644
--- a/app/src/renderer/styles/table.css
+++ b/app/src/renderer/styles/table.css
@@ -21,14 +21,9 @@
.data-table td {
padding: 0.5rem;
position: relative;
- vertical-align: bottom;
color: var(--bright);
}
-.data-table td:not(:first-child) {
- padding-bottom: 1.2rem;
-}
-
.data-table__row__cell__separator:after {
display: block;
position: absolute;
diff --git a/app/src/renderer/vuex/getters.js b/app/src/renderer/vuex/getters.js
index 883a1b3fd8..d0f1ac9b98 100644
--- a/app/src/renderer/vuex/getters.js
+++ b/app/src/renderer/vuex/getters.js
@@ -84,9 +84,12 @@ export const depositDenom = getters =>
? getters.governanceParameters.parameters.deposit.min_deposit[0].denom
: ``
-// status
+// connection
export const approvalRequired = state => state.connection.approvalRequired
export const connected = state => state.connection.connected
export const lastHeader = state => state.connection.lastHeader
export const nodeUrl = state =>
state.connection.connected ? state.connection.nodeUrl : undefined
+
+export const blocks = state => (state.blocks ? state.blocks.blocks : [])
+export const block = state => (state.blocks ? state.blocks.block : [])
diff --git a/app/src/renderer/vuex/modules/blocks.js b/app/src/renderer/vuex/modules/blocks.js
index d9eeaeef5d..09c3557d6b 100644
--- a/app/src/renderer/vuex/modules/blocks.js
+++ b/app/src/renderer/vuex/modules/blocks.js
@@ -1,7 +1,7 @@
import * as Sentry from "@sentry/browser"
import Vue from "vue"
-export const cache = (list, element, maxSize = 1000) => {
+export const cache = (list, element, maxSize = 100) => {
if (list.length >= maxSize) list.splice(-1, 1)
list.unshift(element)
return list
@@ -18,7 +18,11 @@ export default ({ node }) => {
loading: false,
error: null,
peers: [],
- blocks: []
+ blocks: [],
+ // one block, specified by height
+ block: {
+ block_meta: {}
+ }
}
const mutations = {
@@ -29,6 +33,7 @@ export default ({ node }) => {
setBlockMetas: (state, blockMetas) => (state.blockMetas = blockMetas),
setPeers: (state, peers) => (state.peers = peers),
setBlocks: (state, blocks) => (state.blocks = blocks),
+ setBlock: (state, block) => (state.block = block),
addBlock: (state, block) =>
Vue.set(state, `blocks`, cache(state.blocks, block)),
setSubscribedRPC: (state, subscribedRPC) =>
@@ -50,17 +55,16 @@ export default ({ node }) => {
return blockMetaInfo
}
commit(`setLoading`, true)
- const { block_metas } = await node.rpc.blockchain({
- minHeight: String(height),
- maxHeight: String(height)
- })
- blockMetaInfo = block_metas ? block_metas[0] : undefined
+ const block = await node.getBlock(height)
+
+ blockMetaInfo = block.block_metas ? block.block_metas[0] : undefined
commit(`setLoading`, false)
commit(`setBlockMetas`, {
...state.blockMetas,
[height]: blockMetaInfo
})
+ commit(`setBlock`, block)
return blockMetaInfo
} catch (error) {
commit(`notifyError`, {
diff --git a/test/unit/specs/components/common/TmConnectedNetwork.spec.js b/test/unit/specs/components/common/TmConnectedNetwork.spec.js
index e2070a1992..591bd612c6 100644
--- a/test/unit/specs/components/common/TmConnectedNetwork.spec.js
+++ b/test/unit/specs/components/common/TmConnectedNetwork.spec.js
@@ -1,20 +1,31 @@
+import { shallowMount, createLocalVue } from "@vue/test-utils"
import TmConnectedNetwork from "common/TmConnectedNetwork"
-import setup from "../../../helpers/vuex-setup"
+
+const localVue = createLocalVue()
+localVue.directive(`tooltip`, () => {})
describe(`TmConnectedNetwork`, () => {
- let wrapper, store
- const { mount } = setup()
+ let wrapper, $store
- beforeEach(async () => {
- const instance = mount(TmConnectedNetwork, {
+ beforeEach(() => {
+ $store = {
getters: {
- lastHeader: () => ({ chain_id: `Test Net`, height: 42 }),
- nodeUrl: () => `https://faboNode.de`,
- connected: () => true
+ lastHeader: {
+ chain_id: `gaia-20k`,
+ height: `6001`
+ },
+ nodeUrl: `https://faboNode.de`,
+ connected: true
}
+ }
+
+ wrapper = shallowMount(TmConnectedNetwork, {
+ localVue,
+ mocks: {
+ $store
+ },
+ stubs: [`router-link`]
})
- store = instance.store
- wrapper = instance.wrapper
})
it(`has the expected html structure`, () => {
@@ -36,7 +47,7 @@ describe(`TmConnectedNetwork`, () => {
.find(`#tm-connected-network__string`)
.text()
.trim()
- ).toBe(`Test Net`)
+ ).toBe(`gaia-20k`)
})
it(`has a block string`, () => {
@@ -45,53 +56,28 @@ describe(`TmConnectedNetwork`, () => {
.find(`#tm-connected-network__block`)
.text()
.trim()
- ).toContain(`#42`)
- })
-
- it(`has link to the external block explorer`, () => {
- expect(wrapper.vm.explorerLink).toBe(
- `https://explorecosmos.network/blocks/42`
- )
+ ).toBe(`#6,001`)
})
it(`has a connecting state`, async () => {
- const { wrapper } = mount(TmConnectedNetwork, {
+ $store = {
getters: {
- lastHeader: () => ({ chain_id: `Test Net`, height: 0 }),
- connected: () => false
+ lastHeader: {
+ chain_id: ``,
+ height: ``
+ },
+ nodeUrl: null,
+ connected: false
}
- })
- expect(wrapper.vm.$el).toMatchSnapshot()
- })
+ }
- it(`shows a link to the preferences page if not on the preferences page`, () => {
- expect(wrapper.find(`#tm-connected-network_preferences-link`)).toBeDefined()
- wrapper.setData({
- $route: {
- name: `preferences`
- }
- })
- expect(
- wrapper.vm.$el.querySelector(`#tm-connected-network_preferences-link`)
- ).toBeFalsy()
- })
-
- it(`shows the connected node`, async () => {
- const instance = mount(TmConnectedNetwork)
- store = instance.store
- wrapper = instance.wrapper
-
- Object.assign(store.state.connection, {
- mocked: false,
- node: {
- remoteLcdURL: `123.123.123.123`
+ wrapper = shallowMount(TmConnectedNetwork, {
+ localVue,
+ mocks: {
+ $store
},
- lastHeader: Object.assign(store.state.connection.lastHeader, {
- chain_id: `chain_id`
- }),
- connected: true
+ stubs: [`router-link`]
})
-
expect(wrapper.vm.$el).toMatchSnapshot()
})
})
diff --git a/test/unit/specs/components/common/TmSession.spec.js b/test/unit/specs/components/common/TmSession.spec.js
index 9b6c9c66a0..bc5d7c1cb8 100644
--- a/test/unit/specs/components/common/TmSession.spec.js
+++ b/test/unit/specs/components/common/TmSession.spec.js
@@ -31,7 +31,8 @@ describe(`TmSessionWelcome`, () => {
"session-sign-in": true,
"session-hardware": true,
"session-import": true,
- "session-account-delete": true
+ "session-account-delete": true,
+ "router-link": true
}
})
})
diff --git a/test/unit/specs/components/common/__snapshots__/TmConnectedNetwork.spec.js.snap b/test/unit/specs/components/common/__snapshots__/TmConnectedNetwork.spec.js.snap
index b81ec70695..0714dfa86e 100644
--- a/test/unit/specs/components/common/__snapshots__/TmConnectedNetwork.spec.js.snap
+++ b/test/unit/specs/components/common/__snapshots__/TmConnectedNetwork.spec.js.snap
@@ -14,7 +14,7 @@ exports[`TmConnectedNetwork has a connecting state 1`] = `
class="tm-connected-network__string tm-connected-network__string--connecting"
>
- Connecting to Test Net…
+ Connecting to …
@@ -46,7 +46,7 @@ exports[`TmConnectedNetwork has the expected html structure 1`] = `