Add vertical scroller for tx actions area (draft version)

pull/6582/head
POA 2 years ago
parent d7870eaa03
commit 8c4a19d3ea
  1. 37
      apps/block_scout_web/assets/css/custom-scrollbar.scss
  2. 19
      apps/block_scout_web/assets/js/lib/custom_scrollbar.js
  3. 32
      apps/block_scout_web/assets/package-lock.json
  4. 1
      apps/block_scout_web/assets/package.json
  5. 2
      apps/block_scout_web/assets/webpack.config.js
  6. 7
      apps/block_scout_web/lib/block_scout_web/templates/layout/app.html.eex
  7. 152
      apps/block_scout_web/lib/block_scout_web/templates/transaction/_actions.html.eex
  8. 12
      apps/block_scout_web/lib/block_scout_web/templates/transaction/overview.html.eex

File diff suppressed because one or more lines are too long

@ -0,0 +1,19 @@
import $ from 'jquery'
import 'malihu-custom-scrollbar-plugin/jquery.mCustomScrollbar.concat.min'
$(function() {
$(".mCustomScrollbar").mCustomScrollbar({
callbacks: {
onOverflowY: () => {
$("#txActionsTitle .note").css("display", "block");
},
onOverflowYNone: () => {
$("#txActionsTitle .note").css("display", "none");
}
},
theme: "dark",
autoHideScrollbar: true,
scrollButtons: {enable: false},
scrollbarPosition: "outside"
});
});

@ -44,6 +44,7 @@
"lodash.rangeright": "^4.2.0", "lodash.rangeright": "^4.2.0",
"lodash.reduce": "^4.6.0", "lodash.reduce": "^4.6.0",
"luxon": "^3.1.1", "luxon": "^3.1.1",
"malihu-custom-scrollbar-plugin": "3.1.5",
"moment": "^2.29.4", "moment": "^2.29.4",
"nanomorph": "^5.4.0", "nanomorph": "^5.4.0",
"numeral": "^2.0.6", "numeral": "^2.0.6",
@ -98,10 +99,11 @@
} }
}, },
"../../../deps/phoenix": { "../../../deps/phoenix": {
"version": "0.0.1" "version": "1.5.13",
"license": "MIT"
}, },
"../../../deps/phoenix_html": { "../../../deps/phoenix_html": {
"version": "0.0.1" "version": "3.0.4"
}, },
"node_modules/@ampproject/remapping": { "node_modules/@ampproject/remapping": {
"version": "2.2.0", "version": "2.2.0",
@ -11890,6 +11892,11 @@
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.1.tgz", "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.1.tgz",
"integrity": "sha512-opJeO4nCucVnsjiXOE+/PcCgYw9Gwpvs/a6B1LL/lQhwWwpbVEVYDZ1FokFr8PRc7ghYlrFPuyHuiiDNTQxmcw==" "integrity": "sha512-opJeO4nCucVnsjiXOE+/PcCgYw9Gwpvs/a6B1LL/lQhwWwpbVEVYDZ1FokFr8PRc7ghYlrFPuyHuiiDNTQxmcw=="
}, },
"node_modules/jquery-mousewheel": {
"version": "3.1.13",
"resolved": "https://registry.npmjs.org/jquery-mousewheel/-/jquery-mousewheel-3.1.13.tgz",
"integrity": "sha512-GXhSjfOPyDemM005YCEHvzrEALhKDIswtxSHSR2e4K/suHVJKJxxRCGz3skPjNxjJjQa9AVSGGlYjv1M3VLIPg=="
},
"node_modules/js-base64": { "node_modules/js-base64": {
"version": "2.6.4", "version": "2.6.4",
"resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.6.4.tgz", "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.6.4.tgz",
@ -12587,6 +12594,14 @@
"tmpl": "1.0.5" "tmpl": "1.0.5"
} }
}, },
"node_modules/malihu-custom-scrollbar-plugin": {
"version": "3.1.5",
"resolved": "https://registry.npmjs.org/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-3.1.5.tgz",
"integrity": "sha512-lwW3LgI+CNDMPnP4ED2la6oYxWMkCXlnhex+s2wuOLhFDFGnGmQuTQVdRK9bvDLpxs10sGlfErVufJy9ztfgJQ==",
"dependencies": {
"jquery-mousewheel": ">=3.0.6"
}
},
"node_modules/map-obj": { "node_modules/map-obj": {
"version": "4.3.0", "version": "4.3.0",
"resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz",
@ -27464,6 +27479,11 @@
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.1.tgz", "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.1.tgz",
"integrity": "sha512-opJeO4nCucVnsjiXOE+/PcCgYw9Gwpvs/a6B1LL/lQhwWwpbVEVYDZ1FokFr8PRc7ghYlrFPuyHuiiDNTQxmcw==" "integrity": "sha512-opJeO4nCucVnsjiXOE+/PcCgYw9Gwpvs/a6B1LL/lQhwWwpbVEVYDZ1FokFr8PRc7ghYlrFPuyHuiiDNTQxmcw=="
}, },
"jquery-mousewheel": {
"version": "3.1.13",
"resolved": "https://registry.npmjs.org/jquery-mousewheel/-/jquery-mousewheel-3.1.13.tgz",
"integrity": "sha512-GXhSjfOPyDemM005YCEHvzrEALhKDIswtxSHSR2e4K/suHVJKJxxRCGz3skPjNxjJjQa9AVSGGlYjv1M3VLIPg=="
},
"js-base64": { "js-base64": {
"version": "2.6.4", "version": "2.6.4",
"resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.6.4.tgz", "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.6.4.tgz",
@ -28063,6 +28083,14 @@
"tmpl": "1.0.5" "tmpl": "1.0.5"
} }
}, },
"malihu-custom-scrollbar-plugin": {
"version": "3.1.5",
"resolved": "https://registry.npmjs.org/malihu-custom-scrollbar-plugin/-/malihu-custom-scrollbar-plugin-3.1.5.tgz",
"integrity": "sha512-lwW3LgI+CNDMPnP4ED2la6oYxWMkCXlnhex+s2wuOLhFDFGnGmQuTQVdRK9bvDLpxs10sGlfErVufJy9ztfgJQ==",
"requires": {
"jquery-mousewheel": ">=3.0.6"
}
},
"map-obj": { "map-obj": {
"version": "4.3.0", "version": "4.3.0",
"resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz",

@ -56,6 +56,7 @@
"lodash.rangeright": "^4.2.0", "lodash.rangeright": "^4.2.0",
"lodash.reduce": "^4.6.0", "lodash.reduce": "^4.6.0",
"luxon": "^3.1.1", "luxon": "^3.1.1",
"malihu-custom-scrollbar-plugin": "3.1.5",
"moment": "^2.29.4", "moment": "^2.29.4",
"nanomorph": "^5.4.0", "nanomorph": "^5.4.0",
"numeral": "^2.0.6", "numeral": "^2.0.6",

@ -68,6 +68,8 @@ const appJs =
'text-ad': './js/lib/text_ad.js', 'text-ad': './js/lib/text_ad.js',
'banner': './js/lib/banner.js', 'banner': './js/lib/banner.js',
'autocomplete': './js/lib/autocomplete.js', 'autocomplete': './js/lib/autocomplete.js',
'custom-scrollbar': './js/lib/custom_scrollbar.js',
'custom-scrollbar-styles': './css/custom-scrollbar.scss',
'search-results': './js/pages/search-results/search.js', 'search-results': './js/pages/search-results/search.js',
'token-overview': './js/pages/token/overview.js', 'token-overview': './js/pages/token/overview.js',
'export-csv': './css/export-csv.scss', 'export-csv': './css/export-csv.scss',

@ -11,6 +11,10 @@
<link rel="preload" href="<%= static_path(@conn, "/js/chain.js") %>" as="script"> <link rel="preload" href="<%= static_path(@conn, "/js/chain.js") %>" as="script">
<link rel="preload" href="<%= static_path(@conn, "/js/chart-loader.js") %>" as="script"> <link rel="preload" href="<%= static_path(@conn, "/js/chart-loader.js") %>" as="script">
<link rel="preload" href="<%= static_path(@conn, "/js/token-transfers-toggle.js") %>" as="script"> <link rel="preload" href="<%= static_path(@conn, "/js/token-transfers-toggle.js") %>" as="script">
<% Elixir.BlockScoutWeb.TransactionView -> %>
<link rel="stylesheet" href="<%= static_path(@conn, "/css/app.css") %>">
<link rel="stylesheet" href="<%= static_path(@conn, "/css/custom-scrollbar-styles.css") %>">
<link rel="preload" href="<%= static_path(@conn, "/js/custom-scrollbar.js") %>" as="script">
<% _ -> %> <% _ -> %>
<link rel="stylesheet" href="<%= static_path(@conn, "/css/app.css") %>"> <link rel="stylesheet" href="<%= static_path(@conn, "/css/app.css") %>">
<% end %> <% end %>
@ -297,6 +301,9 @@
<script defer data-cfasync="false" src="<%= static_path(@conn, "/js/chart-loader.js") %>"></script> <script defer data-cfasync="false" src="<%= static_path(@conn, "/js/chart-loader.js") %>"></script>
<script defer data-cfasync="false" src="<%= static_path(@conn, "/js/token-transfers-toggle.js") %>"></script> <script defer data-cfasync="false" src="<%= static_path(@conn, "/js/token-transfers-toggle.js") %>"></script>
<% end %> <% end %>
<%= if @view_module == Elixir.BlockScoutWeb.TransactionView do %>
<script defer data-cfasync="false" src="<%= static_path(@conn, "/js/custom-scrollbar.js") %>"></script>
<% end %>
<script defer src="<%= static_path(@conn, "/js/autocomplete.js") %>"></script> <script defer src="<%= static_path(@conn, "/js/autocomplete.js") %>"></script>
<%= if @view_module in [Elixir.BlockScoutWeb.AddressContractVerificationView, Elixir.BlockScoutWeb.AddressContractVerificationVyperView, Elixir.BlockScoutWeb.AddressContractVerificationViaFlattenedCodeView, Elixir.BlockScoutWeb.AddressContractVerificationViaMultiPartFilesView, Elixir.BlockScoutWeb.AddressContractVerificationViaJsonView, Elixir.BlockScoutWeb.AddressContractVerificationViaStandardJsonInputView] do %> <%= if @view_module in [Elixir.BlockScoutWeb.AddressContractVerificationView, Elixir.BlockScoutWeb.AddressContractVerificationVyperView, Elixir.BlockScoutWeb.AddressContractVerificationViaFlattenedCodeView, Elixir.BlockScoutWeb.AddressContractVerificationViaMultiPartFilesView, Elixir.BlockScoutWeb.AddressContractVerificationViaJsonView, Elixir.BlockScoutWeb.AddressContractVerificationViaStandardJsonInputView] do %>
<script defer data-cfasync="false" src="<%= static_path(@conn, "/js/verification-form.js") %>"></script> <script defer data-cfasync="false" src="<%= static_path(@conn, "/js/verification-form.js") %>"></script>

@ -1,89 +1,93 @@
<%= if @action.protocol == :uniswap_v3 do %> <%= if @action.protocol == :uniswap_v3 do %>
<%= if @action.type == :mint_nft do %> <%= if @action.type == :mint_nft do %>
<span class="actions-item"> <div class="<%= if @isLast, do: "lastItem", else: "" %>">
<i class="fa fa-caret-right"></i> <span class="actions-item">
<i class="fa fa-caret-right"></i>
<% address_string = Map.get(@action.data, "address") %> <% address_string = Map.get(@action.data, "address") %>
<% {address_hash_status, address_hash} = Chain.string_to_address_hash(address_string) %> <% {address_hash_status, address_hash} = Chain.string_to_address_hash(address_string) %>
<% {address_status, address} = Chain.hash_to_address(address_hash) %> <% {address_status, address} = Chain.hash_to_address(address_hash) %>
<% address = if address_hash_status == :ok and address_status == :ok do %> <% address = if address_hash_status == :ok and address_status == :ok do %>
<%= render BlockScoutWeb.AddressView, "_link.html", address: address, contract: BlockScoutWeb.AddressView.contract?(address), use_custom_tooltip: false, trimmed: false %> <%= render BlockScoutWeb.AddressView, "_link.html", address: address, contract: BlockScoutWeb.AddressView.contract?(address), use_custom_tooltip: false, trimmed: false %>
<% else %> <% else %>
<%= link to: address_path(BlockScoutWeb.Endpoint, :show, address_string), "data-test": "address_hash_link" do %> <%= link to: address_path(BlockScoutWeb.Endpoint, :show, address_string), "data-test": "address_hash_link" do %>
<% name = Map.get(@action.data, "name") %> <% name = Map.get(@action.data, "name") %>
<span data-toggle="tooltip" data-placement="top" title="<%= name %>"> <span data-toggle="tooltip" data-placement="top" title="<%= name %>">
<span class="d-none d-md-none d-lg-inline d-xl-inline"><%= AddressView.short_string(name, 15) %></span> <span class="d-none d-md-none d-lg-inline d-xl-inline"><%= AddressView.short_string(name, 15) %></span>
<span class="d-inline d-md-inline d-lg-none d-xl-none"><%= AddressView.short_string(name, 5) %></span> <span class="d-inline d-md-inline d-lg-none d-xl-none"><%= AddressView.short_string(name, 5) %></span>
</span> </span>
<% symbol = Map.get(@action.data, "symbol") %>
<span data-toggle="tooltip" data-placement="top" title="<%= symbol %>">
<span class="d-none d-md-none d-lg-inline d-xl-inline">(<%= AddressView.short_string(symbol, 15) %>)</span>
<span class="d-inline d-md-inline d-lg-none d-xl-none">(<%= AddressView.short_string(symbol, 5) %>)</span>
</span>
<% end %>
<% end %>
<% symbol = Map.get(@action.data, "symbol") %> <% to_address = Map.get(@action.data, "to") %>
<span data-toggle="tooltip" data-placement="top" title="<%= symbol %>"> <% to = link to: address_path(BlockScoutWeb.Endpoint, :show, to_address), "data-test": "address_hash_link" do %>
<span class="d-none d-md-none d-lg-inline d-xl-inline">(<%= AddressView.short_string(symbol, 15) %>)</span> <span data-toggle="tooltip" data-placement="top" title="<%= to_address %>">
<span class="d-inline d-md-inline d-lg-none d-xl-none">(<%= AddressView.short_string(symbol, 5) %>)</span> <span class="d-none d-md-none d-xl-inline"><%= to_address %></span>
<span class="d-md-inline-block d-xl-none"><%= BlockScoutWeb.AddressView.trimmed_hash(to_address) %></span>
</span> </span>
<% end %> <% end %>
<% end %> <%= gettext("Mint of %{address} <span class=\"text-muted\">To</span> %{to}", address: safe_to_string(address), to: safe_to_string(to)) |> raw() %>
</span>
<br />
<% to_address = Map.get(@action.data, "to") %> <% token_ids = Map.get(@action.data, "ids") %>
<% to = link to: address_path(BlockScoutWeb.Endpoint, :show, to_address), "data-test": "address_hash_link" do %> <%= for id <- token_ids do %>
<span data-toggle="tooltip" data-placement="top" title="<%= to_address %>"> <span class="actions-item subitem">
<span class="d-none d-md-none d-xl-inline"><%= to_address %></span> <i class="fa fa-caret-right"></i>
<span class="d-md-inline-block d-xl-none"><%= BlockScoutWeb.AddressView.trimmed_hash(to_address) %></span> <% link_to_id = link id, to: token_instance_path(BlockScoutWeb.Endpoint, :show, address_string, id), "data-test": "token_link" %>
<%= gettext("%{qty} of <span class=\"text-muted\">Token ID [%{link_to_id}]</span>", qty: 1, link_to_id: safe_to_string(link_to_id)) |> raw() %>
</span> </span>
<br />
<% end %> <% end %>
<%= gettext("Mint of %{address} <span class=\"text-muted\">To</span> %{to}", address: safe_to_string(address), to: safe_to_string(to)) |> raw() %> </div>
</span>
<br />
<% token_ids = Map.get(@action.data, "ids") %>
<%= for id <- token_ids do %>
<span class="actions-item subitem">
<i class="fa fa-caret-right"></i>
<% link_to_id = link id, to: token_instance_path(BlockScoutWeb.Endpoint, :show, address_string, id), "data-test": "token_link" %>
<%= gettext("%{qty} of <span class=\"text-muted\">Token ID [%{link_to_id}]</span>", qty: 1, link_to_id: safe_to_string(link_to_id)) |> raw() %>
</span>
<br />
<% end %>
<% end %> <% end %>
<%= if Enum.member?([:mint, :burn, :collect, :swap], @action.type) do %> <%= if Enum.member?([:mint, :burn, :collect, :swap], @action.type) do %>
<span class="actions-item"> <div class="<%= if @isLast, do: "lastItem", else: "" %>">
<% amount0 = Map.get(@action.data, "amount0") %> <span class="actions-item">
<% amount0 = BlockScoutWeb.CldrHelper.Number.to_string!(Decimal.new(amount0), format: "#,##0.##################") %> <% amount0 = Map.get(@action.data, "amount0") %>
<% amount1 = Map.get(@action.data, "amount1") %> <% amount0 = BlockScoutWeb.CldrHelper.Number.to_string!(Decimal.new(amount0), format: "#,##0.##################") %>
<% amount1 = BlockScoutWeb.CldrHelper.Number.to_string!(Decimal.new(amount1), format: "#,##0.##################") %> <% amount1 = Map.get(@action.data, "amount1") %>
<% amount1 = BlockScoutWeb.CldrHelper.Number.to_string!(Decimal.new(amount1), format: "#,##0.##################") %>
<% symbol0 = Map.get(@action.data, "symbol0") %> <% symbol0 = Map.get(@action.data, "symbol0") %>
<% address0 = Map.get(@action.data, "address0") %> <% address0 = Map.get(@action.data, "address0") %>
<% symbol1 = Map.get(@action.data, "symbol1") %> <% symbol1 = Map.get(@action.data, "symbol1") %>
<% address1 = Map.get(@action.data, "address1") %> <% address1 = Map.get(@action.data, "address1") %>
<i class="fa fa-caret-right"></i> <i class="fa fa-caret-right"></i>
<% symbol0 = if symbol0 != "Ether" do %> <% symbol0 = if symbol0 != "Ether" do %>
<%= link(symbol0, to: token_path(BlockScoutWeb.Endpoint, :show, address0), "data-test": "token_link") %> <%= link(symbol0, to: token_path(BlockScoutWeb.Endpoint, :show, address0), "data-test": "token_link") %>
<% else %> <% else %>
<%= symbol0 %> <%= symbol0 %>
<% end %> <% end %>
<% symbol1 = if symbol1 != "Ether" do %> <% symbol1 = if symbol1 != "Ether" do %>
<%= link(symbol1, to: token_path(BlockScoutWeb.Endpoint, :show, address1), "data-test": "token_link") %> <%= link(symbol1, to: token_path(BlockScoutWeb.Endpoint, :show, address1), "data-test": "token_link") %>
<% else %> <% else %>
<%= symbol1 %> <%= symbol1 %>
<% end %> <% end %>
<%= if @action.type == :mint do %> <%= if @action.type == :mint do %>
<%= gettext("<span class=\"text-muted\">Add</span> %{amount0} %{symbol0} <span class=\"text-muted\">And</span> %{amount1} %{symbol1} <span class=\"text-muted\">Liquidity To Uniswap V3</span>", amount0: amount0, symbol0: safe_to_string(symbol0), amount1: amount1, symbol1: safe_to_string(symbol1)) |> raw() %> <%= gettext("<span class=\"text-muted\">Add</span> %{amount0} %{symbol0} <span class=\"text-muted\">And</span> %{amount1} %{symbol1} <span class=\"text-muted\">Liquidity To Uniswap V3</span>", amount0: amount0, symbol0: safe_to_string(symbol0), amount1: amount1, symbol1: safe_to_string(symbol1)) |> raw() %>
<% end %> <% end %>
<%= if @action.type == :burn do %> <%= if @action.type == :burn do %>
<%= gettext("<span class=\"text-muted\">Remove</span> %{amount0} %{symbol0} <span class=\"text-muted\">And</span> %{amount1} %{symbol1} <span class=\"text-muted\">Liquidity From Uniswap V3</span>", amount0: amount0, symbol0: safe_to_string(symbol0), amount1: amount1, symbol1: safe_to_string(symbol1)) |> raw() %> <%= gettext("<span class=\"text-muted\">Remove</span> %{amount0} %{symbol0} <span class=\"text-muted\">And</span> %{amount1} %{symbol1} <span class=\"text-muted\">Liquidity From Uniswap V3</span>", amount0: amount0, symbol0: safe_to_string(symbol0), amount1: amount1, symbol1: safe_to_string(symbol1)) |> raw() %>
<% end %> <% end %>
<%= if @action.type == :collect do %> <%= if @action.type == :collect do %>
<%= gettext("<span class=\"text-muted\">Collect</span> %{amount0} %{symbol0} <span class=\"text-muted\">And</span> %{amount1} %{symbol1} <span class=\"text-muted\">From Uniswap V3</span>", amount0: amount0, symbol0: safe_to_string(symbol0), amount1: amount1, symbol1: safe_to_string(symbol1)) |> raw() %> <%= gettext("<span class=\"text-muted\">Collect</span> %{amount0} %{symbol0} <span class=\"text-muted\">And</span> %{amount1} %{symbol1} <span class=\"text-muted\">From Uniswap V3</span>", amount0: amount0, symbol0: safe_to_string(symbol0), amount1: amount1, symbol1: safe_to_string(symbol1)) |> raw() %>
<% end %> <% end %>
<%= if @action.type == :swap do %> <%= if @action.type == :swap do %>
<%= gettext("<span class=\"text-muted\">Swap</span> %{amount0} %{symbol0} <span class=\"text-muted\">For</span> %{amount1} %{symbol1} <span class=\"text-muted\">On Uniswap V3</span>", amount0: amount0, symbol0: safe_to_string(symbol0), amount1: amount1, symbol1: safe_to_string(symbol1)) |> raw() %> <%= gettext("<span class=\"text-muted\">Swap</span> %{amount0} %{symbol0} <span class=\"text-muted\">For</span> %{amount1} %{symbol1} <span class=\"text-muted\">On Uniswap V3</span>", amount0: amount0, symbol0: safe_to_string(symbol0), amount1: amount1, symbol1: safe_to_string(symbol1)) |> raw() %>
<% end %> <% end %>
</span> </span>
<br /> <br />
</div>
<% end %> <% end %>
<% end %> <% end %>

@ -201,9 +201,15 @@
text: gettext("Highlighted events of the transaction.") %> text: gettext("Highlighted events of the transaction.") %>
<%= gettext "Transaction Action" %></dt> <%= gettext "Transaction Action" %></dt>
<dd class="col-sm-9 col-lg-10 actions-list-mobile-container"> <dd class="col-sm-9 col-lg-10 actions-list-mobile-container">
<%= for action <- transaction_actions do %> <div class="mCustomScrollbar" style="max-height:100px;width:90%">
<%= render BlockScoutWeb.TransactionView, "_actions.html", Map.put(assigns, :action, action) %> <% transaction_actions_indexed = Enum.with_index(transaction_actions) %>
<% end %> <% transaction_actions_length = Enum.count(transaction_actions) %>
<%= for {action, i} <- transaction_actions_indexed do %>
<% action_assigns = Map.put(assigns, :action, action) %>
<% action_assigns = Map.put(action_assigns, :isLast, (i == transaction_actions_length - 1)) %>
<%= render BlockScoutWeb.TransactionView, "_actions.html", action_assigns %>
<% end %>
</div>
</dd> </dd>
</dl> </dl>
<% end %> <% end %>

Loading…
Cancel
Save