Co-authored-by: Stamates <stamates@hotmail.com> Co-authored-by: Tim Mecklem <timothy@mecklem.com>pull/333/head
parent
56b6010d60
commit
5041f8fa2c
@ -1,62 +1,21 @@ |
|||||||
// NOTE: The contents of this file will only be executed if
|
|
||||||
// you uncomment its entry in "assets/js/app.js".
|
|
||||||
|
|
||||||
// To use Phoenix channels, the first step is to import Socket
|
|
||||||
// and connect at the socket path in "lib/web/endpoint.ex":
|
|
||||||
import {Socket} from 'phoenix' |
import {Socket} from 'phoenix' |
||||||
|
import $ from 'jquery' |
||||||
|
|
||||||
let socket = new Socket('/socket', {params: {token: window.userToken}}) |
let socket = new Socket('/socket', {params: {locale: window.locale}}) |
||||||
|
|
||||||
// When you connect, you'll often need to authenticate the client.
|
|
||||||
// For example, imagine you have an authentication plug, `MyAuth`,
|
|
||||||
// which authenticates the session and assigns a `:current_user`.
|
|
||||||
// If the current user exists you can assign the user's token in
|
|
||||||
// the connection for use in the layout.
|
|
||||||
//
|
|
||||||
// In your "lib/web/router.ex":
|
|
||||||
//
|
|
||||||
// pipeline :browser do
|
|
||||||
// ...
|
|
||||||
// plug MyAuth
|
|
||||||
// plug :put_user_token
|
|
||||||
// end
|
|
||||||
//
|
|
||||||
// defp put_user_token(conn, _) do
|
|
||||||
// if current_user = conn.assigns[:current_user] do
|
|
||||||
// token = Phoenix.Token.sign(conn, "user socket", current_user.id)
|
|
||||||
// assign(conn, :user_token, token)
|
|
||||||
// else
|
|
||||||
// conn
|
|
||||||
// end
|
|
||||||
// end
|
|
||||||
//
|
|
||||||
// Now you need to pass this token to JavaScript. You can do so
|
|
||||||
// inside a script tag in "lib/web/templates/layout/app.html.eex":
|
|
||||||
//
|
|
||||||
// <script>window.userToken = "<%= assigns[:user_token] %>";</script>
|
|
||||||
//
|
|
||||||
// You will need to verify the user token in the "connect/2" function
|
|
||||||
// in "lib/web/channels/user_socket.ex":
|
|
||||||
//
|
|
||||||
// def connect(%{"token" => token}, socket) do
|
|
||||||
// # max_age: 1209600 is equivalent to two weeks in seconds
|
|
||||||
// case Phoenix.Token.verify(socket, "user socket", token, max_age: 1209600) do
|
|
||||||
// {:ok, user_id} ->
|
|
||||||
// {:ok, assign(socket, :user, user_id)}
|
|
||||||
// {:error, reason} ->
|
|
||||||
// :error
|
|
||||||
// end
|
|
||||||
// end
|
|
||||||
//
|
|
||||||
// Finally, pass the token on connect as below. Or remove it
|
|
||||||
// from connect if you don't care about authentication.
|
|
||||||
|
|
||||||
socket.connect() |
socket.connect() |
||||||
|
|
||||||
// Now that you are connected, you can join channels with a topic:
|
|
||||||
let channel = socket.channel('topic:subtopic', {}) |
|
||||||
|
|
||||||
|
|
||||||
|
// addresses channel
|
||||||
|
let channel = socket.channel(`addresses:${window.addressHash}`, {}) |
||||||
channel.join() |
channel.join() |
||||||
.receive('ok', resp => { console.log('Joined successfully', resp) }) |
.receive('ok', resp => { console.log('Joined successfully', resp) }) |
||||||
.receive('error', resp => { console.log('Unable to join', resp) }) |
.receive('error', resp => { console.log('Unable to join', resp) }) |
||||||
|
|
||||||
|
channel.on('transaction', (msg) => { |
||||||
|
$('[data-selector="transactions-list"]').prepend(msg.transaction) |
||||||
|
}) |
||||||
|
|
||||||
export default socket |
export default socket |
||||||
|
@ -0,0 +1,15 @@ |
|||||||
|
defmodule ExplorerWeb.AddressChannel do |
||||||
|
use ExplorerWeb, :channel |
||||||
|
|
||||||
|
intercept ["transaction"] |
||||||
|
|
||||||
|
def join("addresses:" <> _address_hash, _params, socket) do |
||||||
|
{:ok, %{}, socket} |
||||||
|
end |
||||||
|
|
||||||
|
def handle_out("transaction", %{transaction: transaction}, socket) do |
||||||
|
rendered = Phoenix.View.render_to_string(ExplorerWeb.AddressTransactionView, "_transaction.html", locale: socket.assigns.locale, transaction: transaction) |
||||||
|
push socket, "transaction", %{transaction: rendered} |
||||||
|
{:noreply, socket} |
||||||
|
end |
||||||
|
end |
@ -1,35 +1,14 @@ |
|||||||
defmodule ExplorerWeb.UserSocket do |
defmodule ExplorerWeb.UserSocket do |
||||||
use Phoenix.Socket |
use Phoenix.Socket |
||||||
|
|
||||||
# channel "room:*", ExplorerWeb.RoomChannel |
channel "addresses:*", ExplorerWeb.AddressChannel |
||||||
|
|
||||||
transport(:websocket, Phoenix.Transports.WebSocket, timeout: 45_000) |
transport(:websocket, Phoenix.Transports.WebSocket, timeout: 45_000) |
||||||
# transport :longpoll, Phoenix.Transports.LongPoll |
# transport :longpoll, Phoenix.Transports.LongPoll |
||||||
|
|
||||||
# Socket params are passed from the client and can |
def connect(%{"locale" => locale}, socket) do |
||||||
# be used to verify and authenticate a user. After |
{:ok, assign(socket, :locale, locale)} |
||||||
# verification, you can put default assigns into |
|
||||||
# the socket that will be set for all channels, ie |
|
||||||
# |
|
||||||
# {:ok, assign(socket, :user_id, verified_user_id)} |
|
||||||
# |
|
||||||
# To deny connection, return `:error`. |
|
||||||
# |
|
||||||
# See `Phoenix.Token` documentation for examples in |
|
||||||
# performing token verification on connect. |
|
||||||
def connect(_params, socket) do |
|
||||||
{:ok, socket} |
|
||||||
end |
end |
||||||
|
|
||||||
# Socket ids are topics that allow you to identify all sockets for a user: |
|
||||||
# |
|
||||||
# def id(socket), do: "user_socket:#{socket.assigns.user_id}" |
|
||||||
# |
|
||||||
# Would allow you to broadcast a "disconnect" event and terminate |
|
||||||
# all active sockets and channels for a given user: |
|
||||||
# |
|
||||||
# ExplorerWeb.Endpoint.broadcast("user_socket:#{user.id}", "disconnect", %{}) |
|
||||||
# |
|
||||||
# Returning `nil` makes this socket anonymous. |
|
||||||
def id(_socket), do: nil |
def id(_socket), do: nil |
||||||
end |
end |
||||||
|
@ -0,0 +1,35 @@ |
|||||||
|
<tr> |
||||||
|
<td><div class="transaction__dot transaction__dot--<%= status(@transaction) %>"></div></td> |
||||||
|
<td> |
||||||
|
<%= render ExplorerWeb.TransactionView, "_link.html", locale: @locale, transaction: @transaction %> |
||||||
|
</td> |
||||||
|
<td> |
||||||
|
<%= link( |
||||||
|
@transaction.block, |
||||||
|
to: block_path(ExplorerWeb.Endpoint, :show, @locale, @transaction.block) |
||||||
|
) %> |
||||||
|
</td> |
||||||
|
<td><%= @transaction.block.timestamp |> Timex.from_now %></td> |
||||||
|
<td class="address-cell"> |
||||||
|
<%= render ExplorerWeb.AddressView, "_link.html", locale: @locale, address: @transaction.from_address %> |
||||||
|
</td> |
||||||
|
<td class="u-text-center"><i class="fas fa-arrow-circle-right"></i></td> |
||||||
|
<td> |
||||||
|
<%= cond do %> |
||||||
|
<% @transaction.to_address_hash != nil -> %> |
||||||
|
<%= render ExplorerWeb.AddressView, "_link.html", locale: @locale, address: @transaction.to_address %> |
||||||
|
<% @transaction.created_contract_address_hash != nil -> %> |
||||||
|
<i class="fas fa-plus-square"></i> |
||||||
|
<%= link( |
||||||
|
"Contract Creation", |
||||||
|
class: "transaction__link", |
||||||
|
"data-address-hash": @transaction.created_contract_address_hash, |
||||||
|
to: address_path(ExplorerWeb.Endpoint, :show, @locale, @transaction.created_contract_address_hash), |
||||||
|
title: @transaction.created_contract_address_hash |
||||||
|
) %> |
||||||
|
<% true -> %> |
||||||
|
<% end %> |
||||||
|
</td> |
||||||
|
<td><%= ExplorerWeb.TransactionView.value(@transaction, include_label: false) %></td> |
||||||
|
<td><%= ExplorerWeb.TransactionView.formatted_fee(@transaction, denomination: :ether) %></td> |
||||||
|
</tr> |
Loading…
Reference in new issue