Merge pull request #774 from poanetwork/ams-token-inventory
Contributor sees an Inventory tab for ERC-721 tokenspull/819/head
commit
062172957d
@ -0,0 +1,52 @@ |
||||
defmodule BlockScoutWeb.Tokens.InventoryController do |
||||
use BlockScoutWeb, :controller |
||||
|
||||
alias Explorer.Chain |
||||
alias Explorer.Chain.TokenTransfer |
||||
|
||||
import BlockScoutWeb.Chain, only: [split_list_by_page: 1, default_paging_options: 0] |
||||
|
||||
def index(conn, %{"token_id" => address_hash_string} = params) do |
||||
with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string), |
||||
{:ok, token} <- Chain.token_from_address_hash(address_hash) do |
||||
unique_tokens = |
||||
Chain.address_to_unique_tokens( |
||||
token.contract_address_hash, |
||||
unique_tokens_paging_options(params) |
||||
) |
||||
|
||||
{unique_tokens_paginated, next_page} = split_list_by_page(unique_tokens) |
||||
|
||||
render( |
||||
conn, |
||||
"index.html", |
||||
token: token, |
||||
unique_tokens: unique_tokens_paginated, |
||||
total_token_transfers: Chain.count_token_transfers_from_token_hash(address_hash), |
||||
total_token_holders: Chain.count_token_holders_from_token_hash(address_hash), |
||||
next_page_params: unique_tokens_next_page(next_page, unique_tokens_paginated, params) |
||||
) |
||||
else |
||||
:error -> |
||||
not_found(conn) |
||||
|
||||
{:error, :not_found} -> |
||||
not_found(conn) |
||||
end |
||||
end |
||||
|
||||
defp unique_tokens_paging_options(%{"unique_token" => token_id}), |
||||
do: [paging_options: %{default_paging_options() | key: {token_id}}] |
||||
|
||||
defp unique_tokens_paging_options(_params), do: [paging_options: default_paging_options()] |
||||
|
||||
defp unique_tokens_next_page([], _list, _params), do: nil |
||||
|
||||
defp unique_tokens_next_page(_, list, params) do |
||||
Map.merge(params, paging_params(List.last(list))) |
||||
end |
||||
|
||||
defp paging_params(%TokenTransfer{token_id: token_id}) do |
||||
%{"unique_token" => Decimal.to_integer(token_id)} |
||||
end |
||||
end |
@ -0,0 +1,28 @@ |
||||
<!-- use "tile-type-unique-token-image" to token with images --> |
||||
<div class="tile tile-type-unique-token fade-in"> |
||||
<div class="row"> |
||||
<div class="pl-5 col-md-2 d-flex flex-column align-items-left justify-content-start justify-content-lg-center"> |
||||
<!-- substitute the span with <img class="tile-image" /> to token with images --> |
||||
<span class="tile-label"><%= gettext "Unique Token" %></span> |
||||
</div> |
||||
|
||||
<div class="tile-content col-md-7 col-lg-8 d-flex flex-column"> |
||||
<span class="d-flex flex-md-row flex-column mt-3 mt-md-0"> |
||||
<span class="mr-1"><%= gettext "Token ID" %>:</span> |
||||
<span class="tile-title"> |
||||
<%= @token_transfer.token_id %> |
||||
</span> |
||||
</span> |
||||
|
||||
<span class="d-flex flex-md-row flex-column mt-3 mt-md-0"> |
||||
<span class="mr-1"><%= gettext "Owner Address" %>:</span> |
||||
<span class="tile-title"> |
||||
<%= render BlockScoutWeb.AddressView, |
||||
"_link.html", |
||||
address: @token_transfer.to_address, |
||||
contract: false %> |
||||
</span> |
||||
</span> |
||||
</div> |
||||
</div> |
||||
</div> |
@ -0,0 +1,42 @@ |
||||
<section class="container"> |
||||
<%= render( |
||||
OverviewView, |
||||
"_details.html", |
||||
token: @token, |
||||
total_token_transfers: @total_token_transfers, |
||||
total_token_holders: @total_token_holders, |
||||
conn: @conn |
||||
) %> |
||||
|
||||
<section> |
||||
<div class="card"> |
||||
<div class="card-header"> |
||||
<%= render OverviewView, "_tabs.html", assigns %> |
||||
</div> |
||||
|
||||
<div class="card-body"> |
||||
<h2 class="card-title"><%= gettext "Inventory" %></h2> |
||||
|
||||
<%= if Enum.any?(@unique_tokens) do %> |
||||
<%= for token_transfer <- @unique_tokens do %> |
||||
<%= render "_token.html", token_transfer: token_transfer %> |
||||
<% end %> |
||||
<% else %> |
||||
<div class="tile tile-muted text-center"> |
||||
<span data-selector="empty-transactions-list"> |
||||
<%= gettext "There are no tokens." %> |
||||
</span> |
||||
</div> |
||||
<% end %> |
||||
|
||||
<%= if @next_page_params do %> |
||||
<%= link( |
||||
gettext("Next Page"), |
||||
class: "button button-secondary button-small float-right mt-4", |
||||
to: token_inventory_path(@conn, :index, @token.contract_address_hash, @next_page_params) |
||||
) %> |
||||
<% end %> |
||||
</div> |
||||
</div> |
||||
</section> |
||||
</section> |
@ -0,0 +1,5 @@ |
||||
defmodule BlockScoutWeb.Tokens.InventoryView do |
||||
use BlockScoutWeb, :view |
||||
|
||||
alias BlockScoutWeb.Tokens.OverviewView |
||||
end |
@ -1,14 +1,5 @@ |
||||
defmodule BlockScoutWeb.Tokens.TransferView do |
||||
use BlockScoutWeb, :view |
||||
|
||||
alias Explorer.Chain.{Address, SmartContract, Token} |
||||
alias BlockScoutWeb.Tokens.OverviewView |
||||
|
||||
def smart_contract_with_read_only_functions?( |
||||
%Token{contract_address: %Address{smart_contract: %SmartContract{}}} = token |
||||
) do |
||||
Enum.any?(token.contract_address.smart_contract.abi, & &1["constant"]) |
||||
end |
||||
|
||||
def smart_contract_with_read_only_functions?(%Token{contract_address: %Address{smart_contract: nil}}), do: false |
||||
end |
||||
|
Loading…
Reference in new issue