Remove infinite scroll in address transactions page

pull/1137/head
fvictorio 6 years ago committed by Felipe Renan
parent 4236b39a20
commit d147e94fee
  1. 6
      apps/block_scout_web/assets/js/pages/address.js
  2. 54
      apps/block_scout_web/lib/block_scout_web/controllers/address_transaction_controller.ex
  3. 28
      apps/block_scout_web/lib/block_scout_web/templates/address_transaction/index.html.eex
  4. 48
      apps/block_scout_web/test/block_scout_web/controllers/address_transaction_controller_test.exs

@ -6,7 +6,6 @@ import numeral from 'numeral'
import socket from '../socket' import socket from '../socket'
import { createStore, connectElements } from '../lib/redux_helpers.js' import { createStore, connectElements } from '../lib/redux_helpers.js'
import { batchChannel } from '../lib/utils' import { batchChannel } from '../lib/utils'
import { withInfiniteScroll, connectInfiniteScroll } from '../lib/infinite_scroll_helpers'
import listMorph from '../lib/list_morph' import listMorph from '../lib/list_morph'
import { updateAllCalculatedUsdValues } from '../lib/currency.js' import { updateAllCalculatedUsdValues } from '../lib/currency.js'
import { loadTokenBalanceDropdown } from '../lib/token_balance_dropdown' import { loadTokenBalanceDropdown } from '../lib/token_balance_dropdown'
@ -32,9 +31,7 @@ export const initialState = {
nextPageUrl: $('[data-selector="transactions-list"]').length ? URI(window.location).addQuery({ type: 'JSON' }).toString() : null nextPageUrl: $('[data-selector="transactions-list"]').length ? URI(window.location).addQuery({ type: 'JSON' }).toString() : null
} }
export const reducer = withInfiniteScroll(baseReducer) function reducer (state = initialState, action) {
function baseReducer (state = initialState, action) {
switch (action.type) { switch (action.type) {
case 'PAGE_LOAD': case 'PAGE_LOAD':
case 'ELEMENTS_LOAD': { case 'ELEMENTS_LOAD': {
@ -215,7 +212,6 @@ if ($addressDetailsPage.length) {
beyondPageOne: !!blockNumber beyondPageOne: !!blockNumber
}) })
connectElements({ store, elements }) connectElements({ store, elements })
$('[data-selector="transactions-list"]').length && connectInfiniteScroll(store)
const addressChannel = socket.channel(`addresses:${addressHash}`, {}) const addressChannel = socket.channel(`addresses:${addressHash}`, {})
addressChannel.join() addressChannel.join()

@ -8,11 +8,8 @@ defmodule BlockScoutWeb.AddressTransactionController do
import BlockScoutWeb.AddressController, only: [transaction_count: 1, validation_count: 1] import BlockScoutWeb.AddressController, only: [transaction_count: 1, validation_count: 1]
import BlockScoutWeb.Chain, only: [current_filter: 1, paging_options: 1, next_page_params: 3, split_list_by_page: 1] import BlockScoutWeb.Chain, only: [current_filter: 1, paging_options: 1, next_page_params: 3, split_list_by_page: 1]
alias BlockScoutWeb.TransactionView
alias Explorer.{Chain, Market} alias Explorer.{Chain, Market}
alias Explorer.Chain.Hash
alias Explorer.ExchangeRates.Token alias Explorer.ExchangeRates.Token
alias Phoenix.View
@transaction_necessity_by_association [ @transaction_necessity_by_association [
necessity_by_association: %{ necessity_by_association: %{
@ -26,7 +23,7 @@ defmodule BlockScoutWeb.AddressTransactionController do
} }
] ]
def index(conn, %{"address_id" => address_hash_string, "type" => "JSON"} = params) do def index(conn, %{"address_id" => address_hash_string} = params) do
with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string), with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string),
{:ok, address} <- Chain.hash_to_address(address_hash) do {:ok, address} <- Chain.hash_to_address(address_hash) do
options = options =
@ -38,51 +35,6 @@ defmodule BlockScoutWeb.AddressTransactionController do
transactions_plus_one = Chain.address_to_transactions(address, options) transactions_plus_one = Chain.address_to_transactions(address, options)
{transactions, next_page} = split_list_by_page(transactions_plus_one) {transactions, next_page} = split_list_by_page(transactions_plus_one)
next_page_url =
case next_page_params(next_page, transactions, params) do
nil ->
nil
next_page_params ->
address_transaction_path(
conn,
:index,
address,
next_page_params
)
end
json(
conn,
%{
transactions:
Enum.map(transactions, fn transaction ->
%{
transaction_hash: Hash.to_string(transaction.hash),
transaction_html:
View.render_to_string(
TransactionView,
"_tile.html",
current_address: address,
transaction: transaction
)
}
end),
next_page_url: next_page_url
}
)
else
:error ->
unprocessable_entity(conn)
{:error, :not_found} ->
not_found(conn)
end
end
def index(conn, %{"address_id" => address_hash_string} = params) do
with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string),
{:ok, address} <- Chain.hash_to_address(address_hash) do
render( render(
conn, conn,
"index.html", "index.html",
@ -90,7 +42,9 @@ defmodule BlockScoutWeb.AddressTransactionController do
exchange_rate: Market.get_exchange_rate(Explorer.coin()) || Token.null(), exchange_rate: Market.get_exchange_rate(Explorer.coin()) || Token.null(),
filter: params["filter"], filter: params["filter"],
transaction_count: transaction_count(address), transaction_count: transaction_count(address),
validation_count: validation_count(address) validation_count: validation_count(address),
transactions: transactions,
next_page_params: next_page_params(next_page, transactions, params)
) )
else else
:error -> :error ->

@ -52,17 +52,25 @@
</div> </div>
<h2 class="card-title"><%= gettext "Transactions" %></h2> <h2 class="card-title"><%= gettext "Transactions" %></h2>
<span data-selector="transactions-list"> <span data-selector="transactions-list">
<%= for transaction <- @transactions do %>
<%= render BlockScoutWeb.TransactionView, "_tile.html", transaction: transaction, current_address: @address %>
<% end %>
</span> </span>
<div data-selector="loading-next-page" class="tile tile-muted text-center mt-3">
<span class="loading-spinner-small mr-2"> <%= if @next_page_params do %>
<span class="loading-spinner-block-1"></span> <%= link(
<span class="loading-spinner-block-2"></span> gettext("Older"),
</span> class: "button button-secondary button-sm float-right mt-3",
<%= gettext("Loading") %>... "data-selector": "next-page-button",
</div> to: address_transaction_path(
<div data-selector="paging-error-message" class="alert alert-danger text-center mt-3" style="display: none;"> @conn,
<%= gettext("Error trying to fetch transactions.") %> :index,
</div> @address,
@next_page_params
)
) %>
<% end %>
<div class="tile tile-muted text-center" data-selector="empty-transactions-list" style="display: none;"> <div class="tile tile-muted text-center" data-selector="empty-transactions-list" style="display: none;">
<%= gettext "There are no transactions for this address." %> <%= gettext "There are no transactions for this address." %>
</div> </div>

@ -1,7 +1,7 @@
defmodule BlockScoutWeb.AddressTransactionControllerTest do defmodule BlockScoutWeb.AddressTransactionControllerTest do
use BlockScoutWeb.ConnCase use BlockScoutWeb.ConnCase
import BlockScoutWeb.Router.Helpers, only: [address_transaction_path: 3, address_transaction_path: 4] import BlockScoutWeb.Router.Helpers, only: [address_transaction_path: 3]
alias Explorer.Chain.{Block, Transaction} alias Explorer.Chain.{Block, Transaction}
alias Explorer.ExchangeRates.Token alias Explorer.ExchangeRates.Token
@ -34,15 +34,11 @@ defmodule BlockScoutWeb.AddressTransactionControllerTest do
|> insert(to_address: address) |> insert(to_address: address)
|> with_block(block) |> with_block(block)
conn = get(conn, address_transaction_path(conn, :index, address), %{"type" => "JSON"}) conn = get(conn, address_transaction_path(conn, :index, address))
{:ok, %{"transactions" => transactions}} = conn.resp_body |> Poison.decode()
actual_transaction_hashes = Enum.map(transactions, & &1["transaction_hash"]) transactions_hashes = Enum.map(conn.assigns.transactions, &Map.get(&1, :hash))
assert json_response(conn, 200) assert transactions_hashes == [to_transaction.hash, from_transaction.hash]
assert Enum.member?(actual_transaction_hashes, to_string(from_transaction.hash))
assert Enum.member?(actual_transaction_hashes, to_string(to_transaction.hash))
end end
test "includes USD exchange rate value for address in assigns", %{conn: conn} do test "includes USD exchange rate value for address in assigns", %{conn: conn} do
@ -60,7 +56,7 @@ defmodule BlockScoutWeb.AddressTransactionControllerTest do
50 50
|> insert_list(:transaction, from_address: address) |> insert_list(:transaction, from_address: address)
|> with_block() |> with_block()
|> Enum.map(&to_string(&1.hash)) |> Enum.map(& &1.hash)
%Transaction{block_number: block_number, index: index} = %Transaction{block_number: block_number, index: index} =
:transaction :transaction
@ -69,17 +65,14 @@ defmodule BlockScoutWeb.AddressTransactionControllerTest do
conn = conn =
get(conn, address_transaction_path(BlockScoutWeb.Endpoint, :index, address.hash), %{ get(conn, address_transaction_path(BlockScoutWeb.Endpoint, :index, address.hash), %{
"type" => "JSON",
"block_number" => Integer.to_string(block_number), "block_number" => Integer.to_string(block_number),
"index" => Integer.to_string(index) "index" => Integer.to_string(index)
}) })
{:ok, %{"transactions" => transactions}} = conn.resp_body |> Poison.decode()
actual_hashes = actual_hashes =
transactions conn.assigns.transactions
|> Enum.map(& &1["transaction_hash"])
|> Enum.reverse() |> Enum.reverse()
|> Enum.map(& &1.hash)
assert second_page_hashes == actual_hashes assert second_page_hashes == actual_hashes
end end
@ -92,18 +85,15 @@ defmodule BlockScoutWeb.AddressTransactionControllerTest do
|> insert_list(:transaction, from_address: address) |> insert_list(:transaction, from_address: address)
|> with_block(block) |> with_block(block)
conn = get(conn, address_transaction_path(BlockScoutWeb.Endpoint, :index, address.hash), %{"type" => "JSON"}) conn = get(conn, address_transaction_path(BlockScoutWeb.Endpoint, :index, address.hash))
{:ok, %{"next_page_url" => actual_next_page_url}} = conn.resp_body |> Poison.decode()
expected_next_page_url = expected_next_page_params = %{
address_transaction_path(BlockScoutWeb.Endpoint, :index, address.hash, %{ "address_id" => to_string(address.hash),
"block_number" => number, "block_number" => number,
"index" => 10, "index" => 10
"type" => "JSON" }
})
assert expected_next_page_url == actual_next_page_url assert conn.assigns.next_page_params == expected_next_page_params
end end
test "next_page_params are empty if on last page", %{conn: conn} do test "next_page_params are empty if on last page", %{conn: conn} do
@ -113,11 +103,9 @@ defmodule BlockScoutWeb.AddressTransactionControllerTest do
|> insert(from_address: address) |> insert(from_address: address)
|> with_block() |> with_block()
conn = get(conn, address_transaction_path(BlockScoutWeb.Endpoint, :index, address.hash), %{"type" => "JSON"}) conn = get(conn, address_transaction_path(BlockScoutWeb.Endpoint, :index, address.hash))
{:ok, %{"next_page_url" => next_page_url}} = conn.resp_body |> Poison.decode()
refute next_page_url refute conn.assigns.next_page_params
end end
test "returns parent transaction for a contract address", %{conn: conn} do test "returns parent transaction for a contract address", %{conn: conn} do
@ -140,11 +128,9 @@ defmodule BlockScoutWeb.AddressTransactionControllerTest do
conn = get(conn, address_transaction_path(conn, :index, address), %{"type" => "JSON"}) conn = get(conn, address_transaction_path(conn, :index, address), %{"type" => "JSON"})
{:ok, %{"transactions" => transactions}} = conn.resp_body |> Poison.decode() transaction_hashes = Enum.map(conn.assigns.transactions, & &1.hash)
transaction_hashes = Enum.map(transactions, & &1["transaction_hash"])
assert [to_string(transaction.hash)] == transaction_hashes assert [transaction.hash] == transaction_hashes
end end
end end
end end

Loading…
Cancel
Save