Fix dark forest theme bugs, allow multiple contracts

pull/3333/head
Victor Baranov 4 years ago
parent d42f6729cb
commit 7efee7b685
  1. 2
      apps/block_scout_web/assets/css/components/_log-search.scss
  2. 55
      apps/block_scout_web/assets/css/theme/custom_contracts/_dark-forest-theme.scss
  3. 1
      apps/block_scout_web/assets/js/lib/smart_contract/write.js
  4. 11
      apps/block_scout_web/assets/js/pages/address/internal_transactions.js
  5. 9
      apps/block_scout_web/assets/js/pages/address/token_transfers.js
  6. 9
      apps/block_scout_web/assets/js/pages/address/transactions.js
  7. 2
      apps/block_scout_web/config/config.exs
  8. 11
      apps/block_scout_web/lib/block_scout_web/templates/address/_tabs.html.eex
  9. 17
      apps/block_scout_web/lib/block_scout_web/templates/address/overview.html.eex
  10. 53
      apps/block_scout_web/lib/block_scout_web/templates/address_internal_transaction/index.html.eex
  11. 53
      apps/block_scout_web/lib/block_scout_web/templates/address_token_transfer/index.html.eex
  12. 1
      apps/block_scout_web/lib/block_scout_web/templates/icons/_check_dark_forest_icon.html.eex
  13. 14
      apps/block_scout_web/lib/block_scout_web/templates/layout/app.html.eex
  14. 4
      apps/block_scout_web/lib/block_scout_web/views/address_view.ex
  15. 22
      apps/block_scout_web/lib/block_scout_web/views/custom_contracts_helpers.ex
  16. 2
      apps/block_scout_web/lib/block_scout_web/views/layout_view.ex

@ -62,7 +62,7 @@
transition: .1s ease-in; transition: .1s ease-in;
position: absolute; position: absolute;
top: 0; top: 0;
right: 59px; right: 56px;
&:hover { &:hover {
color: #333; color: #333;
} }

@ -142,12 +142,20 @@ $dark-primary-alternate: $dark-primary;
} }
} }
.card-tab .fa-check-circle { .check_dark_forest_icon {
color: $dark-primary; margin-left: 10px;
} }
.card-tab.active .fa-check-circle { .card-tab .check_dark_forest_icon {
color: $body-dark; svg path {
fill: $dark-primary;
}
}
.card-tab.active .check_dark_forest_icon {
svg path {
fill: $body-dark;
}
} }
.card-background-1 { .card-background-1 {
@ -259,9 +267,11 @@ $dark-primary-alternate: $dark-primary;
} }
.btn-copy-icon, .btn-qr-icon, .btn-address-card-icon .btn-contract-icon { .btn-copy-icon, .btn-qr-icon, .btn-address-card-icon .btn-contract-icon {
border-radius: 0;
border: none;
border-color: $dark-primary; border-color: $dark-primary;
&:hover { &:hover {
background-color: $labels-dark; background-color: rgba(117, 249, 77, 0.4);
} }
} }
@ -274,7 +284,8 @@ $dark-primary-alternate: $dark-primary;
padding: 15px; padding: 15px;
&:not(.no-hover):hover { &:not(.no-hover):hover {
color: #fff; color: #fff;
background-color: $dark-light-bg; border: 1px solid #fff;
background-color: $dark-primary;
path { path {
fill: #fff; fill: #fff;
} }
@ -466,16 +477,19 @@ $dark-primary-alternate: $dark-primary;
background-color: $dark-light; background-color: $dark-light;
border-color: $dark-light; border-color: $dark-light;
color: #fff; color: #fff;
height: 32px;
border-radius: 0px;
border-color: #fff;
} }
.logs-search-btn { .logs-search-btn {
color: $labels-dark; border: none;
} background-color: $dark-primary;
color: $body-dark;
.logs-search-btn {
&:hover { &:hover {
background-color: $dark-primary; background-color: $dark-primary;
color: #fff; color: $body-dark;
} }
} }
@ -569,9 +583,9 @@ $dark-primary-alternate: $dark-primary;
// Content loading placeholders // Content loading placeholders
.tile-loader, .table-content-loader { .tile-loader, .table-content-loader {
background-color: $labels-dark !important; background-color: rgba(117, 249, 77, 0.4) !important;
&:before { &:before {
background: linear-gradient(to right, $labels-dark 2%, lighten($labels-dark, 3) 18%, $labels-dark 33%); background: linear-gradient(to right, rgba(117, 249, 77, 0.4) 2%, lighten(rgba(117, 249, 77, 0.4), 3) 18%, rgba(117, 249, 77, 0.4) 33%);
} }
} }
@ -714,7 +728,7 @@ $dark-primary-alternate: $dark-primary;
.table-bordered, .table-bordered td, .table-bordered th { .table-bordered, .table-bordered td, .table-bordered th {
border-color: darken($labels-dark, 30); border-color: darken($labels-dark, 30);
} }
.dark-theme-applied .table td, .dark-theme-applied .table th, .dark-theme-applied hr { .dark-forest-theme-applied .table td, .dark-forest-theme-applied .table th, .dark-forest-theme-applied hr {
border-top-color: darken($labels-dark, 30); border-top-color: darken($labels-dark, 30);
} }
.btn-copy-ico svg path { .btn-copy-ico svg path {
@ -918,10 +932,6 @@ $dark-primary-alternate: $dark-primary;
background: $dark-primary; background: $dark-primary;
} }
.fa-check-circle {
content: url(/images/custom-themes/dark-forest/union.svg);
}
.custom-balance-icon { .custom-balance-icon {
content: url(/images/custom-themes/dark-forest/pic_balance.svg); content: url(/images/custom-themes/dark-forest/pic_balance.svg);
margin-right: 0px; margin-right: 0px;
@ -972,6 +982,9 @@ $dark-primary-alternate: $dark-primary;
.application-icon { .application-icon {
content: url(/images/custom-themes/dark-forest/planet.svg); content: url(/images/custom-themes/dark-forest/planet.svg);
&:hover {
background-color: rgba(117, 249, 77, 0.4);
}
@media screen and (max-width: 768px) { @media screen and (max-width: 768px) {
float: right; float: right;
} }
@ -987,18 +1000,18 @@ $dark-primary-alternate: $dark-primary;
border: none; border: none;
} }
.dark-theme-applied .dropdown-item { .dark-forest-theme-applied .dropdown-item {
background-color: $dark-light!important; background-color: $dark-light!important;
color: #fff !important; color: #fff !important;
} }
.dark-theme-applied .dropdown-item.active:not(.header), .dark-theme-applied .dropdown-item:not(.header):hover, .dark-theme-applied .dropdown-item:not(.header):focus { .dark-forest-theme-applied .dropdown-item.active:not(.header), .dark-forest-theme-applied .dropdown-item:not(.header):hover, .dark-forest-theme-applied .dropdown-item:not(.header):focus {
background-image: none; background-image: none;
width: 100%; width: 100%;
background-color: #3f426c !important; background-color: rgba(117, 249, 77, 0.4) !important;
} }
.dark-theme-applied .dropdown-item.active.header, .dark-theme-applied .dropdown-item.header:hover, .dark-theme-applied .dropdown-item.header:focus { .dark-forest-theme-applied .dropdown-item.active.header, .dark-forest-theme-applied .dropdown-item.header:hover, .dark-forest-theme-applied .dropdown-item.header:focus {
background-color: $dark-light !important; background-color: $dark-light !important;
} }

@ -64,7 +64,6 @@ export const hideConnectButton = () => {
} }
}) })
} else { } else {
console.log(window.ethereum.selectedAddress)
resolve({ shouldHide: true, account: window.ethereum.selectedAddress }) resolve({ shouldHide: true, account: window.ethereum.selectedAddress })
} }
} else { } else {

@ -69,12 +69,21 @@ const elements = {
} }
}, },
'[data-selector="channel-batching-count"]': { '[data-selector="channel-batching-count"]': {
render ($el, state, oldState) { render ($el, state) {
const $channelBatching = $('[data-selector="channel-batching-message"]') const $channelBatching = $('[data-selector="channel-batching-message"]')
if (!state.internalTransactionsBatch.length) return $channelBatching.hide() if (!state.internalTransactionsBatch.length) return $channelBatching.hide()
$channelBatching.show() $channelBatching.show()
$el[0].innerHTML = numeral(state.internalTransactionsBatch.length).format() $el[0].innerHTML = numeral(state.internalTransactionsBatch.length).format()
} }
},
'[data-test="filter_dropdown"]': {
render ($el, state) {
if (state.emptyResponse && !state.isSearch) {
return $el.hide()
}
return $el.show()
}
} }
} }

@ -50,6 +50,15 @@ const elements = {
render ($el, state) { render ($el, state) {
if (state.channelDisconnected) $el.show() if (state.channelDisconnected) $el.show()
} }
},
'[data-test="filter_dropdown"]': {
render ($el, state) {
if (state.emptyResponse && !state.isSearch) {
return $el.hide()
}
return $el.show()
}
} }
} }

@ -50,6 +50,15 @@ const elements = {
render ($el, state) { render ($el, state) {
if (state.channelDisconnected) $el.show() if (state.channelDisconnected) $el.show()
} }
},
'[data-test="filter_dropdown"]': {
render ($el, state) {
if (state.emptyResponse && !state.isSearch) {
return $el.hide()
}
return $el.show()
}
} }
} }

@ -42,7 +42,7 @@ config :block_scout_web,
gas_price: System.get_env("GAS_PRICE", nil), gas_price: System.get_env("GAS_PRICE", nil),
restricted_list: System.get_env("RESTRICTED_LIST", nil), restricted_list: System.get_env("RESTRICTED_LIST", nil),
restricted_list_key: System.get_env("RESTRICTED_LIST_KEY", nil), restricted_list_key: System.get_env("RESTRICTED_LIST_KEY", nil),
dark_forest_address: System.get_env("CUSTOM_CONTRACT_ADDRESS_DARK_FOREST") dark_forest_addresses: System.get_env("CUSTOM_CONTRACT_ADDRESSES_DARK_FOREST")
config :block_scout_web, BlockScoutWeb.Counters.BlocksIndexedCounter, enabled: true config :block_scout_web, BlockScoutWeb.Counters.BlocksIndexedCounter, enabled: true

@ -1,3 +1,5 @@
<% dark_forest_addresses_list = CustomContractsHelpers.get_dark_forest_addresses_list() %>
<% current_address = "0x" <> Base.encode16(@address.hash.bytes, case: :lower) %>
<div class="card-tabs js-card-tabs"> <div class="card-tabs js-card-tabs">
<%= link( <%= link(
gettext("Transactions"), gettext("Transactions"),
@ -53,7 +55,14 @@
class: "card-tab #{tab_status("contracts", @conn.request_path)}") do %> class: "card-tab #{tab_status("contracts", @conn.request_path)}") do %>
<%= gettext("Code") %> <%= gettext("Code") %>
<%= if smart_contract_verified?(@address) do %> <%= if smart_contract_verified?(@address) do %>
<i class="far fa-check-circle"></i> <%= cond do %>
<% Enum.member?(dark_forest_addresses_list, current_address) -> %>
<i class="check_dark_forest_icon">
<%= render BlockScoutWeb.IconsView, "_check_dark_forest_icon.html" %>
</i>
<% true -> %>
<i class="far fa-check-circle"></i>
<% end %>
<% end %> <% end %>
<% end %> <% end %>
<% end %> <% end %>

@ -1,6 +1,5 @@
<section class="address-overview" data-page="address-details" data-page-address-hash="<%= @address.hash %>" data-async-counters="<%= @counters_path %>"> <section class="address-overview" data-page="address-details" data-page-address-hash="<%= @address.hash %>" data-async-counters="<%= @counters_path %>">
<% dark_forest_address_var = Application.get_env(:block_scout_web, :dark_forest_address) %> <% dark_forest_addresses_list = CustomContractsHelpers.get_dark_forest_addresses_list() %>
<% dark_forest_address = if dark_forest_address_var, do: String.downcase(dark_forest_address_var), else: nil %>
<% current_address = "0x" <> Base.encode16(@address.hash.bytes, case: :lower) %> <% current_address = "0x" <> Base.encode16(@address.hash.bytes, case: :lower) %>
<div class="row"> <div class="row">
<!-- Address details --> <!-- Address details -->
@ -8,14 +7,24 @@
<div class="card"> <div class="card">
<div class="card-body"> <div class="card-body">
<%= cond do %> <%= cond do %>
<% current_address == dark_forest_address -> %> <% Enum.member?(dark_forest_addresses_list, current_address) -> %>
<div class="custom-dapp-header-container"> <div class="custom-dapp-header-container">
<img class="custom-address-icon"/> <img class="custom-address-icon"/>
<div class="custom-dapp-header-description-container"> <div class="custom-dapp-header-description-container">
<span class="address-detail-item custom-address-details"> <span class="address-detail-item custom-address-details">
<%= gettext "zkSnark space warfare (v0.4)" %> <%= gettext "zkSnark space warfare (v0.4)" %>
</span> </span>
<a href="https://zkga.me/" target="_blank" class="application-icon-link"><img class="application-icon"/></a> <a href="https://zkga.me/" target="_blank" class="application-icon-link">
<span
aria-label='<%= gettext("Play") %>'
class="application-icon"
data-placement="top"
data-toggle="tooltip"
title='<%= gettext("Play") %>'
>
<img class="application-icon"/>
</span>
</a>
</div> </div>
</div> </div>
<% true -> %> <% true -> %>

@ -17,36 +17,37 @@
</div> </div>
<div class="clearfix"> <div class="clearfix">
<h2 class="card-title float-left"><%= gettext "Internal Transactions" %></h2> <h2 class="card-title float-left"><%= gettext "Internal Transactions" %></h2>
<div class="dropdown float-right u-push-sm"> <div class="top-pagination-outer-container float-right">
<button data-test="filter_dropdown" class="btn-dropdown-line dropdown-toggle" type="button" <div class="dropdown u-push-sm">
id="dropdownMenu2" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> <button data-test="filter_dropdown" class="btn-dropdown-line dropdown-toggle" type="button"
Filter: <%= format_current_filter(@filter) %> id="dropdownMenu2" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
</button> Filter: <%= format_current_filter(@filter) %>
<div class="dropdown-menu dropdown-menu-right filter" aria-labelledby="dropdownMenu2"> </button>
<%= link( <div class="dropdown-menu dropdown-menu-right filter" aria-labelledby="dropdownMenu2">
gettext("All"), <%= link(
to: AccessHelpers.get_path(@conn, :address_internal_transaction_path, :index, @address.hash), gettext("All"),
class: "address__link address__link--active dropdown-item", to: AccessHelpers.get_path(@conn, :address_internal_transaction_path, :index, @address.hash),
"data-test": "filter_option" class: "address__link address__link--active dropdown-item",
) %> "data-test": "filter_option"
<%= link( ) %>
gettext("To"), <%= link(
to: AccessHelpers.get_path(@conn, :address_internal_transaction_path, :index, @address.hash, %{:filter => "to"}), gettext("To"),
class: "address__link address__link--active dropdown-item", to: AccessHelpers.get_path(@conn, :address_internal_transaction_path, :index, @address.hash, %{:filter => "to"}),
"data-test": "filter_option" class: "address__link address__link--active dropdown-item",
) %> "data-test": "filter_option"
<%= link( ) %>
gettext("From"), <%= link(
to: AccessHelpers.get_path(@conn, :address_internal_transaction_path, :index, @address.hash, %{:filter => "from"}), gettext("From"),
class: "address__link address__link--active dropdown-item", to: AccessHelpers.get_path(@conn, :address_internal_transaction_path, :index, @address.hash, %{:filter => "from"}),
"data-test": "filter_option" class: "address__link address__link--active dropdown-item",
) %> "data-test": "filter_option"
) %>
</div>
</div> </div>
<%= render BlockScoutWeb.CommonComponentsView, "_pagination_container.html", position: "top", cur_page_number: "1", show_pagination_limit: true, data_next_page_button: true, data_prev_page_button: true %>
</div> </div>
</div> </div>
<%= render BlockScoutWeb.CommonComponentsView, "_pagination_container.html", position: "top", cur_page_number: "1", show_pagination_limit: true, data_next_page_button: true, data_prev_page_button: true %>
<button data-error-message class="alert alert-danger col-12 text-left" style="display: none;"> <button data-error-message class="alert alert-danger col-12 text-left" style="display: none;">
<span href="#" class="alert-link"><%= gettext("Something went wrong, click to reload.") %></span> <span href="#" class="alert-link"><%= gettext("Something went wrong, click to reload.") %></span>
</button> </button>

@ -15,37 +15,38 @@
<%= if !assigns[:token] do %> <%= if !assigns[:token] do %>
<div class="clearfix"> <div class="clearfix">
<h2 class="card-title float-left"><%= gettext "Transactions" %></h2> <h2 class="card-title float-left"><%= gettext "Transactions" %></h2>
<div class="dropdown float-right u-push-sm"> <div class="top-pagination-outer-container float-right">
<button data-test="filter_dropdown" class="btn-dropdown-line dropdown-toggle" type="button" <div class="dropdown u-push-sm">
id="dropdownMenu2" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> <button data-test="filter_dropdown" class="btn-dropdown-line dropdown-toggle" type="button"
Filter: <%= format_current_filter(@filter) %> id="dropdownMenu2" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
</button> Filter: <%= format_current_filter(@filter) %>
<div class="dropdown-menu dropdown-menu-right filter" aria-labelledby="dropdownMenu2"> </button>
<%= link( <div class="dropdown-menu dropdown-menu-right filter" aria-labelledby="dropdownMenu2">
gettext("All"), <%= link(
to: AccessHelpers.get_path(@conn, :address_token_transfers_path, :index, to_string(@address.hash)), gettext("All"),
class: "address__link address__link--active dropdown-item", to: AccessHelpers.get_path(@conn, :address_token_transfers_path, :index, to_string(@address.hash)),
"data-test": "filter_option" class: "address__link address__link--active dropdown-item",
) %> "data-test": "filter_option"
<%= link( ) %>
gettext("To"), <%= link(
to: AccessHelpers.get_path(@conn, :address_token_transfers_path, :index, to_string(@address.hash), %{:filter => "to"}), gettext("To"),
class: "address__link address__link--active dropdown-item", to: AccessHelpers.get_path(@conn, :address_token_transfers_path, :index, to_string(@address.hash), %{:filter => "to"}),
"data-test": "filter_option" class: "address__link address__link--active dropdown-item",
) %> "data-test": "filter_option"
<%= link( ) %>
gettext("From"), <%= link(
to: AccessHelpers.get_path(@conn, :address_token_transfers_path, :index, to_string(@address.hash), %{:filter => "from"}), gettext("From"),
class: "address__link address__link--active dropdown-item", to: AccessHelpers.get_path(@conn, :address_token_transfers_path, :index, to_string(@address.hash), %{:filter => "from"}),
"data-test": "filter_option" class: "address__link address__link--active dropdown-item",
) %> "data-test": "filter_option"
) %>
</div>
</div> </div>
<%= render BlockScoutWeb.CommonComponentsView, "_pagination_container.html", position: "top", cur_page_number: "1", show_pagination_limit: true, data_next_page_button: true, data_prev_page_button: true %>
</div> </div>
</div> </div>
<% end %> <% end %>
<%= render BlockScoutWeb.CommonComponentsView, "_pagination_container.html", position: "top", cur_page_number: "1", show_pagination_limit: true, data_next_page_button: true, data_prev_page_button: true %>
<div data-empty-response-message class="tile tile-muted text-center" style="display: none;"> <div data-empty-response-message class="tile tile-muted text-center" style="display: none;">
<span><%= gettext "There are no token transfers for this address." %></span> <span><%= gettext "There are no token transfers for this address." %></span>
</div> </div>

@ -0,0 +1 @@
<svg fill="none" height="10" viewBox="0 0 14 10" width="14" xmlns="http://www.w3.org/2000/svg"><path d="m1.41421 3.53553-1.41421 1.41422 4.94975 4.94975 8.48525-8.48529-1.4142-1.41421-7.07105 7.07107z" fill="#75f94d"/></svg>

After

Width:  |  Height:  |  Size: 224 B

@ -36,15 +36,17 @@
</head> </head>
<body> <body>
<% dark_forest_address_var = Application.get_env(:block_scout_web, :dark_forest_address) %> <% raw_dark_forest_addresses = CustomContractsHelpers.get_raw_dark_forest_addresses_list() %>
<% dark_forest_address = if dark_forest_address_var, do: String.downcase(dark_forest_address_var), else: nil %>
<script> <script>
function applyCustomMode() { function applyCustomMode() {
const darkForestContractAddressHash = "<%= dark_forest_address %>" const darkForestContractAddressHashes = "<%= raw_dark_forest_addresses %>".split(',').map(hash => hash.toLowerCase())
if (window.location.pathname.toLowerCase().includes(darkForestContractAddressHash)) { darkForestContractAddressHashes.forEach(darkForestContractAddressHash => {
document.body.className += " " + "dark-forest-theme-applied"; if (window.location.pathname.toLowerCase().includes(darkForestContractAddressHash)) {
} document.body.className += " " + "dark-forest-theme-applied";
return;
}
})
} }
function applyDarkMode() { function applyDarkMode() {
if (localStorage.getItem("current-color-mode") === "dark") { if (localStorage.getItem("current-color-mode") === "dark") {

@ -3,7 +3,7 @@ defmodule BlockScoutWeb.AddressView do
require Logger require Logger
alias BlockScoutWeb.{AccessHelpers, LayoutView} alias BlockScoutWeb.{AccessHelpers, CustomContractsHelpers, LayoutView}
alias Explorer.Chain alias Explorer.Chain
alias Explorer.Chain.{Address, Hash, InternalTransaction, SmartContract, Token, TokenTransfer, Transaction, Wei} alias Explorer.Chain.{Address, Hash, InternalTransaction, SmartContract, Token, TokenTransfer, Transaction, Wei}
alias Explorer.Chain.Block.Reward alias Explorer.Chain.Block.Reward
@ -132,7 +132,7 @@ defmodule BlockScoutWeb.AddressView do
do: "" do: ""
def balance_percentage(%Address{fetched_coin_balance: balance}, total_supply) do def balance_percentage(%Address{fetched_coin_balance: balance}, total_supply) do
if total_supply > 0 do if Decimal.cmp(total_supply, 0) == :gt do
balance balance
|> Wei.to(:ether) |> Wei.to(:ether)
|> Decimal.div(Decimal.new(total_supply)) |> Decimal.div(Decimal.new(total_supply))

@ -0,0 +1,22 @@
defmodule BlockScoutWeb.CustomContractsHelpers do
@moduledoc """
Helpers to enable custom contracts themes
"""
def get_dark_forest_addresses_list do
dark_forest_addresses_var = get_raw_dark_forest_addresses_list()
dark_forest_addresses_list = (dark_forest_addresses_var && String.split(dark_forest_addresses_var, ",")) || []
formatted_dark_forest_addresses_list =
dark_forest_addresses_list
|> Enum.map(fn addr ->
String.downcase(addr)
end)
formatted_dark_forest_addresses_list
end
def get_raw_dark_forest_addresses_list do
Application.get_env(:block_scout_web, :dark_forest_addresses)
end
end

@ -31,7 +31,7 @@ defmodule BlockScoutWeb.LayoutView do
} }
] ]
alias BlockScoutWeb.SocialMedia alias BlockScoutWeb.{CustomContractsHelpers, SocialMedia}
def logo do def logo do
Keyword.get(application_config(), :logo) || "/images/blockscout_logo.svg" Keyword.get(application_config(), :logo) || "/images/blockscout_logo.svg"

Loading…
Cancel
Save