diff --git a/assets/gif/coins/bitcoin/kiss.gif b/assets/gif/coins/bitcoin/kiss.gif
new file mode 100644
index 000000000..8649f857d
Binary files /dev/null and b/assets/gif/coins/bitcoin/kiss.gif differ
diff --git a/assets/gif/coins/bitcoin/plain.gif b/assets/gif/coins/bitcoin/plain.gif
new file mode 100644
index 000000000..5f3680219
Binary files /dev/null and b/assets/gif/coins/bitcoin/plain.gif differ
diff --git a/assets/gif/coins/bitcoincash/kiss.gif b/assets/gif/coins/bitcoincash/kiss.gif
new file mode 100644
index 000000000..bbd5924b1
Binary files /dev/null and b/assets/gif/coins/bitcoincash/kiss.gif differ
diff --git a/assets/gif/coins/bitcoincash/plain.gif b/assets/gif/coins/bitcoincash/plain.gif
new file mode 100644
index 000000000..4c8d29c77
Binary files /dev/null and b/assets/gif/coins/bitcoincash/plain.gif differ
diff --git a/assets/gif/coins/dogecoin/kiss.gif b/assets/gif/coins/dogecoin/kiss.gif
new file mode 100644
index 000000000..d0f1ffba4
Binary files /dev/null and b/assets/gif/coins/dogecoin/kiss.gif differ
diff --git a/assets/gif/coins/dogecoin/plain.gif b/assets/gif/coins/dogecoin/plain.gif
new file mode 100644
index 000000000..9ce1fbb7a
Binary files /dev/null and b/assets/gif/coins/dogecoin/plain.gif differ
diff --git a/assets/gif/coins/epicCash/kiss.gif b/assets/gif/coins/epicCash/kiss.gif
new file mode 100644
index 000000000..ef8f27fab
Binary files /dev/null and b/assets/gif/coins/epicCash/kiss.gif differ
diff --git a/assets/gif/coins/epicCash/plain.gif b/assets/gif/coins/epicCash/plain.gif
new file mode 100644
index 000000000..4a05889af
Binary files /dev/null and b/assets/gif/coins/epicCash/plain.gif differ
diff --git a/assets/gif/coins/ethereum/kiss.gif b/assets/gif/coins/ethereum/kiss.gif
new file mode 100644
index 000000000..712834662
Binary files /dev/null and b/assets/gif/coins/ethereum/kiss.gif differ
diff --git a/assets/gif/coins/ethereum/plain.gif b/assets/gif/coins/ethereum/plain.gif
new file mode 100644
index 000000000..0da0eeb64
Binary files /dev/null and b/assets/gif/coins/ethereum/plain.gif differ
diff --git a/assets/gif/coins/firo/kiss.gif b/assets/gif/coins/firo/kiss.gif
new file mode 100644
index 000000000..0225077db
Binary files /dev/null and b/assets/gif/coins/firo/kiss.gif differ
diff --git a/assets/gif/coins/firo/plain.gif b/assets/gif/coins/firo/plain.gif
new file mode 100644
index 000000000..3d2f9b620
Binary files /dev/null and b/assets/gif/coins/firo/plain.gif differ
diff --git a/assets/gif/coins/litecoin/kiss.gif b/assets/gif/coins/litecoin/kiss.gif
new file mode 100644
index 000000000..68272d06d
Binary files /dev/null and b/assets/gif/coins/litecoin/kiss.gif differ
diff --git a/assets/gif/coins/litecoin/plain.gif b/assets/gif/coins/litecoin/plain.gif
new file mode 100644
index 000000000..5c12d94bf
Binary files /dev/null and b/assets/gif/coins/litecoin/plain.gif differ
diff --git a/assets/gif/coins/monero/kiss.gif b/assets/gif/coins/monero/kiss.gif
new file mode 100644
index 000000000..b54fb2096
Binary files /dev/null and b/assets/gif/coins/monero/kiss.gif differ
diff --git a/assets/gif/coins/monero/plain.gif b/assets/gif/coins/monero/plain.gif
new file mode 100644
index 000000000..5090eefc2
Binary files /dev/null and b/assets/gif/coins/monero/plain.gif differ
diff --git a/assets/gif/coins/namecoin/kiss.gif b/assets/gif/coins/namecoin/kiss.gif
new file mode 100644
index 000000000..10b74b356
Binary files /dev/null and b/assets/gif/coins/namecoin/kiss.gif differ
diff --git a/assets/gif/coins/namecoin/plain.gif b/assets/gif/coins/namecoin/plain.gif
new file mode 100644
index 000000000..954fa0046
Binary files /dev/null and b/assets/gif/coins/namecoin/plain.gif differ
diff --git a/assets/gif/coins/particl/kiss.gif b/assets/gif/coins/particl/kiss.gif
new file mode 100644
index 000000000..0cc80c1c8
Binary files /dev/null and b/assets/gif/coins/particl/kiss.gif differ
diff --git a/assets/gif/coins/particl/plain.gif b/assets/gif/coins/particl/plain.gif
new file mode 100644
index 000000000..99d36ef9c
Binary files /dev/null and b/assets/gif/coins/particl/plain.gif differ
diff --git a/assets/gif/coins/wownero/kiss.gif b/assets/gif/coins/wownero/kiss.gif
new file mode 100644
index 000000000..16c1c1fdc
Binary files /dev/null and b/assets/gif/coins/wownero/kiss.gif differ
diff --git a/assets/gif/coins/wownero/plain.gif b/assets/gif/coins/wownero/plain.gif
new file mode 100644
index 000000000..0c30a857f
Binary files /dev/null and b/assets/gif/coins/wownero/plain.gif differ
diff --git a/assets/images/ethereum2.svg b/assets/images/ethereum2.svg
deleted file mode 100644
index df9a44d1e..000000000
--- a/assets/images/ethereum2.svg
+++ /dev/null
@@ -1,174 +0,0 @@
-
diff --git a/assets/images/oceanBreeze/stack.png b/assets/images/oceanBreeze/stack.png
deleted file mode 100644
index b59af1608..000000000
Binary files a/assets/images/oceanBreeze/stack.png and /dev/null differ
diff --git a/assets/images/unclaimed.png b/assets/images/unclaimed.png
deleted file mode 100644
index f99d4ab2a..000000000
Binary files a/assets/images/unclaimed.png and /dev/null differ
diff --git a/assets/lottie/test.json b/assets/lottie/test.json
deleted file mode 100644
index a8130f1da..000000000
--- a/assets/lottie/test.json
+++ /dev/null
@@ -1 +0,0 @@
-{"v":"4.8.0","meta":{"g":"LottieFiles AE ","a":"","k":"","d":"","tc":""},"fr":25,"ip":0,"op":75,"w":600,"h":600,"nm":"stack-test-1","ddd":0,"assets":[{"id":"image_0","w":171,"h":171,"u":"","p":"data:image/png;base64,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","e":1}],"layers":[{"ddd":0,"ind":1,"ty":2,"nm":"stack-icon.ai","cl":"ai","refId":"image_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[306,304,0],"to":[0,4,0],"ti":[0,4.167,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":26,"s":[306,328,0],"to":[0,-4.167,0],"ti":[0,4,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":50,"s":[306,279,0],"to":[0,-4,0],"ti":[0,-4.167,0]},{"t":75,"s":[306,304,0]}],"ix":2,"x":"var $bm_rt;\n$bm_rt = transform.position;"},"a":{"a":0,"k":[85.5,85.5,0],"ix":1},"s":{"a":0,"k":[269.591,269.591,100],"ix":6}},"ao":0,"ip":0,"op":750,"st":0,"bm":0}],"markers":[]}
\ No newline at end of file
diff --git a/assets/svg/chanstheme.svg b/assets/svg/chanstheme.svg
new file mode 100644
index 000000000..0a94d5f57
--- /dev/null
+++ b/assets/svg/chanstheme.svg
@@ -0,0 +1,12 @@
+
+
+
diff --git a/assets/svg/fruitSorbet/persona-easy-1.png b/assets/svg/fruitSorbet/persona-easy-1.png
deleted file mode 100644
index f2dd39e2f..000000000
Binary files a/assets/svg/fruitSorbet/persona-easy-1.png and /dev/null differ
diff --git a/assets/svg/fruitSorbet/persona-incognito-1.png b/assets/svg/fruitSorbet/persona-incognito-1.png
deleted file mode 100644
index 16465fcff..000000000
Binary files a/assets/svg/fruitSorbet/persona-incognito-1.png and /dev/null differ
diff --git a/assets/svg/list-ul.svg b/assets/svg/list-ul.svg
new file mode 100644
index 000000000..f5cef4eae
--- /dev/null
+++ b/assets/svg/list-ul.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/svg/oceanBreeze/persona-easy-1.png b/assets/svg/oceanBreeze/persona-easy-1.png
deleted file mode 100644
index 20cafb519..000000000
Binary files a/assets/svg/oceanBreeze/persona-easy-1.png and /dev/null differ
diff --git a/assets/svg/oceanBreeze/persona-easy-1.svg b/assets/svg/oceanBreeze/persona-easy-1.svg
deleted file mode 100644
index f21e19345..000000000
--- a/assets/svg/oceanBreeze/persona-easy-1.svg
+++ /dev/null
@@ -1,123 +0,0 @@
-
diff --git a/assets/svg/oceanBreeze/persona-incognito-1.png b/assets/svg/oceanBreeze/persona-incognito-1.png
deleted file mode 100644
index 8453cfa76..000000000
Binary files a/assets/svg/oceanBreeze/persona-incognito-1.png and /dev/null differ
diff --git a/assets/svg/oceanBreeze/persona-incognito-1.svg b/assets/svg/oceanBreeze/persona-incognito-1.svg
deleted file mode 100644
index a8037e997..000000000
--- a/assets/svg/oceanBreeze/persona-incognito-1.svg
+++ /dev/null
@@ -1,107 +0,0 @@
-
diff --git a/assets/svg/oledBlack/persona-easy-1.svg b/assets/svg/oledBlack/persona-easy-1.svg
deleted file mode 100644
index 1e15b8dab..000000000
--- a/assets/svg/oledBlack/persona-easy-1.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/assets/svg/oledBlack/persona-incognito-1.svg b/assets/svg/oledBlack/persona-incognito-1.svg
deleted file mode 100644
index c31c285b1..000000000
--- a/assets/svg/oledBlack/persona-incognito-1.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/assets/svg/dark/bell-new.svg b/assets/svg/themed/dark/bell-new.svg
similarity index 100%
rename from assets/svg/dark/bell-new.svg
rename to assets/svg/themed/dark/bell-new.svg
diff --git a/assets/images/dark/bitcoin.svg b/assets/svg/themed/dark/bitcoin.svg
similarity index 100%
rename from assets/images/dark/bitcoin.svg
rename to assets/svg/themed/dark/bitcoin.svg
diff --git a/assets/images/dark/bitcoincash.svg b/assets/svg/themed/dark/bitcoincash.svg
similarity index 100%
rename from assets/images/dark/bitcoincash.svg
rename to assets/svg/themed/dark/bitcoincash.svg
diff --git a/assets/svg/dark/buy-coins-icon.svg b/assets/svg/themed/dark/buy-coins-icon.svg
similarity index 100%
rename from assets/svg/dark/buy-coins-icon.svg
rename to assets/svg/themed/dark/buy-coins-icon.svg
diff --git a/assets/images/dark/doge.svg b/assets/svg/themed/dark/doge.svg
similarity index 100%
rename from assets/images/dark/doge.svg
rename to assets/svg/themed/dark/doge.svg
diff --git a/assets/images/dark/epic-cash.svg b/assets/svg/themed/dark/epic-cash.svg
similarity index 100%
rename from assets/images/dark/epic-cash.svg
rename to assets/svg/themed/dark/epic-cash.svg
diff --git a/assets/svg/dark/exchange-2.svg b/assets/svg/themed/dark/exchange-2.svg
similarity index 100%
rename from assets/svg/dark/exchange-2.svg
rename to assets/svg/themed/dark/exchange-2.svg
diff --git a/assets/images/dark/firo.svg b/assets/svg/themed/dark/firo.svg
similarity index 100%
rename from assets/images/dark/firo.svg
rename to assets/svg/themed/dark/firo.svg
diff --git a/assets/images/dark/litecoin.svg b/assets/svg/themed/dark/litecoin.svg
similarity index 100%
rename from assets/images/dark/litecoin.svg
rename to assets/svg/themed/dark/litecoin.svg
diff --git a/assets/images/dark/monero.svg b/assets/svg/themed/dark/monero.svg
similarity index 100%
rename from assets/images/dark/monero.svg
rename to assets/svg/themed/dark/monero.svg
diff --git a/assets/images/dark/namecoin.svg b/assets/svg/themed/dark/namecoin.svg
similarity index 100%
rename from assets/images/dark/namecoin.svg
rename to assets/svg/themed/dark/namecoin.svg
diff --git a/assets/images/dark/particl.svg b/assets/svg/themed/dark/particl.svg
similarity index 100%
rename from assets/images/dark/particl.svg
rename to assets/svg/themed/dark/particl.svg
diff --git a/assets/svg/dark/persona-easy-1.svg b/assets/svg/themed/dark/persona-easy-1.svg
similarity index 100%
rename from assets/svg/dark/persona-easy-1.svg
rename to assets/svg/themed/dark/persona-easy-1.svg
diff --git a/assets/svg/dark/persona-incognito-1.svg b/assets/svg/themed/dark/persona-incognito-1.svg
similarity index 100%
rename from assets/svg/dark/persona-incognito-1.svg
rename to assets/svg/themed/dark/persona-incognito-1.svg
diff --git a/assets/svg/dark/stack-icon1.svg b/assets/svg/themed/dark/stack-icon1.svg
similarity index 100%
rename from assets/svg/dark/stack-icon1.svg
rename to assets/svg/themed/dark/stack-icon1.svg
diff --git a/assets/images/dark/stack.svg b/assets/svg/themed/dark/stack.svg
similarity index 100%
rename from assets/images/dark/stack.svg
rename to assets/svg/themed/dark/stack.svg
index 22dce4736..94929475d 100644
--- a/assets/images/dark/stack.svg
+++ b/assets/svg/themed/dark/stack.svg
@@ -1,4 +1,10 @@
diff --git a/assets/svg/dark/tx-exchange-icon-failed.svg b/assets/svg/themed/dark/tx-exchange-icon-failed.svg
similarity index 100%
rename from assets/svg/dark/tx-exchange-icon-failed.svg
rename to assets/svg/themed/dark/tx-exchange-icon-failed.svg
diff --git a/assets/svg/dark/tx-exchange-icon-pending.svg b/assets/svg/themed/dark/tx-exchange-icon-pending.svg
similarity index 100%
rename from assets/svg/dark/tx-exchange-icon-pending.svg
rename to assets/svg/themed/dark/tx-exchange-icon-pending.svg
diff --git a/assets/svg/dark/tx-exchange-icon.svg b/assets/svg/themed/dark/tx-exchange-icon.svg
similarity index 100%
rename from assets/svg/dark/tx-exchange-icon.svg
rename to assets/svg/themed/dark/tx-exchange-icon.svg
diff --git a/assets/svg/dark/tx-icon-receive-failed.svg b/assets/svg/themed/dark/tx-icon-receive-failed.svg
similarity index 100%
rename from assets/svg/dark/tx-icon-receive-failed.svg
rename to assets/svg/themed/dark/tx-icon-receive-failed.svg
diff --git a/assets/svg/dark/tx-icon-receive-pending.svg b/assets/svg/themed/dark/tx-icon-receive-pending.svg
similarity index 100%
rename from assets/svg/dark/tx-icon-receive-pending.svg
rename to assets/svg/themed/dark/tx-icon-receive-pending.svg
diff --git a/assets/svg/dark/tx-icon-receive.svg b/assets/svg/themed/dark/tx-icon-receive.svg
similarity index 100%
rename from assets/svg/dark/tx-icon-receive.svg
rename to assets/svg/themed/dark/tx-icon-receive.svg
diff --git a/assets/svg/dark/tx-icon-send-failed.svg b/assets/svg/themed/dark/tx-icon-send-failed.svg
similarity index 100%
rename from assets/svg/dark/tx-icon-send-failed.svg
rename to assets/svg/themed/dark/tx-icon-send-failed.svg
diff --git a/assets/svg/dark/tx-icon-send-pending.svg b/assets/svg/themed/dark/tx-icon-send-pending.svg
similarity index 100%
rename from assets/svg/dark/tx-icon-send-pending.svg
rename to assets/svg/themed/dark/tx-icon-send-pending.svg
diff --git a/assets/svg/dark/tx-icon-send.svg b/assets/svg/themed/dark/tx-icon-send.svg
similarity index 100%
rename from assets/svg/dark/tx-icon-send.svg
rename to assets/svg/themed/dark/tx-icon-send.svg
diff --git a/assets/images/dark/wownero.svg b/assets/svg/themed/dark/wownero.svg
similarity index 100%
rename from assets/images/dark/wownero.svg
rename to assets/svg/themed/dark/wownero.svg
diff --git a/assets/svg/forest/bell-new.svg b/assets/svg/themed/forest/bell-new.svg
similarity index 100%
rename from assets/svg/forest/bell-new.svg
rename to assets/svg/themed/forest/bell-new.svg
diff --git a/assets/svg/forest/bg.svg b/assets/svg/themed/forest/bg.svg
similarity index 100%
rename from assets/svg/forest/bg.svg
rename to assets/svg/themed/forest/bg.svg
diff --git a/assets/images/forest/bitcoin.svg b/assets/svg/themed/forest/bitcoin.svg
similarity index 100%
rename from assets/images/forest/bitcoin.svg
rename to assets/svg/themed/forest/bitcoin.svg
diff --git a/assets/images/forest/bitcoincash.svg b/assets/svg/themed/forest/bitcoincash.svg
similarity index 100%
rename from assets/images/forest/bitcoincash.svg
rename to assets/svg/themed/forest/bitcoincash.svg
diff --git a/assets/svg/forest/buy-coins-icon.svg b/assets/svg/themed/forest/buy-coins-icon.svg
similarity index 100%
rename from assets/svg/forest/buy-coins-icon.svg
rename to assets/svg/themed/forest/buy-coins-icon.svg
diff --git a/assets/images/forest/doge.svg b/assets/svg/themed/forest/doge.svg
similarity index 100%
rename from assets/images/forest/doge.svg
rename to assets/svg/themed/forest/doge.svg
diff --git a/assets/images/forest/epic-cash.svg b/assets/svg/themed/forest/epic-cash.svg
similarity index 100%
rename from assets/images/forest/epic-cash.svg
rename to assets/svg/themed/forest/epic-cash.svg
diff --git a/assets/images/forest/ethereum.svg b/assets/svg/themed/forest/ethereum.svg
similarity index 100%
rename from assets/images/forest/ethereum.svg
rename to assets/svg/themed/forest/ethereum.svg
diff --git a/assets/svg/forest/exchange-2.svg b/assets/svg/themed/forest/exchange-2.svg
similarity index 100%
rename from assets/svg/forest/exchange-2.svg
rename to assets/svg/themed/forest/exchange-2.svg
diff --git a/assets/images/forest/firo.svg b/assets/svg/themed/forest/firo.svg
similarity index 100%
rename from assets/images/forest/firo.svg
rename to assets/svg/themed/forest/firo.svg
diff --git a/assets/images/forest/litecoin.svg b/assets/svg/themed/forest/litecoin.svg
similarity index 100%
rename from assets/images/forest/litecoin.svg
rename to assets/svg/themed/forest/litecoin.svg
diff --git a/assets/images/forest/monero.svg b/assets/svg/themed/forest/monero.svg
similarity index 100%
rename from assets/images/forest/monero.svg
rename to assets/svg/themed/forest/monero.svg
diff --git a/assets/images/forest/namecoin.svg b/assets/svg/themed/forest/namecoin.svg
similarity index 100%
rename from assets/images/forest/namecoin.svg
rename to assets/svg/themed/forest/namecoin.svg
diff --git a/assets/images/forest/particl.svg b/assets/svg/themed/forest/particl.svg
similarity index 100%
rename from assets/images/forest/particl.svg
rename to assets/svg/themed/forest/particl.svg
diff --git a/assets/svg/forest/persona-easy-1.svg b/assets/svg/themed/forest/persona-easy-1.svg
similarity index 100%
rename from assets/svg/forest/persona-easy-1.svg
rename to assets/svg/themed/forest/persona-easy-1.svg
diff --git a/assets/svg/forest/persona-incognito-1.svg b/assets/svg/themed/forest/persona-incognito-1.svg
similarity index 100%
rename from assets/svg/forest/persona-incognito-1.svg
rename to assets/svg/themed/forest/persona-incognito-1.svg
diff --git a/assets/svg/forest/stack-icon1.svg b/assets/svg/themed/forest/stack-icon1.svg
similarity index 100%
rename from assets/svg/forest/stack-icon1.svg
rename to assets/svg/themed/forest/stack-icon1.svg
diff --git a/assets/images/forest/stack.svg b/assets/svg/themed/forest/stack.svg
similarity index 100%
rename from assets/images/forest/stack.svg
rename to assets/svg/themed/forest/stack.svg
diff --git a/assets/svg/forest/tx-exchange-icon-failed.svg b/assets/svg/themed/forest/tx-exchange-icon-failed.svg
similarity index 100%
rename from assets/svg/forest/tx-exchange-icon-failed.svg
rename to assets/svg/themed/forest/tx-exchange-icon-failed.svg
diff --git a/assets/svg/forest/tx-exchange-icon-pending.svg b/assets/svg/themed/forest/tx-exchange-icon-pending.svg
similarity index 100%
rename from assets/svg/forest/tx-exchange-icon-pending.svg
rename to assets/svg/themed/forest/tx-exchange-icon-pending.svg
diff --git a/assets/svg/forest/tx-exchange-icon.svg b/assets/svg/themed/forest/tx-exchange-icon.svg
similarity index 100%
rename from assets/svg/forest/tx-exchange-icon.svg
rename to assets/svg/themed/forest/tx-exchange-icon.svg
diff --git a/assets/svg/forest/tx-icon-receive-failed.svg b/assets/svg/themed/forest/tx-icon-receive-failed.svg
similarity index 100%
rename from assets/svg/forest/tx-icon-receive-failed.svg
rename to assets/svg/themed/forest/tx-icon-receive-failed.svg
diff --git a/assets/svg/forest/tx-icon-receive-pending.svg b/assets/svg/themed/forest/tx-icon-receive-pending.svg
similarity index 100%
rename from assets/svg/forest/tx-icon-receive-pending.svg
rename to assets/svg/themed/forest/tx-icon-receive-pending.svg
diff --git a/assets/svg/forest/tx-icon-receive.svg b/assets/svg/themed/forest/tx-icon-receive.svg
similarity index 100%
rename from assets/svg/forest/tx-icon-receive.svg
rename to assets/svg/themed/forest/tx-icon-receive.svg
diff --git a/assets/svg/forest/tx-icon-send-failed.svg b/assets/svg/themed/forest/tx-icon-send-failed.svg
similarity index 100%
rename from assets/svg/forest/tx-icon-send-failed.svg
rename to assets/svg/themed/forest/tx-icon-send-failed.svg
diff --git a/assets/svg/forest/tx-icon-send-pending.svg b/assets/svg/themed/forest/tx-icon-send-pending.svg
similarity index 100%
rename from assets/svg/forest/tx-icon-send-pending.svg
rename to assets/svg/themed/forest/tx-icon-send-pending.svg
diff --git a/assets/svg/forest/tx-icon-send.svg b/assets/svg/themed/forest/tx-icon-send.svg
similarity index 100%
rename from assets/svg/forest/tx-icon-send.svg
rename to assets/svg/themed/forest/tx-icon-send.svg
diff --git a/assets/images/forest/wownero.svg b/assets/svg/themed/forest/wownero.svg
similarity index 100%
rename from assets/images/forest/wownero.svg
rename to assets/svg/themed/forest/wownero.svg
diff --git a/assets/svg/fruitSorbet/bell-new.svg b/assets/svg/themed/fruitSorbet/bell-new.svg
similarity index 100%
rename from assets/svg/fruitSorbet/bell-new.svg
rename to assets/svg/themed/fruitSorbet/bell-new.svg
diff --git a/assets/svg/fruitSorbet/bg.svg b/assets/svg/themed/fruitSorbet/bg.svg
similarity index 100%
rename from assets/svg/fruitSorbet/bg.svg
rename to assets/svg/themed/fruitSorbet/bg.svg
diff --git a/assets/images/fruitSorbet/bitcoin.svg b/assets/svg/themed/fruitSorbet/bitcoin.svg
similarity index 100%
rename from assets/images/fruitSorbet/bitcoin.svg
rename to assets/svg/themed/fruitSorbet/bitcoin.svg
diff --git a/assets/images/fruitSorbet/bitcoincash.svg b/assets/svg/themed/fruitSorbet/bitcoincash.svg
similarity index 100%
rename from assets/images/fruitSorbet/bitcoincash.svg
rename to assets/svg/themed/fruitSorbet/bitcoincash.svg
diff --git a/assets/svg/fruitSorbet/buy-coins-icon.svg b/assets/svg/themed/fruitSorbet/buy-coins-icon.svg
similarity index 100%
rename from assets/svg/fruitSorbet/buy-coins-icon.svg
rename to assets/svg/themed/fruitSorbet/buy-coins-icon.svg
diff --git a/assets/images/fruitSorbet/doge.svg b/assets/svg/themed/fruitSorbet/doge.svg
similarity index 100%
rename from assets/images/fruitSorbet/doge.svg
rename to assets/svg/themed/fruitSorbet/doge.svg
diff --git a/assets/images/fruitSorbet/epic-cash.svg b/assets/svg/themed/fruitSorbet/epic-cash.svg
similarity index 100%
rename from assets/images/fruitSorbet/epic-cash.svg
rename to assets/svg/themed/fruitSorbet/epic-cash.svg
diff --git a/assets/svg/fruitSorbet/exchange-2.svg b/assets/svg/themed/fruitSorbet/exchange-2.svg
similarity index 100%
rename from assets/svg/fruitSorbet/exchange-2.svg
rename to assets/svg/themed/fruitSorbet/exchange-2.svg
diff --git a/assets/images/fruitSorbet/firo.svg b/assets/svg/themed/fruitSorbet/firo.svg
similarity index 100%
rename from assets/images/fruitSorbet/firo.svg
rename to assets/svg/themed/fruitSorbet/firo.svg
diff --git a/assets/images/fruitSorbet/litecoin.svg b/assets/svg/themed/fruitSorbet/litecoin.svg
similarity index 100%
rename from assets/images/fruitSorbet/litecoin.svg
rename to assets/svg/themed/fruitSorbet/litecoin.svg
diff --git a/assets/images/fruitSorbet/monero.svg b/assets/svg/themed/fruitSorbet/monero.svg
similarity index 100%
rename from assets/images/fruitSorbet/monero.svg
rename to assets/svg/themed/fruitSorbet/monero.svg
diff --git a/assets/images/fruitSorbet/namecoin.svg b/assets/svg/themed/fruitSorbet/namecoin.svg
similarity index 100%
rename from assets/images/fruitSorbet/namecoin.svg
rename to assets/svg/themed/fruitSorbet/namecoin.svg
diff --git a/assets/images/fruitSorbet/particl.svg b/assets/svg/themed/fruitSorbet/particl.svg
similarity index 100%
rename from assets/images/fruitSorbet/particl.svg
rename to assets/svg/themed/fruitSorbet/particl.svg
diff --git a/assets/svg/themed/fruitSorbet/persona-easy-1.svg b/assets/svg/themed/fruitSorbet/persona-easy-1.svg
new file mode 100644
index 000000000..041c775fb
--- /dev/null
+++ b/assets/svg/themed/fruitSorbet/persona-easy-1.svg
@@ -0,0 +1,225 @@
+
+
+
diff --git a/assets/svg/themed/fruitSorbet/persona-incognito-1.svg b/assets/svg/themed/fruitSorbet/persona-incognito-1.svg
new file mode 100644
index 000000000..6602556f9
--- /dev/null
+++ b/assets/svg/themed/fruitSorbet/persona-incognito-1.svg
@@ -0,0 +1,149 @@
+
+
+
diff --git a/assets/svg/fruitSorbet/stack-icon1.svg b/assets/svg/themed/fruitSorbet/stack-icon1.svg
similarity index 100%
rename from assets/svg/fruitSorbet/stack-icon1.svg
rename to assets/svg/themed/fruitSorbet/stack-icon1.svg
diff --git a/assets/images/fruitSorbet/stack.svg b/assets/svg/themed/fruitSorbet/stack.svg
similarity index 100%
rename from assets/images/fruitSorbet/stack.svg
rename to assets/svg/themed/fruitSorbet/stack.svg
diff --git a/assets/svg/fruitSorbet/tx-exchange-icon-failed.svg b/assets/svg/themed/fruitSorbet/tx-exchange-icon-failed.svg
similarity index 100%
rename from assets/svg/fruitSorbet/tx-exchange-icon-failed.svg
rename to assets/svg/themed/fruitSorbet/tx-exchange-icon-failed.svg
diff --git a/assets/svg/fruitSorbet/tx-exchange-icon-pending.svg b/assets/svg/themed/fruitSorbet/tx-exchange-icon-pending.svg
similarity index 100%
rename from assets/svg/fruitSorbet/tx-exchange-icon-pending.svg
rename to assets/svg/themed/fruitSorbet/tx-exchange-icon-pending.svg
diff --git a/assets/svg/fruitSorbet/tx-exchange-icon.svg b/assets/svg/themed/fruitSorbet/tx-exchange-icon.svg
similarity index 100%
rename from assets/svg/fruitSorbet/tx-exchange-icon.svg
rename to assets/svg/themed/fruitSorbet/tx-exchange-icon.svg
diff --git a/assets/svg/fruitSorbet/tx-icon-receive-failed.svg b/assets/svg/themed/fruitSorbet/tx-icon-receive-failed.svg
similarity index 100%
rename from assets/svg/fruitSorbet/tx-icon-receive-failed.svg
rename to assets/svg/themed/fruitSorbet/tx-icon-receive-failed.svg
diff --git a/assets/svg/fruitSorbet/tx-icon-receive-pending.svg b/assets/svg/themed/fruitSorbet/tx-icon-receive-pending.svg
similarity index 100%
rename from assets/svg/fruitSorbet/tx-icon-receive-pending.svg
rename to assets/svg/themed/fruitSorbet/tx-icon-receive-pending.svg
diff --git a/assets/svg/fruitSorbet/tx-icon-receive.svg b/assets/svg/themed/fruitSorbet/tx-icon-receive.svg
similarity index 100%
rename from assets/svg/fruitSorbet/tx-icon-receive.svg
rename to assets/svg/themed/fruitSorbet/tx-icon-receive.svg
diff --git a/assets/svg/fruitSorbet/tx-icon-send-failed.svg b/assets/svg/themed/fruitSorbet/tx-icon-send-failed.svg
similarity index 100%
rename from assets/svg/fruitSorbet/tx-icon-send-failed.svg
rename to assets/svg/themed/fruitSorbet/tx-icon-send-failed.svg
diff --git a/assets/svg/fruitSorbet/tx-icon-send-pending.svg b/assets/svg/themed/fruitSorbet/tx-icon-send-pending.svg
similarity index 100%
rename from assets/svg/fruitSorbet/tx-icon-send-pending.svg
rename to assets/svg/themed/fruitSorbet/tx-icon-send-pending.svg
diff --git a/assets/svg/fruitSorbet/tx-icon-send.svg b/assets/svg/themed/fruitSorbet/tx-icon-send.svg
similarity index 100%
rename from assets/svg/fruitSorbet/tx-icon-send.svg
rename to assets/svg/themed/fruitSorbet/tx-icon-send.svg
diff --git a/assets/images/fruitSorbet/wownero.svg b/assets/svg/themed/fruitSorbet/wownero.svg
similarity index 100%
rename from assets/images/fruitSorbet/wownero.svg
rename to assets/svg/themed/fruitSorbet/wownero.svg
diff --git a/assets/svg/light/bell-new.svg b/assets/svg/themed/light/bell-new.svg
similarity index 100%
rename from assets/svg/light/bell-new.svg
rename to assets/svg/themed/light/bell-new.svg
diff --git a/assets/images/light/bitcoin.svg b/assets/svg/themed/light/bitcoin.svg
similarity index 100%
rename from assets/images/light/bitcoin.svg
rename to assets/svg/themed/light/bitcoin.svg
diff --git a/assets/images/light/bitcoincash.svg b/assets/svg/themed/light/bitcoincash.svg
similarity index 100%
rename from assets/images/light/bitcoincash.svg
rename to assets/svg/themed/light/bitcoincash.svg
diff --git a/assets/svg/light/buy-coins-icon.svg b/assets/svg/themed/light/buy-coins-icon.svg
similarity index 100%
rename from assets/svg/light/buy-coins-icon.svg
rename to assets/svg/themed/light/buy-coins-icon.svg
diff --git a/assets/images/light/doge.svg b/assets/svg/themed/light/doge.svg
similarity index 100%
rename from assets/images/light/doge.svg
rename to assets/svg/themed/light/doge.svg
diff --git a/assets/images/light/epic-cash.svg b/assets/svg/themed/light/epic-cash.svg
similarity index 100%
rename from assets/images/light/epic-cash.svg
rename to assets/svg/themed/light/epic-cash.svg
diff --git a/assets/svg/light/exchange-2.svg b/assets/svg/themed/light/exchange-2.svg
similarity index 100%
rename from assets/svg/light/exchange-2.svg
rename to assets/svg/themed/light/exchange-2.svg
diff --git a/assets/images/light/firo.svg b/assets/svg/themed/light/firo.svg
similarity index 100%
rename from assets/images/light/firo.svg
rename to assets/svg/themed/light/firo.svg
diff --git a/assets/images/light/litecoin.svg b/assets/svg/themed/light/litecoin.svg
similarity index 100%
rename from assets/images/light/litecoin.svg
rename to assets/svg/themed/light/litecoin.svg
diff --git a/assets/images/light/monero.svg b/assets/svg/themed/light/monero.svg
similarity index 100%
rename from assets/images/light/monero.svg
rename to assets/svg/themed/light/monero.svg
diff --git a/assets/images/light/namecoin.svg b/assets/svg/themed/light/namecoin.svg
similarity index 100%
rename from assets/images/light/namecoin.svg
rename to assets/svg/themed/light/namecoin.svg
diff --git a/assets/images/light/particl.svg b/assets/svg/themed/light/particl.svg
similarity index 100%
rename from assets/images/light/particl.svg
rename to assets/svg/themed/light/particl.svg
diff --git a/assets/svg/fruitSorbet/persona-easy-1.svg b/assets/svg/themed/light/persona-easy-1.svg
similarity index 100%
rename from assets/svg/fruitSorbet/persona-easy-1.svg
rename to assets/svg/themed/light/persona-easy-1.svg
diff --git a/assets/svg/fruitSorbet/persona-incognito-1.svg b/assets/svg/themed/light/persona-incognito-1.svg
similarity index 100%
rename from assets/svg/fruitSorbet/persona-incognito-1.svg
rename to assets/svg/themed/light/persona-incognito-1.svg
diff --git a/assets/svg/light/stack-icon1.svg b/assets/svg/themed/light/stack-icon1.svg
similarity index 100%
rename from assets/svg/light/stack-icon1.svg
rename to assets/svg/themed/light/stack-icon1.svg
diff --git a/assets/images/light/stack.svg b/assets/svg/themed/light/stack.svg
similarity index 100%
rename from assets/images/light/stack.svg
rename to assets/svg/themed/light/stack.svg
index 22dce4736..94929475d 100644
--- a/assets/images/light/stack.svg
+++ b/assets/svg/themed/light/stack.svg
@@ -1,4 +1,10 @@
diff --git a/assets/svg/light/tx-exchange-icon-failed.svg b/assets/svg/themed/light/tx-exchange-icon-failed.svg
similarity index 100%
rename from assets/svg/light/tx-exchange-icon-failed.svg
rename to assets/svg/themed/light/tx-exchange-icon-failed.svg
diff --git a/assets/svg/light/tx-exchange-icon-pending.svg b/assets/svg/themed/light/tx-exchange-icon-pending.svg
similarity index 100%
rename from assets/svg/light/tx-exchange-icon-pending.svg
rename to assets/svg/themed/light/tx-exchange-icon-pending.svg
diff --git a/assets/svg/light/tx-exchange-icon.svg b/assets/svg/themed/light/tx-exchange-icon.svg
similarity index 100%
rename from assets/svg/light/tx-exchange-icon.svg
rename to assets/svg/themed/light/tx-exchange-icon.svg
diff --git a/assets/svg/light/tx-icon-receive-failed.svg b/assets/svg/themed/light/tx-icon-receive-failed.svg
similarity index 100%
rename from assets/svg/light/tx-icon-receive-failed.svg
rename to assets/svg/themed/light/tx-icon-receive-failed.svg
diff --git a/assets/svg/light/tx-icon-receive-pending.svg b/assets/svg/themed/light/tx-icon-receive-pending.svg
similarity index 100%
rename from assets/svg/light/tx-icon-receive-pending.svg
rename to assets/svg/themed/light/tx-icon-receive-pending.svg
diff --git a/assets/svg/light/tx-icon-receive.svg b/assets/svg/themed/light/tx-icon-receive.svg
similarity index 100%
rename from assets/svg/light/tx-icon-receive.svg
rename to assets/svg/themed/light/tx-icon-receive.svg
diff --git a/assets/svg/light/tx-icon-send-failed.svg b/assets/svg/themed/light/tx-icon-send-failed.svg
similarity index 100%
rename from assets/svg/light/tx-icon-send-failed.svg
rename to assets/svg/themed/light/tx-icon-send-failed.svg
diff --git a/assets/svg/light/tx-icon-send-pending.svg b/assets/svg/themed/light/tx-icon-send-pending.svg
similarity index 100%
rename from assets/svg/light/tx-icon-send-pending.svg
rename to assets/svg/themed/light/tx-icon-send-pending.svg
diff --git a/assets/svg/light/tx-icon-send.svg b/assets/svg/themed/light/tx-icon-send.svg
similarity index 100%
rename from assets/svg/light/tx-icon-send.svg
rename to assets/svg/themed/light/tx-icon-send.svg
diff --git a/assets/images/light/wownero.svg b/assets/svg/themed/light/wownero.svg
similarity index 100%
rename from assets/images/light/wownero.svg
rename to assets/svg/themed/light/wownero.svg
diff --git a/assets/svg/oceanBreeze/bell-new.svg b/assets/svg/themed/oceanBreeze/bell-new.svg
similarity index 100%
rename from assets/svg/oceanBreeze/bell-new.svg
rename to assets/svg/themed/oceanBreeze/bell-new.svg
diff --git a/assets/svg/oceanBreeze/bg.svg b/assets/svg/themed/oceanBreeze/bg.svg
similarity index 100%
rename from assets/svg/oceanBreeze/bg.svg
rename to assets/svg/themed/oceanBreeze/bg.svg
diff --git a/assets/images/oceanBreeze/bitcoin.svg b/assets/svg/themed/oceanBreeze/bitcoin.svg
similarity index 100%
rename from assets/images/oceanBreeze/bitcoin.svg
rename to assets/svg/themed/oceanBreeze/bitcoin.svg
diff --git a/assets/images/oceanBreeze/bitcoincash.svg b/assets/svg/themed/oceanBreeze/bitcoincash.svg
similarity index 100%
rename from assets/images/oceanBreeze/bitcoincash.svg
rename to assets/svg/themed/oceanBreeze/bitcoincash.svg
diff --git a/assets/svg/oceanBreeze/buy-coins-icon.svg b/assets/svg/themed/oceanBreeze/buy-coins-icon.svg
similarity index 100%
rename from assets/svg/oceanBreeze/buy-coins-icon.svg
rename to assets/svg/themed/oceanBreeze/buy-coins-icon.svg
diff --git a/assets/images/oceanBreeze/doge.svg b/assets/svg/themed/oceanBreeze/doge.svg
similarity index 100%
rename from assets/images/oceanBreeze/doge.svg
rename to assets/svg/themed/oceanBreeze/doge.svg
diff --git a/assets/images/oceanBreeze/epic-cash.svg b/assets/svg/themed/oceanBreeze/epic-cash.svg
similarity index 100%
rename from assets/images/oceanBreeze/epic-cash.svg
rename to assets/svg/themed/oceanBreeze/epic-cash.svg
diff --git a/assets/svg/oceanBreeze/exchange-2.svg b/assets/svg/themed/oceanBreeze/exchange-2.svg
similarity index 100%
rename from assets/svg/oceanBreeze/exchange-2.svg
rename to assets/svg/themed/oceanBreeze/exchange-2.svg
diff --git a/assets/images/oceanBreeze/firo.svg b/assets/svg/themed/oceanBreeze/firo.svg
similarity index 100%
rename from assets/images/oceanBreeze/firo.svg
rename to assets/svg/themed/oceanBreeze/firo.svg
diff --git a/assets/images/oceanBreeze/litecoin.svg b/assets/svg/themed/oceanBreeze/litecoin.svg
similarity index 100%
rename from assets/images/oceanBreeze/litecoin.svg
rename to assets/svg/themed/oceanBreeze/litecoin.svg
diff --git a/assets/images/oceanBreeze/monero.svg b/assets/svg/themed/oceanBreeze/monero.svg
similarity index 100%
rename from assets/images/oceanBreeze/monero.svg
rename to assets/svg/themed/oceanBreeze/monero.svg
diff --git a/assets/images/oceanBreeze/namecoin.svg b/assets/svg/themed/oceanBreeze/namecoin.svg
similarity index 100%
rename from assets/images/oceanBreeze/namecoin.svg
rename to assets/svg/themed/oceanBreeze/namecoin.svg
diff --git a/assets/images/oceanBreeze/particl.svg b/assets/svg/themed/oceanBreeze/particl.svg
similarity index 100%
rename from assets/images/oceanBreeze/particl.svg
rename to assets/svg/themed/oceanBreeze/particl.svg
diff --git a/assets/svg/themed/oceanBreeze/persona-easy-1.svg b/assets/svg/themed/oceanBreeze/persona-easy-1.svg
new file mode 100644
index 000000000..760b6a852
--- /dev/null
+++ b/assets/svg/themed/oceanBreeze/persona-easy-1.svg
@@ -0,0 +1,32 @@
+
+
+
diff --git a/assets/svg/themed/oceanBreeze/persona-incognito-1.svg b/assets/svg/themed/oceanBreeze/persona-incognito-1.svg
new file mode 100644
index 000000000..d1160b221
--- /dev/null
+++ b/assets/svg/themed/oceanBreeze/persona-incognito-1.svg
@@ -0,0 +1,97 @@
+
+
+
diff --git a/assets/svg/oceanBreeze/stack-icon1.svg b/assets/svg/themed/oceanBreeze/stack-icon1.svg
similarity index 100%
rename from assets/svg/oceanBreeze/stack-icon1.svg
rename to assets/svg/themed/oceanBreeze/stack-icon1.svg
diff --git a/assets/images/oceanBreeze/stack.svg b/assets/svg/themed/oceanBreeze/stack.svg
similarity index 100%
rename from assets/images/oceanBreeze/stack.svg
rename to assets/svg/themed/oceanBreeze/stack.svg
diff --git a/assets/svg/oceanBreeze/tx-exchange-icon-failed.svg b/assets/svg/themed/oceanBreeze/tx-exchange-icon-failed.svg
similarity index 100%
rename from assets/svg/oceanBreeze/tx-exchange-icon-failed.svg
rename to assets/svg/themed/oceanBreeze/tx-exchange-icon-failed.svg
diff --git a/assets/svg/oceanBreeze/tx-exchange-icon-pending.svg b/assets/svg/themed/oceanBreeze/tx-exchange-icon-pending.svg
similarity index 100%
rename from assets/svg/oceanBreeze/tx-exchange-icon-pending.svg
rename to assets/svg/themed/oceanBreeze/tx-exchange-icon-pending.svg
diff --git a/assets/svg/oceanBreeze/tx-exchange-icon.svg b/assets/svg/themed/oceanBreeze/tx-exchange-icon.svg
similarity index 100%
rename from assets/svg/oceanBreeze/tx-exchange-icon.svg
rename to assets/svg/themed/oceanBreeze/tx-exchange-icon.svg
diff --git a/assets/svg/oceanBreeze/tx-icon-receive-failed.svg b/assets/svg/themed/oceanBreeze/tx-icon-receive-failed.svg
similarity index 100%
rename from assets/svg/oceanBreeze/tx-icon-receive-failed.svg
rename to assets/svg/themed/oceanBreeze/tx-icon-receive-failed.svg
diff --git a/assets/svg/oceanBreeze/tx-icon-receive-pending.svg b/assets/svg/themed/oceanBreeze/tx-icon-receive-pending.svg
similarity index 100%
rename from assets/svg/oceanBreeze/tx-icon-receive-pending.svg
rename to assets/svg/themed/oceanBreeze/tx-icon-receive-pending.svg
diff --git a/assets/svg/oceanBreeze/tx-icon-receive.svg b/assets/svg/themed/oceanBreeze/tx-icon-receive.svg
similarity index 100%
rename from assets/svg/oceanBreeze/tx-icon-receive.svg
rename to assets/svg/themed/oceanBreeze/tx-icon-receive.svg
diff --git a/assets/svg/oceanBreeze/tx-icon-send-failed.svg b/assets/svg/themed/oceanBreeze/tx-icon-send-failed.svg
similarity index 100%
rename from assets/svg/oceanBreeze/tx-icon-send-failed.svg
rename to assets/svg/themed/oceanBreeze/tx-icon-send-failed.svg
diff --git a/assets/svg/oceanBreeze/tx-icon-send-pending.svg b/assets/svg/themed/oceanBreeze/tx-icon-send-pending.svg
similarity index 100%
rename from assets/svg/oceanBreeze/tx-icon-send-pending.svg
rename to assets/svg/themed/oceanBreeze/tx-icon-send-pending.svg
diff --git a/assets/svg/oceanBreeze/tx-icon-send.svg b/assets/svg/themed/oceanBreeze/tx-icon-send.svg
similarity index 100%
rename from assets/svg/oceanBreeze/tx-icon-send.svg
rename to assets/svg/themed/oceanBreeze/tx-icon-send.svg
diff --git a/assets/images/oceanBreeze/wownero.svg b/assets/svg/themed/oceanBreeze/wownero.svg
similarity index 100%
rename from assets/images/oceanBreeze/wownero.svg
rename to assets/svg/themed/oceanBreeze/wownero.svg
diff --git a/assets/svg/oledBlack/bell-new.svg b/assets/svg/themed/oledBlack/bell-new.svg
similarity index 100%
rename from assets/svg/oledBlack/bell-new.svg
rename to assets/svg/themed/oledBlack/bell-new.svg
diff --git a/assets/images/oledBlack/bitcoin.svg b/assets/svg/themed/oledBlack/bitcoin.svg
similarity index 100%
rename from assets/images/oledBlack/bitcoin.svg
rename to assets/svg/themed/oledBlack/bitcoin.svg
diff --git a/assets/images/oledBlack/bitcoincash.svg b/assets/svg/themed/oledBlack/bitcoincash.svg
similarity index 100%
rename from assets/images/oledBlack/bitcoincash.svg
rename to assets/svg/themed/oledBlack/bitcoincash.svg
diff --git a/assets/svg/oledBlack/buy-coins-icon.svg b/assets/svg/themed/oledBlack/buy-coins-icon.svg
similarity index 100%
rename from assets/svg/oledBlack/buy-coins-icon.svg
rename to assets/svg/themed/oledBlack/buy-coins-icon.svg
diff --git a/assets/images/oledBlack/doge.svg b/assets/svg/themed/oledBlack/doge.svg
similarity index 100%
rename from assets/images/oledBlack/doge.svg
rename to assets/svg/themed/oledBlack/doge.svg
diff --git a/assets/images/oledBlack/epic-cash.svg b/assets/svg/themed/oledBlack/epic-cash.svg
similarity index 100%
rename from assets/images/oledBlack/epic-cash.svg
rename to assets/svg/themed/oledBlack/epic-cash.svg
diff --git a/assets/svg/oledBlack/exchange-2.svg b/assets/svg/themed/oledBlack/exchange-2.svg
similarity index 100%
rename from assets/svg/oledBlack/exchange-2.svg
rename to assets/svg/themed/oledBlack/exchange-2.svg
diff --git a/assets/images/oledBlack/firo.svg b/assets/svg/themed/oledBlack/firo.svg
similarity index 100%
rename from assets/images/oledBlack/firo.svg
rename to assets/svg/themed/oledBlack/firo.svg
diff --git a/assets/images/oledBlack/litecoin.svg b/assets/svg/themed/oledBlack/litecoin.svg
similarity index 100%
rename from assets/images/oledBlack/litecoin.svg
rename to assets/svg/themed/oledBlack/litecoin.svg
diff --git a/assets/images/oledBlack/monero.svg b/assets/svg/themed/oledBlack/monero.svg
similarity index 100%
rename from assets/images/oledBlack/monero.svg
rename to assets/svg/themed/oledBlack/monero.svg
diff --git a/assets/images/oledBlack/namecoin.svg b/assets/svg/themed/oledBlack/namecoin.svg
similarity index 100%
rename from assets/images/oledBlack/namecoin.svg
rename to assets/svg/themed/oledBlack/namecoin.svg
diff --git a/assets/images/oledBlack/particl.svg b/assets/svg/themed/oledBlack/particl.svg
similarity index 100%
rename from assets/images/oledBlack/particl.svg
rename to assets/svg/themed/oledBlack/particl.svg
diff --git a/assets/svg/light/persona-easy-1.svg b/assets/svg/themed/oledBlack/persona-easy-1.svg
similarity index 100%
rename from assets/svg/light/persona-easy-1.svg
rename to assets/svg/themed/oledBlack/persona-easy-1.svg
diff --git a/assets/svg/light/persona-incognito-1.svg b/assets/svg/themed/oledBlack/persona-incognito-1.svg
similarity index 100%
rename from assets/svg/light/persona-incognito-1.svg
rename to assets/svg/themed/oledBlack/persona-incognito-1.svg
diff --git a/assets/svg/oledBlack/stack-icon1.svg b/assets/svg/themed/oledBlack/stack-icon1.svg
similarity index 100%
rename from assets/svg/oledBlack/stack-icon1.svg
rename to assets/svg/themed/oledBlack/stack-icon1.svg
diff --git a/assets/images/oledBlack/stack.svg b/assets/svg/themed/oledBlack/stack.svg
similarity index 100%
rename from assets/images/oledBlack/stack.svg
rename to assets/svg/themed/oledBlack/stack.svg
index 22dce4736..94929475d 100644
--- a/assets/images/oledBlack/stack.svg
+++ b/assets/svg/themed/oledBlack/stack.svg
@@ -1,4 +1,10 @@
diff --git a/assets/svg/oledBlack/tx-exchange-icon-failed.svg b/assets/svg/themed/oledBlack/tx-exchange-icon-failed.svg
similarity index 100%
rename from assets/svg/oledBlack/tx-exchange-icon-failed.svg
rename to assets/svg/themed/oledBlack/tx-exchange-icon-failed.svg
diff --git a/assets/svg/oledBlack/tx-exchange-icon-pending.svg b/assets/svg/themed/oledBlack/tx-exchange-icon-pending.svg
similarity index 100%
rename from assets/svg/oledBlack/tx-exchange-icon-pending.svg
rename to assets/svg/themed/oledBlack/tx-exchange-icon-pending.svg
diff --git a/assets/svg/oledBlack/tx-exchange-icon.svg b/assets/svg/themed/oledBlack/tx-exchange-icon.svg
similarity index 100%
rename from assets/svg/oledBlack/tx-exchange-icon.svg
rename to assets/svg/themed/oledBlack/tx-exchange-icon.svg
diff --git a/assets/svg/oledBlack/tx-icon-receive-failed.svg b/assets/svg/themed/oledBlack/tx-icon-receive-failed.svg
similarity index 100%
rename from assets/svg/oledBlack/tx-icon-receive-failed.svg
rename to assets/svg/themed/oledBlack/tx-icon-receive-failed.svg
diff --git a/assets/svg/oledBlack/tx-icon-receive-pending.svg b/assets/svg/themed/oledBlack/tx-icon-receive-pending.svg
similarity index 100%
rename from assets/svg/oledBlack/tx-icon-receive-pending.svg
rename to assets/svg/themed/oledBlack/tx-icon-receive-pending.svg
diff --git a/assets/svg/oledBlack/tx-icon-receive.svg b/assets/svg/themed/oledBlack/tx-icon-receive.svg
similarity index 100%
rename from assets/svg/oledBlack/tx-icon-receive.svg
rename to assets/svg/themed/oledBlack/tx-icon-receive.svg
diff --git a/assets/svg/oledBlack/tx-icon-send-failed.svg b/assets/svg/themed/oledBlack/tx-icon-send-failed.svg
similarity index 100%
rename from assets/svg/oledBlack/tx-icon-send-failed.svg
rename to assets/svg/themed/oledBlack/tx-icon-send-failed.svg
diff --git a/assets/svg/oledBlack/tx-icon-send-pending.svg b/assets/svg/themed/oledBlack/tx-icon-send-pending.svg
similarity index 100%
rename from assets/svg/oledBlack/tx-icon-send-pending.svg
rename to assets/svg/themed/oledBlack/tx-icon-send-pending.svg
diff --git a/assets/svg/oledBlack/tx-icon-send.svg b/assets/svg/themed/oledBlack/tx-icon-send.svg
similarity index 100%
rename from assets/svg/oledBlack/tx-icon-send.svg
rename to assets/svg/themed/oledBlack/tx-icon-send.svg
diff --git a/assets/images/oledBlack/wownero.svg b/assets/svg/themed/oledBlack/wownero.svg
similarity index 100%
rename from assets/images/oledBlack/wownero.svg
rename to assets/svg/themed/oledBlack/wownero.svg
diff --git a/assets/svg/unclaimed.svg b/assets/svg/unclaimed.svg
new file mode 100644
index 000000000..a6ff2213d
--- /dev/null
+++ b/assets/svg/unclaimed.svg
@@ -0,0 +1,175 @@
+
+
+
diff --git a/lib/db/main_db.dart b/lib/db/main_db.dart
index 1cd78f951..1fb672d34 100644
--- a/lib/db/main_db.dart
+++ b/lib/db/main_db.dart
@@ -1,9 +1,15 @@
+import 'package:decimal/decimal.dart';
+import 'package:flutter_native_splash/cli_commands.dart';
import 'package:isar/isar.dart';
import 'package:stackwallet/exceptions/main_db/main_db_exception.dart';
import 'package:stackwallet/models/isar/models/isar_models.dart';
+import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/utilities/format.dart';
import 'package:stackwallet/utilities/stack_file_system.dart';
import 'package:tuple/tuple.dart';
+part 'queries/queries.dart';
+
class MainDB {
MainDB._();
static MainDB? _instance;
diff --git a/lib/db/queries/queries.dart b/lib/db/queries/queries.dart
new file mode 100644
index 000000000..2995de06d
--- /dev/null
+++ b/lib/db/queries/queries.dart
@@ -0,0 +1,182 @@
+part of 'package:stackwallet/db/main_db.dart';
+
+enum CCFilter {
+ all,
+ available,
+ frozen;
+
+ @override
+ String toString() {
+ if (this == all) {
+ return "Show $name outputs";
+ }
+
+ return "${name.capitalize()} outputs";
+ }
+}
+
+enum CCSortDescriptor {
+ age,
+ address,
+ value;
+
+ @override
+ String toString() {
+ return name.capitalize();
+ }
+}
+
+extension MainDBQueries on MainDB {
+ List queryUTXOsSync({
+ required String walletId,
+ required CCFilter filter,
+ required CCSortDescriptor sort,
+ required String searchTerm,
+ required Coin coin,
+ }) {
+ var preSort = getUTXOs(walletId).filter().group((q) {
+ final qq = q.group(
+ (q) => q.usedIsNull().or().usedEqualTo(false),
+ );
+ switch (filter) {
+ case CCFilter.frozen:
+ return qq.and().isBlockedEqualTo(true);
+ case CCFilter.available:
+ return qq.and().isBlockedEqualTo(false);
+ case CCFilter.all:
+ return qq;
+ }
+ });
+
+ if (searchTerm.isNotEmpty) {
+ preSort = preSort.and().group(
+ (q) {
+ var qq = q.addressContains(searchTerm, caseSensitive: false);
+
+ qq = qq.or().nameContains(searchTerm, caseSensitive: false);
+ qq = qq.or().group(
+ (q) => q
+ .isBlockedEqualTo(true)
+ .and()
+ .blockedReasonContains(searchTerm, caseSensitive: false),
+ );
+
+ qq = qq.or().txidContains(searchTerm, caseSensitive: false);
+ qq = qq.or().blockHashContains(searchTerm, caseSensitive: false);
+
+ final maybeDecimal = Decimal.tryParse(searchTerm);
+ if (maybeDecimal != null) {
+ qq = qq.or().valueEqualTo(
+ Format.decimalAmountToSatoshis(
+ maybeDecimal,
+ coin,
+ ),
+ );
+ }
+
+ final maybeInt = int.tryParse(searchTerm);
+ if (maybeInt != null) {
+ qq = qq.or().valueEqualTo(maybeInt);
+ }
+
+ return qq;
+ },
+ );
+ }
+
+ final List ids;
+ switch (sort) {
+ case CCSortDescriptor.age:
+ ids = preSort.sortByBlockHeight().idProperty().findAllSync();
+ break;
+ case CCSortDescriptor.address:
+ ids = preSort.sortByAddress().idProperty().findAllSync();
+ break;
+ case CCSortDescriptor.value:
+ ids = preSort.sortByValueDesc().idProperty().findAllSync();
+ break;
+ }
+ return ids;
+ }
+
+ Map> queryUTXOsGroupedByAddressSync({
+ required String walletId,
+ required CCFilter filter,
+ required CCSortDescriptor sort,
+ required String searchTerm,
+ required Coin coin,
+ }) {
+ var preSort = getUTXOs(walletId).filter().group((q) {
+ final qq = q.group(
+ (q) => q.usedIsNull().or().usedEqualTo(false),
+ );
+ switch (filter) {
+ case CCFilter.frozen:
+ return qq.and().isBlockedEqualTo(true);
+ case CCFilter.available:
+ return qq.and().isBlockedEqualTo(false);
+ case CCFilter.all:
+ return qq;
+ }
+ });
+
+ if (searchTerm.isNotEmpty) {
+ preSort = preSort.and().group(
+ (q) {
+ var qq = q.addressContains(searchTerm, caseSensitive: false);
+
+ qq = qq.or().nameContains(searchTerm, caseSensitive: false);
+ qq = qq.or().group(
+ (q) => q
+ .isBlockedEqualTo(true)
+ .and()
+ .blockedReasonContains(searchTerm, caseSensitive: false),
+ );
+
+ qq = qq.or().txidContains(searchTerm, caseSensitive: false);
+ qq = qq.or().blockHashContains(searchTerm, caseSensitive: false);
+
+ final maybeDecimal = Decimal.tryParse(searchTerm);
+ if (maybeDecimal != null) {
+ qq = qq.or().valueEqualTo(
+ Format.decimalAmountToSatoshis(
+ maybeDecimal,
+ coin,
+ ),
+ );
+ }
+
+ final maybeInt = int.tryParse(searchTerm);
+ if (maybeInt != null) {
+ qq = qq.or().valueEqualTo(maybeInt);
+ }
+
+ return qq;
+ },
+ );
+ }
+
+ final List utxos;
+ switch (sort) {
+ case CCSortDescriptor.age:
+ utxos = preSort.sortByBlockHeight().findAllSync();
+ break;
+ case CCSortDescriptor.address:
+ utxos = preSort.sortByAddress().findAllSync();
+ break;
+ case CCSortDescriptor.value:
+ utxos = preSort.sortByValueDesc().findAllSync();
+ break;
+ }
+
+ final Map> results = {};
+ for (final utxo in utxos) {
+ if (results[utxo.address!] == null) {
+ results[utxo.address!] = [];
+ }
+ results[utxo.address!]!.add(utxo.id);
+ }
+
+ return results;
+ }
+}
diff --git a/lib/main.dart b/lib/main.dart
index 8612d2f7e..d34eb455f 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -6,6 +6,7 @@ import 'package:cw_core/node.dart';
import 'package:cw_core/unspent_coins_info.dart';
import 'package:cw_core/wallet_info.dart';
import 'package:cw_core/wallet_type.dart';
+import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_libmonero/monero/monero.dart';
@@ -56,6 +57,7 @@ import 'package:stackwallet/utilities/enums/backup_frequency_type.dart';
import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
import 'package:stackwallet/utilities/logger.dart';
import 'package:stackwallet/utilities/stack_file_system.dart';
+import 'package:stackwallet/utilities/theme/chan_colors.dart';
import 'package:stackwallet/utilities/theme/color_theme.dart';
import 'package:stackwallet/utilities/theme/dark_colors.dart';
import 'package:stackwallet/utilities/theme/forest_colors.dart';
@@ -91,7 +93,7 @@ void main() async {
setWindowMaxSize(Size.infinite);
final screenHeight = screen?.frame.height;
- if (screenHeight != null) {
+ if (screenHeight != null && !kDebugMode) {
// starting to height be 3/4 screen height or 900, whichever is smaller
final height = min(screenHeight * 0.75, 900);
setWindowFrame(
@@ -352,6 +354,9 @@ class _MaterialAppWithThemeState extends ConsumerState
case "forest":
colorTheme = ForestColors();
break;
+ case "chan":
+ colorTheme = ChanColors();
+ break;
case "light":
default:
colorTheme = LightColors();
@@ -524,7 +529,7 @@ class _MaterialAppWithThemeState extends ConsumerState
theme: ThemeData(
extensions: [colorScheme],
highlightColor: colorScheme.highlight,
- brightness: Brightness.light,
+ brightness: colorScheme.brightness,
fontFamily: GoogleFonts.inter().fontFamily,
unselectedWidgetColor: colorScheme.radioButtonBorderDisabled,
// textTheme: GoogleFonts.interTextTheme().copyWith(
diff --git a/lib/pages/add_wallet_views/create_or_restore_wallet_view/create_or_restore_wallet_view.dart b/lib/pages/add_wallet_views/create_or_restore_wallet_view/create_or_restore_wallet_view.dart
index 7108b35be..85d5beb74 100644
--- a/lib/pages/add_wallet_views/create_or_restore_wallet_view/create_or_restore_wallet_view.dart
+++ b/lib/pages/add_wallet_views/create_or_restore_wallet_view/create_or_restore_wallet_view.dart
@@ -61,7 +61,10 @@ class CreateOrRestoreWalletView extends StatelessWidget {
),
CoinImage(
coin: coin,
- isDesktop: isDesktop,
+ width:
+ isDesktop ? 324 : MediaQuery.of(context).size.width / 1.6,
+ height:
+ isDesktop ? null : MediaQuery.of(context).size.width / 1.6,
),
const SizedBox(
height: 32,
@@ -99,7 +102,12 @@ class CreateOrRestoreWalletView extends StatelessWidget {
children: [
CoinImage(
coin: coin,
- isDesktop: isDesktop,
+ width: isDesktop
+ ? 324
+ : MediaQuery.of(context).size.width / 1.6,
+ height: isDesktop
+ ? null
+ : MediaQuery.of(context).size.width / 1.6,
),
const Spacer(
flex: 2,
diff --git a/lib/pages/add_wallet_views/create_or_restore_wallet_view/sub_widgets/coin_image.dart b/lib/pages/add_wallet_views/create_or_restore_wallet_view/sub_widgets/coin_image.dart
index 874580faa..fb282d9ca 100644
--- a/lib/pages/add_wallet_views/create_or_restore_wallet_view/sub_widgets/coin_image.dart
+++ b/lib/pages/add_wallet_views/create_or_restore_wallet_view/sub_widgets/coin_image.dart
@@ -3,22 +3,40 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/svg.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/utilities/theme/color_theme.dart';
+import 'package:stackwallet/utilities/theme/stack_colors.dart';
class CoinImage extends ConsumerWidget {
const CoinImage({
Key? key,
required this.coin,
- required this.isDesktop,
+ this.width,
+ this.height,
}) : super(key: key);
final Coin coin;
- final bool isDesktop;
+ final double? width;
+ final double? height;
@override
Widget build(BuildContext context, WidgetRef ref) {
- return SvgPicture.asset(
- Assets.svg.imageFor(coin: coin, context: context),
- width: isDesktop ? 324 : MediaQuery.of(context).size.width / 1.6,
- );
+ if (Theme.of(context).extension()!.themeType ==
+ ThemeType.chan) {
+ return SizedBox(
+ width: width,
+ height: height,
+ child: Image(
+ image: AssetImage(
+ Assets.gif.plain(coin),
+ ),
+ ),
+ );
+ } else {
+ return SvgPicture.asset(
+ Assets.svg.imageFor(coin: coin, context: context),
+ width: width,
+ height: height,
+ );
+ }
}
}
diff --git a/lib/pages/add_wallet_views/name_your_wallet_view/name_your_wallet_view.dart b/lib/pages/add_wallet_views/name_your_wallet_view/name_your_wallet_view.dart
index e699db58e..6a3f28318 100644
--- a/lib/pages/add_wallet_views/name_your_wallet_view/name_your_wallet_view.dart
+++ b/lib/pages/add_wallet_views/name_your_wallet_view/name_your_wallet_view.dart
@@ -2,8 +2,8 @@ import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
-import 'package:flutter_svg/svg.dart';
import 'package:stackwallet/notifications/show_flush_bar.dart';
+import 'package:stackwallet/pages/add_wallet_views/create_or_restore_wallet_view/sub_widgets/coin_image.dart';
import 'package:stackwallet/pages/add_wallet_views/new_wallet_recovery_phrase_warning_view/new_wallet_recovery_phrase_warning_view.dart';
import 'package:stackwallet/pages/add_wallet_views/restore_wallet_view/restore_options_view/restore_options_view.dart';
import 'package:stackwallet/pages_desktop_specific/my_stack_view/exit_to_my_stack_button.dart';
@@ -166,9 +166,10 @@ class _NameYourWalletViewState extends ConsumerState {
flex: 1,
),
if (!isDesktop)
- SvgPicture.asset(
- Assets.svg.imageFor(coin: coin, context: context),
+ CoinImage(
+ coin: coin,
height: 100,
+ width: 100,
),
SizedBox(
height: isDesktop ? 0 : 16,
diff --git a/lib/pages/add_wallet_views/restore_wallet_view/restore_options_view/restore_options_view.dart b/lib/pages/add_wallet_views/restore_wallet_view/restore_options_view/restore_options_view.dart
index fcb932e56..a83fa5bd2 100644
--- a/lib/pages/add_wallet_views/restore_wallet_view/restore_options_view/restore_options_view.dart
+++ b/lib/pages/add_wallet_views/restore_wallet_view/restore_options_view/restore_options_view.dart
@@ -4,6 +4,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_rounded_date_picker/flutter_rounded_date_picker.dart';
import 'package:flutter_svg/svg.dart';
import 'package:google_fonts/google_fonts.dart';
+import 'package:stackwallet/pages/add_wallet_views/create_or_restore_wallet_view/sub_widgets/coin_image.dart';
import 'package:stackwallet/pages/add_wallet_views/restore_wallet_view/restore_options_view/sub_widgets/mobile_mnemonic_length_selector.dart';
import 'package:stackwallet/pages/add_wallet_views/restore_wallet_view/restore_options_view/sub_widgets/restore_from_date_picker.dart';
import 'package:stackwallet/pages/add_wallet_views/restore_wallet_view/restore_options_view/sub_widgets/restore_options_next_button.dart';
@@ -282,9 +283,10 @@ class _RestoreOptionsViewState extends ConsumerState {
flex: isDesktop ? 10 : 1,
),
if (!isDesktop)
- SvgPicture.asset(
- Assets.svg.imageFor(coin: coin, context: context),
+ CoinImage(
+ coin: coin,
height: 100,
+ width: 100,
),
SizedBox(
height: isDesktop ? 0 : 16,
diff --git a/lib/pages/coin_control/coin_control_view.dart b/lib/pages/coin_control/coin_control_view.dart
index 5457a8c86..0eeff1089 100644
--- a/lib/pages/coin_control/coin_control_view.dart
+++ b/lib/pages/coin_control/coin_control_view.dart
@@ -2,6 +2,7 @@ import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:flutter_svg/flutter_svg.dart';
import 'package:isar/isar.dart';
import 'package:stackwallet/db/main_db.dart';
import 'package:stackwallet/models/isar/models/isar_models.dart';
@@ -9,20 +10,27 @@ import 'package:stackwallet/pages/coin_control/utxo_card.dart';
import 'package:stackwallet/pages/coin_control/utxo_details_view.dart';
import 'package:stackwallet/providers/global/wallets_provider.dart';
import 'package:stackwallet/services/mixins/coin_control_interface.dart';
+import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
import 'package:stackwallet/utilities/format.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
+import 'package:stackwallet/widgets/app_bar_field.dart';
import 'package:stackwallet/widgets/background.dart';
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
+import 'package:stackwallet/widgets/custom_buttons/dropdown_button.dart';
import 'package:stackwallet/widgets/desktop/primary_button.dart';
import 'package:stackwallet/widgets/desktop/secondary_button.dart';
+import 'package:stackwallet/widgets/expandable2.dart';
import 'package:stackwallet/widgets/icon_widgets/x_icon.dart';
import 'package:stackwallet/widgets/rounded_white_container.dart';
import 'package:stackwallet/widgets/toggle.dart';
import 'package:tuple/tuple.dart';
+import '../../widgets/animated_widgets/rotate_icon.dart';
+import '../../widgets/rounded_container.dart';
+
enum CoinControlViewType {
manage,
use;
@@ -49,8 +57,17 @@ class CoinControlView extends ConsumerStatefulWidget {
}
class _CoinControlViewState extends ConsumerState {
+ final searchController = TextEditingController();
+ final searchFocus = FocusNode();
+
+ bool _isSearching = false;
bool _showBlocked = false;
+ CCSortDescriptor _sort = CCSortDescriptor.age;
+
+ Map>? _map;
+ List? _list;
+
final Set _selectedAvailable = {};
final Set _selectedBlocked = {};
@@ -67,9 +84,21 @@ class _CoinControlViewState extends ConsumerState {
if (widget.selectedUTXOs != null) {
_selectedAvailable.addAll(widget.selectedUTXOs!);
}
+ searchController.addListener(() {
+ WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
+ setState(() {});
+ });
+ });
super.initState();
}
+ @override
+ void dispose() {
+ searchController.dispose();
+ searchFocus.dispose();
+ super.dispose();
+ }
+
@override
Widget build(BuildContext context) {
debugPrint("BUILD: $runtimeType");
@@ -94,16 +123,29 @@ class _CoinControlViewState extends ConsumerState {
),
);
- final ids = MainDB.instance
- .getUTXOs(widget.walletId)
- .filter()
- .isBlockedEqualTo(_showBlocked)
- .and()
- .group(
- (q) => q.usedIsNull().or().usedEqualTo(false),
- )
- .idProperty()
- .findAllSync();
+ if (_sort == CCSortDescriptor.address && !_isSearching) {
+ _list = null;
+ _map = MainDB.instance.queryUTXOsGroupedByAddressSync(
+ walletId: widget.walletId,
+ filter: CCFilter.all,
+ sort: _sort,
+ searchTerm: "",
+ coin: coin,
+ );
+ } else {
+ _map = null;
+ _list = MainDB.instance.queryUTXOsSync(
+ walletId: widget.walletId,
+ filter: _isSearching
+ ? CCFilter.all
+ : _showBlocked
+ ? CCFilter.frozen
+ : CCFilter.available,
+ sort: _sort,
+ searchTerm: _isSearching ? searchController.text : "",
+ coin: coin,
+ );
+ }
return WillPopScope(
onWillPop: () async {
@@ -117,36 +159,105 @@ class _CoinControlViewState extends ConsumerState {
backgroundColor:
Theme.of(context).extension()!.background,
appBar: AppBar(
- leading: widget.type == CoinControlViewType.use &&
- _selectedAvailable.isNotEmpty
- ? AppBarIconButton(
- icon: XIcon(
- width: 24,
- height: 24,
- color: Theme.of(context)
- .extension()!
- .topNavIconPrimary,
- ),
- onPressed: () {
- setState(() {
- _selectedAvailable.clear();
- });
- },
+ automaticallyImplyLeading: false,
+ leading: _isSearching
+ ? null
+ : widget.type == CoinControlViewType.use &&
+ _selectedAvailable.isNotEmpty
+ ? AppBarIconButton(
+ icon: XIcon(
+ width: 24,
+ height: 24,
+ color: Theme.of(context)
+ .extension()!
+ .topNavIconPrimary,
+ ),
+ onPressed: () {
+ setState(() {
+ _selectedAvailable.clear();
+ });
+ },
+ )
+ : AppBarBackButton(
+ onPressed: () {
+ unawaited(_refreshBalance());
+ Navigator.of(context).pop(
+ widget.type == CoinControlViewType.use
+ ? _selectedAvailable
+ : null);
+ },
+ ),
+ title: _isSearching
+ ? AppBarSearchField(
+ controller: searchController,
+ focusNode: searchFocus,
)
- : AppBarBackButton(
- onPressed: () {
- unawaited(_refreshBalance());
- Navigator.of(context).pop(
- widget.type == CoinControlViewType.use
- ? _selectedAvailable
- : null);
- },
+ : Text(
+ "Coin control",
+ style: STextStyles.navBarTitle(context),
),
- title: Text(
- "Coin control",
- style: STextStyles.navBarTitle(context),
- ),
titleSpacing: 0,
+ actions: _isSearching
+ ? [
+ AspectRatio(
+ aspectRatio: 1,
+ child: AppBarIconButton(
+ size: 36,
+ icon: SvgPicture.asset(
+ Assets.svg.x,
+ width: 20,
+ height: 20,
+ color: Theme.of(context)
+ .extension()!
+ .topNavIconPrimary,
+ ),
+ onPressed: () {
+ // show search
+ setState(() {
+ _isSearching = false;
+ });
+ },
+ ),
+ ),
+ ]
+ : [
+ AspectRatio(
+ aspectRatio: 1,
+ child: AppBarIconButton(
+ size: 36,
+ icon: SvgPicture.asset(
+ Assets.svg.search,
+ width: 20,
+ height: 20,
+ color: Theme.of(context)
+ .extension()!
+ .topNavIconPrimary,
+ ),
+ onPressed: () {
+ // show search
+ setState(() {
+ _isSearching = true;
+ });
+ },
+ ),
+ ),
+ AspectRatio(
+ aspectRatio: 1,
+ child: JDropdownIconButton(
+ mobileAppBar: true,
+ groupValue: _sort,
+ items: CCSortDescriptor.values.toSet(),
+ onSelectionChanged: (CCSortDescriptor? newValue) {
+ if (newValue != null && newValue != _sort) {
+ setState(() {
+ _sort = newValue;
+ });
+ }
+ },
+ displayPrefix: "Sort by",
+ ),
+ ),
+ ],
),
body: SafeArea(
child: Column(
@@ -161,109 +272,328 @@ class _CoinControlViewState extends ConsumerState {
const SizedBox(
height: 10,
),
- RoundedWhiteContainer(
- child: Text(
- "This option allows you to control, freeze, and utilize "
- "outputs at your discretion. Tap the output circle to "
- "select.",
- style: STextStyles.w500_14(context).copyWith(
- color: Theme.of(context)
- .extension()!
- .textSubtitle1,
- ),
- ),
- ),
- const SizedBox(
- height: 10,
- ),
- SizedBox(
- height: 48,
- child: Toggle(
- key: UniqueKey(),
- onColor: Theme.of(context)
- .extension()!
- .popupBG,
- onText: "Available outputs",
- offColor: Theme.of(context)
- .extension()!
- .textFieldDefaultBG,
- offText: "Frozen outputs",
- isOn: _showBlocked,
- onValueChanged: (value) {
- setState(() {
- _showBlocked = value;
- });
- },
- decoration: BoxDecoration(
- color: Colors.transparent,
- borderRadius: BorderRadius.circular(
- Constants.size.circularBorderRadius,
+ if (!_isSearching)
+ RoundedWhiteContainer(
+ child: Text(
+ "This option allows you to control, freeze, and utilize "
+ "outputs at your discretion. Tap the output circle to "
+ "select.",
+ style: STextStyles.w500_14(context).copyWith(
+ color: Theme.of(context)
+ .extension()!
+ .textSubtitle1,
),
),
),
- ),
- const SizedBox(
- height: 10,
- ),
- Expanded(
- child: ListView.separated(
- itemCount: ids.length,
- separatorBuilder: (context, _) => const SizedBox(
- height: 10,
- ),
- itemBuilder: (context, index) {
- final utxo = MainDB.instance.isar.utxos
- .where()
- .idEqualTo(ids[index])
- .findFirstSync()!;
-
- final isSelected = _showBlocked
- ? _selectedBlocked.contains(utxo)
- : _selectedAvailable.contains(utxo);
-
- return UtxoCard(
- key: Key(
- "${utxo.walletId}_${utxo.id}_$isSelected"),
- walletId: widget.walletId,
- utxo: utxo,
- canSelect: widget.type ==
- CoinControlViewType.manage ||
- (widget.type == CoinControlViewType.use &&
- !_showBlocked &&
- utxo.isConfirmed(
- currentChainHeight,
- coin.requiredConfirmations,
- )),
- initialSelectedState: isSelected,
- onSelectedChanged: (value) {
- if (value) {
- _showBlocked
- ? _selectedBlocked.add(utxo)
- : _selectedAvailable.add(utxo);
- } else {
- _showBlocked
- ? _selectedBlocked.remove(utxo)
- : _selectedAvailable.remove(utxo);
- }
- setState(() {});
- },
- onPressed: () async {
- final result =
- await Navigator.of(context).pushNamed(
- UtxoDetailsView.routeName,
- arguments: Tuple2(
- utxo.id,
- widget.walletId,
- ),
- );
- if (mounted && result == "refresh") {
- setState(() {});
- }
- },
- );
- },
+ if (!_isSearching)
+ const SizedBox(
+ height: 10,
),
- ),
+ if (!(_isSearching || _map != null))
+ SizedBox(
+ height: 48,
+ child: Toggle(
+ key: UniqueKey(),
+ onColor: Theme.of(context)
+ .extension()!
+ .popupBG,
+ onText: "Available outputs",
+ offColor: Theme.of(context)
+ .extension()!
+ .textFieldDefaultBG,
+ offText: "Frozen outputs",
+ isOn: _showBlocked,
+ onValueChanged: (value) {
+ setState(() {
+ _showBlocked = value;
+ });
+ },
+ decoration: BoxDecoration(
+ color: Colors.transparent,
+ borderRadius: BorderRadius.circular(
+ Constants.size.circularBorderRadius,
+ ),
+ ),
+ ),
+ ),
+ if (!_isSearching)
+ const SizedBox(
+ height: 10,
+ ),
+ if (_isSearching)
+ Expanded(
+ child: ListView.separated(
+ itemCount: _list!.length,
+ separatorBuilder: (context, _) => const SizedBox(
+ height: 10,
+ ),
+ itemBuilder: (context, index) {
+ final utxo = MainDB.instance.isar.utxos
+ .where()
+ .idEqualTo(_list![index])
+ .findFirstSync()!;
+
+ final isSelected =
+ _selectedBlocked.contains(utxo) ||
+ _selectedAvailable.contains(utxo);
+
+ return UtxoCard(
+ key: Key(
+ "${utxo.walletId}_${utxo.id}_$isSelected"),
+ walletId: widget.walletId,
+ utxo: utxo,
+ canSelect: widget.type ==
+ CoinControlViewType.manage ||
+ (widget.type == CoinControlViewType.use &&
+ !utxo.isBlocked &&
+ utxo.isConfirmed(
+ currentChainHeight,
+ coin.requiredConfirmations,
+ )),
+ initialSelectedState: isSelected,
+ onSelectedChanged: (value) {
+ if (value) {
+ utxo.isBlocked
+ ? _selectedBlocked.add(utxo)
+ : _selectedAvailable.add(utxo);
+ } else {
+ utxo.isBlocked
+ ? _selectedBlocked.remove(utxo)
+ : _selectedAvailable.remove(utxo);
+ }
+ setState(() {});
+ },
+ onPressed: () async {
+ final result =
+ await Navigator.of(context).pushNamed(
+ UtxoDetailsView.routeName,
+ arguments: Tuple2(
+ utxo.id,
+ widget.walletId,
+ ),
+ );
+ if (mounted && result == "refresh") {
+ setState(() {});
+ }
+ },
+ );
+ },
+ ),
+ ),
+ if (!_isSearching)
+ _list != null
+ ? Expanded(
+ child: ListView.separated(
+ itemCount: _list!.length,
+ separatorBuilder: (context, _) =>
+ const SizedBox(
+ height: 10,
+ ),
+ itemBuilder: (context, index) {
+ final utxo = MainDB.instance.isar.utxos
+ .where()
+ .idEqualTo(_list![index])
+ .findFirstSync()!;
+
+ final isSelected = _showBlocked
+ ? _selectedBlocked.contains(utxo)
+ : _selectedAvailable.contains(utxo);
+
+ return UtxoCard(
+ key: Key(
+ "${utxo.walletId}_${utxo.id}_$isSelected"),
+ walletId: widget.walletId,
+ utxo: utxo,
+ canSelect: widget.type ==
+ CoinControlViewType.manage ||
+ (widget.type ==
+ CoinControlViewType.use &&
+ !_showBlocked &&
+ utxo.isConfirmed(
+ currentChainHeight,
+ coin.requiredConfirmations,
+ )),
+ initialSelectedState: isSelected,
+ onSelectedChanged: (value) {
+ if (value) {
+ _showBlocked
+ ? _selectedBlocked.add(utxo)
+ : _selectedAvailable.add(utxo);
+ } else {
+ _showBlocked
+ ? _selectedBlocked.remove(utxo)
+ : _selectedAvailable
+ .remove(utxo);
+ }
+ setState(() {});
+ },
+ onPressed: () async {
+ final result =
+ await Navigator.of(context)
+ .pushNamed(
+ UtxoDetailsView.routeName,
+ arguments: Tuple2(
+ utxo.id,
+ widget.walletId,
+ ),
+ );
+ if (mounted && result == "refresh") {
+ setState(() {});
+ }
+ },
+ );
+ },
+ ),
+ )
+ : Expanded(
+ child: ListView.separated(
+ itemCount: _map!.entries.length,
+ separatorBuilder: (context, _) =>
+ const SizedBox(
+ height: 10,
+ ),
+ itemBuilder: (context, index) {
+ final entry =
+ _map!.entries.elementAt(index);
+ final _controller =
+ RotateIconController();
+
+ return Expandable2(
+ border: Theme.of(context)
+ .extension()!
+ .backgroundAppBar,
+ background: Theme.of(context)
+ .extension()!
+ .popupBG,
+ animationDurationMultiplier:
+ 0.2 * entry.value.length,
+ onExpandWillChange: (state) {
+ if (state ==
+ Expandable2State.expanded) {
+ _controller.forward?.call();
+ } else {
+ _controller.reverse?.call();
+ }
+ },
+ header: RoundedContainer(
+ padding: const EdgeInsets.all(14),
+ color: Colors.transparent,
+ child: Row(
+ children: [
+ Expanded(
+ child: Column(
+ crossAxisAlignment:
+ CrossAxisAlignment.start,
+ children: [
+ Text(
+ entry.key,
+ style:
+ STextStyles.w600_14(
+ context),
+ ),
+ const SizedBox(
+ height: 2,
+ ),
+ Text(
+ "${entry.value.length} "
+ "output${entry.value.length > 1 ? "s" : ""}",
+ style:
+ STextStyles.w500_12(
+ context)
+ .copyWith(
+ color: Theme.of(context)
+ .extension<
+ StackColors>()!
+ .textSubtitle1,
+ ),
+ ),
+ ],
+ ),
+ ),
+ RotateIcon(
+ animationDurationMultiplier:
+ 0.2 * entry.value.length,
+ icon: SvgPicture.asset(
+ Assets.svg.chevronDown,
+ width: 14,
+ color: Theme.of(context)
+ .extension()!
+ .textSubtitle1,
+ ),
+ curve: Curves.easeInOut,
+ controller: _controller,
+ ),
+ ],
+ ),
+ ),
+ children: entry.value.map(
+ (id) {
+ final utxo = MainDB
+ .instance.isar.utxos
+ .where()
+ .idEqualTo(id)
+ .findFirstSync()!;
+
+ final isSelected = _selectedBlocked
+ .contains(utxo) ||
+ _selectedAvailable
+ .contains(utxo);
+
+ return UtxoCard(
+ key: Key(
+ "${utxo.walletId}_${utxo.id}_$isSelected"),
+ walletId: widget.walletId,
+ utxo: utxo,
+ canSelect: widget.type ==
+ CoinControlViewType
+ .manage ||
+ (widget.type ==
+ CoinControlViewType
+ .use &&
+ !utxo.isBlocked &&
+ utxo.isConfirmed(
+ currentChainHeight,
+ coin.requiredConfirmations,
+ )),
+ initialSelectedState: isSelected,
+ onSelectedChanged: (value) {
+ if (value) {
+ utxo.isBlocked
+ ? _selectedBlocked
+ .add(utxo)
+ : _selectedAvailable
+ .add(utxo);
+ } else {
+ utxo.isBlocked
+ ? _selectedBlocked
+ .remove(utxo)
+ : _selectedAvailable
+ .remove(utxo);
+ }
+ setState(() {});
+ },
+ onPressed: () async {
+ final result =
+ await Navigator.of(context)
+ .pushNamed(
+ UtxoDetailsView.routeName,
+ arguments: Tuple2(
+ utxo.id,
+ widget.walletId,
+ ),
+ );
+ if (mounted &&
+ result == "refresh") {
+ setState(() {});
+ }
+ },
+ );
+ },
+ ).toList(),
+ );
+ },
+ ),
+ ),
],
),
),
@@ -420,6 +750,9 @@ class _CoinControlViewState extends ConsumerState {
label: "Use coins",
enabled: _selectedAvailable.isNotEmpty,
onPressed: () async {
+ if (searchFocus.hasFocus) {
+ searchFocus.unfocus();
+ }
Navigator.of(context).pop(
_selectedAvailable,
);
diff --git a/lib/pages/coin_control/utxo_details_view.dart b/lib/pages/coin_control/utxo_details_view.dart
index 180cae39d..e4b31c63d 100644
--- a/lib/pages/coin_control/utxo_details_view.dart
+++ b/lib/pages/coin_control/utxo_details_view.dart
@@ -5,6 +5,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:isar/isar.dart';
import 'package:stackwallet/db/main_db.dart';
import 'package:stackwallet/models/isar/models/isar_models.dart';
+import 'package:stackwallet/pages/wallet_view/transaction_views/transaction_details_view.dart';
import 'package:stackwallet/providers/global/wallets_provider.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
import 'package:stackwallet/utilities/format.dart';
@@ -16,8 +17,11 @@ import 'package:stackwallet/widgets/conditional_parent.dart';
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
import 'package:stackwallet/widgets/custom_buttons/simple_copy_button.dart';
import 'package:stackwallet/widgets/custom_buttons/simple_edit_button.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
+import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
import 'package:stackwallet/widgets/desktop/secondary_button.dart';
-import 'package:stackwallet/widgets/rounded_white_container.dart';
+import 'package:stackwallet/widgets/icon_widgets/utxo_status_icon.dart';
+import 'package:stackwallet/widgets/rounded_container.dart';
class UtxoDetailsView extends ConsumerStatefulWidget {
const UtxoDetailsView({
@@ -36,7 +40,7 @@ class UtxoDetailsView extends ConsumerStatefulWidget {
}
class _UtxoDetailsViewState extends ConsumerState {
- static const double _spacing = 12;
+ final isDesktop = Util.isDesktop;
late Stream streamUTXO;
UTXO? utxo;
@@ -94,7 +98,7 @@ class _UtxoDetailsViewState extends ConsumerState {
);
return ConditionalParent(
- condition: !Util.isDesktop,
+ condition: !isDesktop,
builder: (child) => Background(
child: Scaffold(
backgroundColor:
@@ -130,233 +134,235 @@ class _UtxoDetailsViewState extends ConsumerState {
),
),
child: StreamBuilder(
- stream: streamUTXO,
- builder: (context, snapshot) {
- if (snapshot.hasData) {
- utxo = snapshot.data!;
- }
-
- return Column(
- crossAxisAlignment: CrossAxisAlignment.stretch,
- children: [
- const SizedBox(
- height: 10,
- ),
- RoundedWhiteContainer(
- child: Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
- Text(
- "${Format.satoshisToAmount(
- utxo!.value,
- coin: coin,
- ).toStringAsFixed(
- coin.decimals,
- )} ${coin.ticker}",
- style: STextStyles.pageTitleH2(context),
- ),
- Text(
- utxo!.isBlocked
- ? "Frozen"
- : confirmed
- ? "Available"
- : "Unconfirmed",
- style: STextStyles.w500_14(context).copyWith(
- color: utxo!.isBlocked
- ? const Color(0xFF7FA2D4) // todo theme
- : confirmed
- ? Theme.of(context)
- .extension()!
- .accentColorGreen
- : Theme.of(context)
- .extension()!
- .accentColorYellow,
- ),
- ),
- ],
- ),
- ),
- const SizedBox(
- height: _spacing,
- ),
- RoundedWhiteContainer(
- child: Column(
- mainAxisSize: MainAxisSize.min,
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
- Text(
- "Label",
- style: STextStyles.w500_14(context).copyWith(
- color: Theme.of(context)
- .extension()!
- .textSubtitle1,
- ),
- ),
- SimpleEditButton(
- editValue: utxo!.name,
- editLabel: "label",
- onValueChanged: (newName) {
- MainDB.instance.putUTXO(
- utxo!.copyWith(
- name: newName,
- ),
- );
- },
- ),
- ],
- ),
- const SizedBox(
- height: 4,
- ),
- Text(
- utxo!.name,
- style: STextStyles.w500_14(context),
- ),
- ],
- ),
- ),
- const SizedBox(
- height: _spacing,
- ),
- RoundedWhiteContainer(
- child: Column(
- mainAxisSize: MainAxisSize.min,
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
- Text(
- "Address",
- style: STextStyles.w500_14(context).copyWith(
- color: Theme.of(context)
- .extension()!
- .textSubtitle1,
- ),
- ),
- SimpleCopyButton(
- data: utxo!.address!,
- ),
- ],
- ),
- const SizedBox(
- height: 4,
- ),
- Text(
- utxo!.address!,
- style: STextStyles.w500_14(context),
- ),
- ],
- ),
- ),
- if (label != null && label!.value.isNotEmpty)
- const SizedBox(
- height: _spacing,
- ),
- if (label != null && label!.value.isNotEmpty)
- RoundedWhiteContainer(
+ stream: streamUTXO,
+ builder: (context, snapshot) {
+ if (snapshot.hasData) {
+ utxo = snapshot.data!;
+ }
+ return ConditionalParent(
+ condition: isDesktop,
+ builder: (child) {
+ return DesktopDialog(
+ maxHeight: double.infinity,
child: Column(
- mainAxisSize: MainAxisSize.min,
- crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
- Text(
- "Address label",
- style: STextStyles.w500_14(context).copyWith(
- color: Theme.of(context)
- .extension()!
- .textSubtitle1,
+ Padding(
+ padding: const EdgeInsets.only(left: 32),
+ child: Text(
+ "Output details",
+ style: STextStyles.desktopH3(context),
),
),
- SimpleCopyButton(
- data: label!.value,
+ DesktopDialogCloseButton(
+ onPressedOverride: () {
+ Navigator.of(context)
+ .pop(_popWithRefresh ? "refresh" : null);
+ },
),
],
),
- const SizedBox(
- height: 4,
- ),
- Text(
- label!.value,
- style: STextStyles.w500_14(context),
+ IntrinsicHeight(
+ child: Padding(
+ padding: const EdgeInsets.only(
+ left: 32,
+ right: 32,
+ bottom: 32,
+ top: 10,
+ ),
+ child: Column(
+ children: [
+ IntrinsicHeight(
+ child: RoundedContainer(
+ padding: EdgeInsets.zero,
+ color: Colors.transparent,
+ borderColor: Theme.of(context)
+ .extension()!
+ .textFieldDefaultBG,
+ child: child,
+ ),
+ ),
+ const SizedBox(
+ height: 20,
+ ),
+ SecondaryButton(
+ buttonHeight: ButtonHeight.l,
+ label: utxo!.isBlocked ? "Unfreeze" : "Freeze",
+ onPressed: _toggleFreeze,
+ ),
+ ],
+ ),
+ ),
),
],
),
- ),
- const SizedBox(
- height: _spacing,
- ),
- RoundedWhiteContainer(
- child: Column(
- mainAxisSize: MainAxisSize.min,
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Row(
+ );
+ },
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.stretch,
+ children: [
+ if (!isDesktop)
+ const SizedBox(
+ height: 10,
+ ),
+ RoundedContainer(
+ padding: const EdgeInsets.all(12),
+ color: isDesktop
+ ? Colors.transparent
+ : Theme.of(context).extension()!.popupBG,
+ child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
- Text(
- "Transaction ID",
- style: STextStyles.w500_14(context).copyWith(
- color: Theme.of(context)
- .extension()!
- .textSubtitle1,
- ),
+ Row(
+ children: [
+ if (isDesktop)
+ UTXOStatusIcon(
+ blocked: utxo!.isBlocked,
+ status: confirmed
+ ? UTXOStatusIconStatus.confirmed
+ : UTXOStatusIconStatus.unconfirmed,
+ background: Theme.of(context)
+ .extension()!
+ .popupBG,
+ selected: false,
+ width: 32,
+ height: 32,
+ ),
+ if (isDesktop)
+ const SizedBox(
+ width: 16,
+ ),
+ Text(
+ "${Format.satoshisToAmount(
+ utxo!.value,
+ coin: coin,
+ ).toStringAsFixed(
+ coin.decimals,
+ )} ${coin.ticker}",
+ style: STextStyles.pageTitleH2(context),
+ ),
+ ],
),
- SimpleCopyButton(
- data: utxo!.txid,
+ Text(
+ utxo!.isBlocked
+ ? "Frozen"
+ : confirmed
+ ? "Available"
+ : "Unconfirmed",
+ style: STextStyles.w500_14(context).copyWith(
+ color: utxo!.isBlocked
+ ? const Color(0xFF7FA2D4) // todo theme
+ : confirmed
+ ? Theme.of(context)
+ .extension()!
+ .accentColorGreen
+ : Theme.of(context)
+ .extension()!
+ .accentColorYellow,
+ ),
),
],
),
- const SizedBox(
- height: 4,
+ ),
+ const _Div(),
+ RoundedContainer(
+ padding: isDesktop
+ ? const EdgeInsets.all(16)
+ : const EdgeInsets.all(12),
+ color: isDesktop
+ ? Colors.transparent
+ : Theme.of(context).extension()!.popupBG,
+ child: Column(
+ mainAxisSize: MainAxisSize.min,
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Text(
+ "Label",
+ style: STextStyles.w500_14(context).copyWith(
+ color: Theme.of(context)
+ .extension()!
+ .textSubtitle1,
+ ),
+ ),
+ SimpleEditButton(
+ editValue: utxo!.name,
+ editLabel: "label",
+ onValueChanged: (newName) {
+ MainDB.instance.putUTXO(
+ utxo!.copyWith(
+ name: newName,
+ ),
+ );
+ },
+ ),
+ ],
+ ),
+ const SizedBox(
+ height: 4,
+ ),
+ Text(
+ utxo!.name,
+ style: STextStyles.w500_14(context),
+ ),
+ ],
),
- Text(
- utxo!.txid,
- style: STextStyles.w500_14(context),
+ ),
+ const _Div(),
+ RoundedContainer(
+ padding: isDesktop
+ ? const EdgeInsets.all(16)
+ : const EdgeInsets.all(12),
+ color: isDesktop
+ ? Colors.transparent
+ : Theme.of(context).extension()!.popupBG,
+ child: Column(
+ mainAxisSize: MainAxisSize.min,
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Text(
+ "Address",
+ style: STextStyles.w500_14(context).copyWith(
+ color: Theme.of(context)
+ .extension()!
+ .textSubtitle1,
+ ),
+ ),
+ isDesktop
+ ? IconCopyButton(
+ data: utxo!.address!,
+ )
+ : SimpleCopyButton(
+ data: utxo!.address!,
+ ),
+ ],
+ ),
+ const SizedBox(
+ height: 4,
+ ),
+ Text(
+ utxo!.address!,
+ style: STextStyles.w500_14(context),
+ ),
+ ],
),
- ],
- ),
- ),
- const SizedBox(
- height: _spacing,
- ),
- RoundedWhiteContainer(
- child: Column(
- mainAxisSize: MainAxisSize.min,
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Text(
- "Confirmations",
- style: STextStyles.w500_14(context).copyWith(
- color: Theme.of(context)
- .extension()!
- .textSubtitle1,
- ),
- ),
- const SizedBox(
- height: 4,
- ),
- Text(
- "${utxo!.getConfirmations(currentHeight)}",
- style: STextStyles.w500_14(context),
- ),
- ],
- ),
- ),
- const SizedBox(
- height: _spacing,
- ),
- if (utxo!.isBlocked)
- Column(
- mainAxisSize: MainAxisSize.min,
- crossAxisAlignment: CrossAxisAlignment.stretch,
- children: [
- RoundedWhiteContainer(
+ ),
+ if (label != null && label!.value.isNotEmpty) const _Div(),
+ if (label != null && label!.value.isNotEmpty)
+ RoundedContainer(
+ padding: isDesktop
+ ? const EdgeInsets.all(16)
+ : const EdgeInsets.all(12),
+ color: isDesktop
+ ? Colors.transparent
+ : Theme.of(context).extension()!.popupBG,
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
@@ -365,53 +371,195 @@ class _UtxoDetailsViewState extends ConsumerState {
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
- "Freeze reason",
+ "Address label",
style: STextStyles.w500_14(context).copyWith(
color: Theme.of(context)
.extension()!
.textSubtitle1,
),
),
- SimpleEditButton(
- editValue: utxo!.blockedReason ?? "",
- editLabel: "freeze reason",
- onValueChanged: (newReason) {
- MainDB.instance.putUTXO(
- utxo!.copyWith(
- blockedReason: newReason,
+ isDesktop
+ ? IconCopyButton(
+ data: utxo!.address!,
+ )
+ : SimpleCopyButton(
+ data: label!.value,
),
- );
- },
- ),
],
),
const SizedBox(
height: 4,
),
Text(
- utxo!.blockedReason ?? "",
+ label!.value,
style: STextStyles.w500_14(context),
),
],
),
),
- const SizedBox(
- height: _spacing,
+ const _Div(),
+ RoundedContainer(
+ padding: isDesktop
+ ? const EdgeInsets.all(16)
+ : const EdgeInsets.all(12),
+ color: isDesktop
+ ? Colors.transparent
+ : Theme.of(context).extension()!.popupBG,
+ child: Column(
+ mainAxisSize: MainAxisSize.min,
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Text(
+ "Transaction ID",
+ style: STextStyles.w500_14(context).copyWith(
+ color: Theme.of(context)
+ .extension()!
+ .textSubtitle1,
+ ),
+ ),
+ isDesktop
+ ? IconCopyButton(
+ data: utxo!.address!,
+ )
+ : SimpleCopyButton(
+ data: utxo!.txid,
+ ),
+ ],
+ ),
+ const SizedBox(
+ height: 4,
+ ),
+ Text(
+ utxo!.txid,
+ style: STextStyles.w500_14(context),
+ ),
+ ],
),
- ],
- ),
- const Spacer(),
- SecondaryButton(
- label: utxo!.isBlocked ? "Unfreeze" : "Freeze",
- onPressed: _toggleFreeze,
+ ),
+ const _Div(),
+ RoundedContainer(
+ padding: isDesktop
+ ? const EdgeInsets.all(16)
+ : const EdgeInsets.all(12),
+ color: isDesktop
+ ? Colors.transparent
+ : Theme.of(context).extension()!.popupBG,
+ child: Column(
+ mainAxisSize: MainAxisSize.min,
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text(
+ "Confirmations",
+ style: STextStyles.w500_14(context).copyWith(
+ color: Theme.of(context)
+ .extension()!
+ .textSubtitle1,
+ ),
+ ),
+ const SizedBox(
+ height: 4,
+ ),
+ Text(
+ "${utxo!.getConfirmations(currentHeight)}",
+ style: STextStyles.w500_14(context),
+ ),
+ ],
+ ),
+ ),
+ if (utxo!.isBlocked) const _Div(),
+ if (utxo!.isBlocked)
+ Column(
+ mainAxisSize: MainAxisSize.min,
+ crossAxisAlignment: CrossAxisAlignment.stretch,
+ children: [
+ RoundedContainer(
+ padding: isDesktop
+ ? const EdgeInsets.all(16)
+ : const EdgeInsets.all(12),
+ color: isDesktop
+ ? Colors.transparent
+ : Theme.of(context)
+ .extension()!
+ .popupBG,
+ child: Column(
+ mainAxisSize: MainAxisSize.min,
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Row(
+ mainAxisAlignment:
+ MainAxisAlignment.spaceBetween,
+ children: [
+ Text(
+ "Freeze reason",
+ style:
+ STextStyles.w500_14(context).copyWith(
+ color: Theme.of(context)
+ .extension()!
+ .textSubtitle1,
+ ),
+ ),
+ SimpleEditButton(
+ editValue: utxo!.blockedReason ?? "",
+ editLabel: "freeze reason",
+ onValueChanged: (newReason) {
+ MainDB.instance.putUTXO(
+ utxo!.copyWith(
+ blockedReason: newReason,
+ ),
+ );
+ },
+ ),
+ ],
+ ),
+ const SizedBox(
+ height: 4,
+ ),
+ Text(
+ utxo!.blockedReason ?? "",
+ style: STextStyles.w500_14(context),
+ ),
+ ],
+ ),
+ ),
+ if (!isDesktop) const _Div(),
+ ],
+ ),
+ if (!isDesktop) const Spacer(),
+ if (!isDesktop)
+ SecondaryButton(
+ label: utxo!.isBlocked ? "Unfreeze" : "Freeze",
+ onPressed: _toggleFreeze,
+ ),
+ if (!isDesktop)
+ const SizedBox(
+ height: 16,
+ ),
+ ],
),
- const SizedBox(
- height: 16,
- ),
- ],
- );
- },
- ),
+ );
+ }),
);
}
}
+
+class _Div extends StatelessWidget {
+ const _Div({Key? key}) : super(key: key);
+
+ @override
+ Widget build(BuildContext context) {
+ if (Util.isDesktop) {
+ return Container(
+ width: double.infinity,
+ height: 1.0,
+ color: Theme.of(context).extension()!.textFieldDefaultBG,
+ );
+ } else {
+ return const SizedBox(
+ height: 12,
+ );
+ }
+ }
+}
diff --git a/lib/pages/exchange_view/confirm_change_now_send.dart b/lib/pages/exchange_view/confirm_change_now_send.dart
index 808a0417f..23712f0fd 100644
--- a/lib/pages/exchange_view/confirm_change_now_send.dart
+++ b/lib/pages/exchange_view/confirm_change_now_send.dart
@@ -64,33 +64,49 @@ class _ConfirmChangeNowSendViewState
final isDesktop = Util.isDesktop;
Future _attemptSend(BuildContext context) async {
+ final manager =
+ ref.read(walletsChangeNotifierProvider).getManager(walletId);
unawaited(
showDialog(
context: context,
useSafeArea: false,
barrierDismissible: false,
builder: (context) {
- return const SendingTransactionDialog();
+ return SendingTransactionDialog(
+ coin: manager.coin,
+ );
},
),
);
+ final time = Future.delayed(
+ const Duration(
+ milliseconds: 2500,
+ ),
+ );
+
+ late String txid;
+ Future txidFuture;
+
final String note = transactionInfo["note"] as String? ?? "";
- final manager =
- ref.read(walletsChangeNotifierProvider).getManager(walletId);
try {
- late final String txid;
-
if (widget.shouldSendPublicFiroFunds == true) {
- txid = await (manager.wallet as FiroWallet)
+ txidFuture = (manager.wallet as FiroWallet)
.confirmSendPublic(txData: transactionInfo);
} else {
- txid = await manager.confirmSend(txData: transactionInfo);
+ txidFuture = manager.confirmSend(txData: transactionInfo);
}
unawaited(manager.refresh());
+ final results = await Future.wait([
+ txidFuture,
+ time,
+ ]);
+
+ txid = results.first as String;
+
// save note
await ref
.read(notesServiceChangeNotifierProvider(walletId))
diff --git a/lib/pages/exchange_view/exchange_step_views/step_4_view.dart b/lib/pages/exchange_view/exchange_step_views/step_4_view.dart
index 1d32b4811..30d40f008 100644
--- a/lib/pages/exchange_view/exchange_step_views/step_4_view.dart
+++ b/lib/pages/exchange_view/exchange_step_views/step_4_view.dart
@@ -536,24 +536,34 @@ class _Step4ViewState extends ConsumerState {
try {
bool wasCancelled = false;
- unawaited(showDialog(
- context: context,
- useSafeArea: false,
- barrierDismissible: false,
- builder: (context) {
- return BuildingTransactionDialog(
- onCancel: () {
- wasCancelled = true;
+ unawaited(
+ showDialog(
+ context: context,
+ useSafeArea: false,
+ barrierDismissible: false,
+ builder: (context) {
+ return BuildingTransactionDialog(
+ coin: manager.coin,
+ onCancel: () {
+ wasCancelled = true;
- Navigator.of(context)
- .pop();
- },
- );
- },
- ));
+ Navigator.of(context)
+ .pop();
+ },
+ );
+ },
+ ),
+ );
- final txData =
- await manager.prepareSend(
+ final time =
+ Future.delayed(
+ const Duration(
+ milliseconds: 2500,
+ ),
+ );
+
+ final txDataFuture =
+ manager.prepareSend(
address: address,
satoshiAmount: amount,
args: {
@@ -563,6 +573,15 @@ class _Step4ViewState extends ConsumerState {
},
);
+ final results =
+ await Future.wait([
+ txDataFuture,
+ time,
+ ]);
+
+ final txData = results.last
+ as Map;
+
if (!wasCancelled) {
// pop building dialog
diff --git a/lib/pages/exchange_view/send_from_view.dart b/lib/pages/exchange_view/send_from_view.dart
index 41df723da..780a88d92 100644
--- a/lib/pages/exchange_view/send_from_view.dart
+++ b/lib/pages/exchange_view/send_from_view.dart
@@ -240,6 +240,7 @@ class _SendFromCardState extends ConsumerState {
),
),
child: BuildingTransactionDialog(
+ coin: manager.coin,
onCancel: () {
wasCancelled = true;
@@ -251,11 +252,18 @@ class _SendFromCardState extends ConsumerState {
),
);
- late Map txData;
+ final time = Future.delayed(
+ const Duration(
+ milliseconds: 2500,
+ ),
+ );
+
+ Map txData;
+ Future