Co-authored-by: Stamates <stamates@hotmail.com> Co-authored-by: Tim Mecklem <timothy@mecklem.com>pull/462/head
parent
e3f6737e3a
commit
c81cca4552
@ -0,0 +1,26 @@ |
||||
import { reducer, initialState } from '../../js/pages/chain' |
||||
|
||||
test('CHANNEL_DISCONNECTED', () => { |
||||
const state = initialState |
||||
const action = { |
||||
type: 'CHANNEL_DISCONNECTED' |
||||
} |
||||
const output = reducer(state, action) |
||||
|
||||
expect(output.channelDisconnected).toBe(true) |
||||
}) |
||||
|
||||
test('RECEIVED_NEW_BLOCK', () => { |
||||
const state = Object.assign({}, initialState, { |
||||
newBlock: 'last new block' |
||||
}) |
||||
const action = { |
||||
type: 'RECEIVED_NEW_BLOCK', |
||||
msg: { |
||||
homepageBlockHtml: 'new block' |
||||
} |
||||
} |
||||
const output = reducer(state, action) |
||||
|
||||
expect(output.newBlock).toEqual('new block') |
||||
}) |
@ -0,0 +1,48 @@ |
||||
import $ from 'jquery' |
||||
import humps from 'humps' |
||||
import router from '../router' |
||||
import socket from '../socket' |
||||
import { updateAllAges } from '../lib/from_now' |
||||
import { initRedux } from '../utils' |
||||
|
||||
export const initialState = { |
||||
newBlock: null, |
||||
channelDisconnected: false |
||||
} |
||||
|
||||
export function reducer (state = initialState, action) { |
||||
switch (action.type) { |
||||
case 'CHANNEL_DISCONNECTED': { |
||||
return Object.assign({}, state, { |
||||
channelDisconnected: true |
||||
}) |
||||
} |
||||
case 'RECEIVED_NEW_BLOCK': { |
||||
return Object.assign({}, state, { |
||||
newBlock: humps.camelizeKeys(action.msg).homepageBlockHtml |
||||
}) |
||||
} |
||||
default: |
||||
return state |
||||
} |
||||
} |
||||
|
||||
router.when('', { exactPathMatch: true }).then(() => initRedux(reducer, { |
||||
main (store) { |
||||
const blocksChannel = socket.channel(`blocks:new_block`) |
||||
blocksChannel.join() |
||||
.receive('ok', resp => { console.log('Joined successfully', 'blocks:new_block', resp) }) |
||||
.receive('error', resp => { console.log('Unable to join', 'blocks:new_block', resp) }) |
||||
blocksChannel.onError(() => store.dispatch({ type: 'CHANNEL_DISCONNECTED' })) |
||||
blocksChannel.on('new_block', msg => store.dispatch({ type: 'RECEIVED_NEW_BLOCK', msg })) |
||||
}, |
||||
render (state, oldState) { |
||||
const $blockList = $('[data-selector="chain-block-list"]') |
||||
|
||||
if (oldState.newBlock !== state.newBlock) { |
||||
$blockList.children().last().remove() |
||||
$blockList.prepend(state.newBlock) |
||||
updateAllAges() |
||||
} |
||||
} |
||||
})) |
@ -0,0 +1,33 @@ |
||||
defmodule ExplorerWeb.BlockChannel do |
||||
@moduledoc """ |
||||
Establishes pub/sub channel for live updates of block events. |
||||
""" |
||||
use ExplorerWeb, :channel |
||||
|
||||
alias ExplorerWeb.ChainView |
||||
alias Phoenix.View |
||||
|
||||
intercept(["new_block"]) |
||||
|
||||
def join("blocks:new_block", _params, socket) do |
||||
{:ok, %{}, socket} |
||||
end |
||||
|
||||
def handle_out("new_block", %{block: block}, socket) do |
||||
Gettext.put_locale(ExplorerWeb.Gettext, socket.assigns.locale) |
||||
|
||||
rendered_homepage_block = |
||||
View.render_to_string( |
||||
ChainView, |
||||
"_block.html", |
||||
locale: socket.assigns.locale, |
||||
block: block |
||||
) |
||||
|
||||
push(socket, "new_block", %{ |
||||
homepage_block_html: rendered_homepage_block |
||||
}) |
||||
|
||||
{:noreply, socket} |
||||
end |
||||
end |
Loading…
Reference in new issue