Merge pull request #76 from cypherstack/testing

Dark theme + various small ui fixes
This commit is contained in:
Rylee Davis 2022-09-23 08:52:41 -06:00 committed by GitHub
commit 4c8b2d9ca6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
267 changed files with 24719 additions and 4581 deletions

3
.gitignore vendored
View file

@ -37,6 +37,8 @@ lib/generated_plugin_registrant.dart
test/services/coins/bitcoin/bitcoin_wallet_test_parameters.dart
test/services/coins/firo/firo_wallet_test_parameters.dart
test/services/coins/dogecoin/dogecoin_wallet_test_parameters.dart
test/services/coins/namecoin/namecoin_wallet_test_parameters.dart
test/services/coins/bitcoincash/bitcoincash_wallet_test_parameters.dart
/integration_test/private.dart
# Exceptions to above rules.
@ -46,3 +48,4 @@ test/services/coins/dogecoin/dogecoin_wallet_test_parameters.dart
coverage
scripts/**/build
/lib/external_api_keys.dart
/test/services/coins/bitcoincash/bitcoincash_wallet_test_parameters.dart

Binary file not shown.

After

Width:  |  Height:  |  Size: 354 KiB

BIN
assets/images/namecoin.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 351 KiB

BIN
assets/images/wownero.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 371 KiB

View file

@ -0,0 +1,4 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M11.25 12C12.907 12 14.25 10.657 14.25 9C14.25 7.34297 12.907 6 11.25 6C9.59344 6 8.25 7.34297 8.25 9C8.25 10.657 9.59531 12 11.25 12ZM12.75 13.5H9.75C7.67812 13.5 6 15.1781 6 17.25C6 17.6625 6.3375 18 6.75 18H15.75C16.1642 18 16.5 17.6642 16.5 17.25C16.5 15.1781 14.8219 13.5 12.75 13.5ZM23.25 3H21V7.5H23.25C23.6625 7.5 24 7.1625 24 6.75V3.75C24 3.33562 23.6625 3 23.25 3ZM23.25 15H21V19.5H23.25C23.6642 19.5 24 19.1642 24 18.75V15.75C24 15.3375 23.6625 15 23.25 15ZM23.25 9H21V13.5H23.25C23.6625 13.5 24 13.1625 24 12.75V9.75C24 9.3375 23.6625 9 23.25 9Z" fill="#232323"/>
<path opacity="0.4" d="M18.75 0H3.75C2.50734 0 1.5 1.00734 1.5 2.25V21.75C1.5 22.9922 2.50734 24 3.75 24H18.75C19.9927 24 21 22.9927 21 21.75V2.25C21 1.00734 19.9922 0 18.75 0ZM11.25 6C12.907 6 14.25 7.34297 14.25 9C14.25 10.657 12.907 12 11.25 12C9.59344 12 8.25 10.657 8.25 9C8.25 7.34297 9.59531 6 11.25 6ZM15.75 18H6.75C6.3375 18 6 17.6625 6 17.25C6 15.1781 7.67812 13.5 9.75 13.5H12.75C14.8209 13.5 16.5 15.1791 16.5 17.25C16.5 17.6625 16.1625 18 15.75 18Z" fill="#232323"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M9 18L15 12L9 6" stroke="#8E9192" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 212 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 511.76 511.76"><title>bitcoin-cash-bch</title><circle style="fill:#0ac18e;" cx="255.88" cy="255.88" r="255.88"/><path id="symbol" style="fill:#fff;" d="M335.94,170.3c-12.86-29.16-42.41-35.4-78.59-29.36L245.73,95.87,218.32,103l11.43,44.94c-7.21,1.82-14.61,3.38-21.95,5.46l-11.43-44.68L169,115.75l11.63,45.07c-5.91,1.69-55.33,14.35-55.33,14.35l7.53,29.35s20.13-5.65,19.94-5.19c11.17-2.92,16.43,2.66,18.9,7.92l32,123.53c.39,3.57-.26,9.67-7.92,11.75.45.26-19.94,5.13-19.94,5.13l3,34.23s49-12.54,55.4-14.16l11.76,45.59,27.4-7.08-11.75-45.91q11.3-2.64,22-5.46l11.69,45.66,27.4-7.08-11.75-45.53c42.21-10.26,72-36.89,65.92-77.61-3.9-24.55-30.72-44.68-53-46.95,13.7-12.15,20.65-29.88,12.15-53.06ZM322.75,277.78c5.46,40.33-50.59,45.27-69.1,50.14l-16.11-60.33C256.12,262.71,313.53,242.26,322.75,277.78ZM289,195.63c5.78,35.85-42.15,40-57.61,44L216.7,184.85C232.22,181,277.23,162.44,289,195.63Z" transform="translate(-0.24 -0.34)"/></svg>

After

Width:  |  Height:  |  Size: 978 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32"><g fill="none" fill-rule="evenodd"><circle cx="16" cy="16" r="16" fill="#186C9D"/><path fill="#FFF" fill-rule="nonzero" d="M19.261 23.5l.001-.002a1.8 1.8 0 0 0 .458-.05c.876-.205 1.617-.97 1.793-1.796L25 8.556l-2.772-.014-2.286 8.568-6.18-8.597-.004.004.003-.01L12.74 8.5v.001a1.9 1.9 0 0 0-.459.049c-.875.206-1.616.971-1.793 1.796L7 23.445l2.773.012 2.285-8.568 6.18 8.598h.003l1.02.013zm-6.593-10.894l.483-1.81 6.181 8.599-.483 1.81-6.18-8.6z"/></g></svg>

After

Width:  |  Height:  |  Size: 520 B

View file

@ -0,0 +1,5 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M15 21C15 21.5031 14.6859 22.0406 14.1234 22.4156C13.5609 22.7906 12.7547 23 12 23C11.2031 23 10.4391 22.7906 9.87656 22.4156C9.31406 22.0406 9 21.5031 9 21H15Z" fill="#E0E3E3"/>
<path d="M13.4279 2.38462V3.21538C16.6867 3.85707 19.1419 6.65096 19.1419 10V10.8135C19.1419 12.8514 19.9142 14.8115 21.307 16.3346L21.6373 16.6938C22.0123 17.1048 22.106 17.6846 21.8739 18.1822C21.6418 18.6798 21.1329 19 20.5704 19H3.42848C2.86601 19 2.35582 18.6798 2.12538 18.1822C1.89495 17.6846 1.98712 17.1048 2.36086 16.6938L2.69192 16.3346C4.08648 14.8115 4.85697 12.8514 4.85697 10.8135V10C4.85697 6.65096 7.27202 3.85707 10.5709 3.21538V2.38462C10.5709 1.62005 11.2093 1 11.9994 1C12.7896 1 13.4279 1.62005 13.4279 2.38462Z" fill="#E0E3E3"/>
<circle cx="20.5" cy="3.5" r="2.5" fill="#C00205"/>
</svg>

After

Width:  |  Height:  |  Size: 895 B

View file

@ -0,0 +1,18 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_5101_18544)">
<g opacity="0.4">
<path d="M22.2 6C23.3297 5.37187 24 4.59422 24 3.75C24 1.67906 19.9688 0 15 0C9.98906 0 6 1.67906 6 3.75C6 4.59422 6.67031 5.37187 7.8 6C7.80937 6.00469 7.81758 6.00937 7.82578 6.01406C7.83398 6.01875 7.84219 6.02344 7.85156 6.02813C8.23125 6.00938 8.61094 6 9 6C11.6344 6 14.0906 6.44062 15.9422 7.21406C16.1203 7.28906 16.2984 7.36875 16.4672 7.44844C18.8062 7.28906 20.8359 6.75469 22.2 6Z" fill="white"/>
<path d="M19.9435 12.9151C19.7958 12.9551 19.6477 12.9951 19.5 13.0359V13.5C20.7602 13.5 21.9296 13.8885 22.8951 14.5522C23.5995 14.0172 24 13.4028 24 12.75V11.0906C23.4141 11.5734 22.7063 11.9672 21.9422 12.2859C21.3382 12.5376 20.6447 12.7253 19.9435 12.9151Z" fill="white"/>
<path d="M18.3703 8.74688C19.0031 9.37969 19.5 10.2234 19.5 11.25V11.4984C20.4328 11.2734 21.2625 10.9781 21.9469 10.6359C21.9739 10.6209 22.0009 10.6021 22.0279 10.5833C22.0852 10.5432 22.1426 10.5032 22.2 10.5C23.3297 9.87187 24 9.09375 24 8.25V6.59063C23.4141 7.07344 22.7063 7.46719 21.9422 7.78594C20.9109 8.2125 19.6969 8.54063 18.3703 8.74688Z" fill="white"/>
</g>
<path d="M16.2 13.5C17.3297 12.8719 18 12.0938 18 11.25C18 9.17813 13.9688 7.5 9 7.5C4.02938 7.5 0 9.17813 0 11.25C0 12.0938 0.669375 12.8719 1.79953 13.5C1.85443 13.5031 1.91057 13.5415 1.96782 13.5807C1.9966 13.6004 2.02567 13.6203 2.055 13.6359C3.70594 14.4703 6.20625 15 9 15C11.9438 15 14.5594 14.4094 16.2 13.5Z" fill="white"/>
<path d="M14.8788 15.6729C13.1948 16.2046 11.1571 16.5 9 16.5C6.36562 16.5 3.91125 16.0594 2.05922 15.2859C1.29469 14.9672 0.583594 14.5734 0 14.0906V15.75C0 16.5938 0.669375 17.3719 1.79953 18C3.44109 18.9094 6.05625 19.5 9 19.5C10.6471 19.5 12.1916 19.3159 13.5211 18.9937C13.6261 17.7367 14.1186 16.5898 14.8788 15.6729Z" fill="white"/>
<path d="M13.5862 20.5191C13.7529 21.4936 14.1547 22.3879 14.731 23.1415C13.1742 23.6778 11.1771 24 9 24C4.02938 24 0 22.3219 0 20.25V18.5906C0.583594 19.0734 1.29469 19.4672 2.05922 19.7859C3.91125 20.5594 6.36562 21 9 21C10.6307 21 12.1932 20.8312 13.5862 20.5191Z" fill="white"/>
<path d="M24 19.5C24 21.9844 21.9844 24 19.5 24C17.0156 24 15 21.9844 15 19.5C15 17.0156 17.0156 15 19.5 15C21.9844 15 24 17.0156 24 19.5ZM19 17.4719V18.9719H17.5C17.225 18.9719 17 19.225 17 19.4719C17 19.775 17.225 19.9719 17.5 19.9719H19V21.4719C19 21.775 19.225 21.9719 19.5 21.9719C19.775 21.9719 20 21.775 20 21.4719V19.9719H21.5C21.775 19.9719 22 19.775 22 19.4719C22 19.225 21.775 18.9719 21.5 18.9719H20V17.4719C20 17.225 19.775 16.9719 19.5 16.9719C19.225 16.9719 19 17.225 19 17.4719Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_5101_18544">
<rect width="24" height="24" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

View file

@ -0,0 +1,11 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_5101_7226)">
<path d="M19.5 6.5L20.4343 7.33045C20.8552 6.85685 20.8552 6.14315 20.4343 5.66955L19.5 6.5ZM16.4343 1.16955C15.9756 0.653567 15.1855 0.607091 14.6695 1.06574C14.1536 1.52439 14.1071 2.31448 14.5657 2.83045L16.4343 1.16955ZM14.5657 10.1695C14.1071 10.6855 14.1536 11.4756 14.6695 11.9343C15.1855 12.3929 15.9756 12.3464 16.4343 11.8305L14.5657 10.1695ZM0.75 10.5C0.75 11.1904 1.30964 11.75 2 11.75C2.69036 11.75 3.25 11.1904 3.25 10.5H0.75ZM6 7.75H19.5V5.25H6V7.75ZM14.5657 2.83045L18.5657 7.33045L20.4343 5.66955L16.4343 1.16955L14.5657 2.83045ZM16.4343 11.8305L20.4343 7.33045L18.5657 5.66955L14.5657 10.1695L16.4343 11.8305ZM3.25 10.5C3.25 8.98122 4.48122 7.75 6 7.75V5.25C3.10051 5.25 0.75 7.60051 0.75 10.5H3.25Z" fill="white"/>
<path opacity="0.4" d="M4.5 18L3.56574 17.1695C3.14475 17.6432 3.14475 18.3568 3.56574 18.8305L4.5 18ZM7.56574 23.3305C8.02439 23.8464 8.81448 23.8929 9.33045 23.4343C9.84643 22.9756 9.89291 22.1855 9.43426 21.6695L7.56574 23.3305ZM9.43426 14.3305C9.89291 13.8145 9.84643 13.0244 9.33046 12.5657C8.81448 12.1071 8.02439 12.1536 7.56574 12.6695L9.43426 14.3305ZM23.25 14C23.25 13.3096 22.6904 12.75 22 12.75C21.3096 12.75 20.75 13.3096 20.75 14L23.25 14ZM18 16.75L4.5 16.75L4.5 19.25L18 19.25L18 16.75ZM9.43426 21.6695L5.43426 17.1695L3.56574 18.8305L7.56574 23.3305L9.43426 21.6695ZM7.56574 12.6695L3.56574 17.1695L5.43426 18.8305L9.43426 14.3305L7.56574 12.6695ZM20.75 14C20.75 15.5188 19.5188 16.75 18 16.75L18 19.25C20.8995 19.25 23.25 16.8995 23.25 14L20.75 14Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_5101_7226">
<rect width="24" height="24" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View file

@ -0,0 +1,5 @@
<svg width="60" height="47" viewBox="0 0 60 47" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M35.4652 0.708774C31.9724 -1.30683 27.6074 1.21691 27.6074 5.24811C27.6074 9.27931 29.5549 12.7727 32.7471 14.9281L46.2653 22.7661L46.2992 22.7534L59.9995 14.8349L35.4652 0.708774Z" fill="white"/>
<path d="M32.7438 14.9285C29.5515 12.7731 27.604 9.14421 27.604 5.24851C27.604 3.3303 28.6074 1.72968 30.0342 0.823501C29.9664 0.861612 30.1019 0.785391 30.0342 0.823501L8.64977 12.8409L5.21624 14.9158L2.875 16.2623C4.34833 15.5128 6.19422 15.4535 7.84113 16.4105L13.7302 19.7642L18.8911 22.7495L32.5913 30.6552L46.2577 22.758L32.7395 14.92L32.7438 14.9285Z" fill="#999999"/>
<path d="M60 30.6636L32.5953 46.5005L27.4217 43.5152L27.4005 43.494L5.19475 30.6636C3.67485 29.6728 2.43861 28.322 1.56647 26.8018C0.550381 25.0487 0 23.0331 0 20.9455C0 19.0654 0.944115 17.5114 2.31583 16.5883C2.50212 16.4739 2.68417 16.3681 2.87892 16.2665C4.35224 15.517 6.19814 15.4577 7.84505 16.4147L13.7003 19.7938L18.8611 22.7664L18.895 22.7536L32.5953 30.6594L46.2616 22.7621L60 30.6594V30.6636Z" fill="#4C4C4C"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -0,0 +1,14 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_5094_29952)">
<path d="M23.0154 16.7681C23.6489 15.3066 24 13.6943 24 12C24 5.37258 18.6274 0 12 0C5.37258 0 0 5.37258 0 12C0 18.6274 5.37258 24 12 24C13.6943 24 15.3066 23.6489 16.7681 23.0154C16.2832 22.2973 16 21.4317 16 20.5C16 18.0147 18.0147 16 20.5 16C21.4317 16 22.2973 16.2832 23.0154 16.7681Z" fill="#B4C4FF"/>
<path d="M5.30071 12.4C4.91018 12.7905 4.91018 13.4236 5.30071 13.8142C5.69123 14.2047 6.32439 14.2047 6.71492 13.8142L5.30071 12.4ZM13.0789 6.03599L14.0787 6.05567C14.0839 5.78863 13.9821 5.53058 13.796 5.33904C13.6098 5.1475 13.3548 5.03839 13.0877 5.03603L13.0789 6.03599ZM9.00968 5.00004C8.45741 4.99516 8.00576 5.43891 8.00089 5.99117C7.99601 6.54344 8.43976 6.99509 8.99202 6.99996L9.00968 5.00004ZM12.001 9.98032C11.9902 10.5325 12.429 10.9889 12.9812 10.9998C13.5333 11.0107 13.9898 10.5719 14.0007 10.0197L12.001 9.98032ZM18.6429 11.6C19.0334 11.2095 19.0334 10.5764 18.6429 10.1858C18.2524 9.79531 17.6192 9.79531 17.2287 10.1858L18.6429 11.6ZM10.8647 17.964L9.8653 17.9297C9.85604 18.1992 9.95602 18.461 10.1426 18.6557C10.3291 18.8505 10.5864 18.9616 10.856 18.964L10.8647 17.964ZM14.9922 19C15.5444 19.0048 15.996 18.561 16.0008 18.0087C16.0056 17.4564 15.5618 17.0048 15.0096 17L14.9922 19ZM12.0003 14.0343C12.0192 13.4824 11.5871 13.0195 11.0352 13.0006C10.4832 12.9816 10.0204 13.4137 10.0014 13.9657L12.0003 14.0343ZM6.71492 13.8142L13.786 6.7431L12.3718 5.32889L5.30071 12.4L6.71492 13.8142ZM8.99202 6.99996L13.0701 7.03595L13.0877 5.03603L9.00968 5.00004L8.99202 6.99996ZM12.0791 6.01631L12.001 9.98032L14.0007 10.0197L14.0787 6.05567L12.0791 6.01631ZM17.2287 10.1858L10.1576 17.2569L11.5718 18.6711L18.6429 11.6L17.2287 10.1858ZM15.0096 17L10.8734 16.964L10.856 18.964L14.9922 19L15.0096 17ZM11.8641 17.9983L12.0003 14.0343L10.0014 13.9657L9.8653 17.9297L11.8641 17.9983Z" fill="#00297A"/>
<circle cx="20.5" cy="20.5" r="3.5" fill="#D34E50"/>
<path d="M19.4395 19.4395L20.5001 20.5001L21.5608 21.5608" stroke="#2A2D34" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M19.5 21.5605L20.5607 20.4999L21.6213 19.4392" stroke="#2A2D34" stroke-linecap="round" stroke-linejoin="round"/>
</g>
<defs>
<clipPath id="clip0_5094_29952">
<rect width="24" height="24" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View file

@ -0,0 +1,13 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_5094_29944)">
<path d="M23.0154 16.7681C23.6489 15.3066 24 13.6943 24 12C24 5.37258 18.6274 0 12 0C5.37258 0 0 5.37258 0 12C0 18.6274 5.37258 24 12 24C13.6943 24 15.3066 23.6489 16.7681 23.0154C16.2832 22.2973 16 21.4317 16 20.5C16 18.0147 18.0147 16 20.5 16C21.4317 16 22.2973 16.2832 23.0154 16.7681Z" fill="#B4C4FF"/>
<circle cx="20.5" cy="20.5" r="3.5" fill="#F7D65D"/>
<path d="M20.5 19V20.5H21.5" stroke="#2A2D34" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M5.30071 12.4C4.91018 12.7905 4.91018 13.4236 5.30071 13.8142C5.69123 14.2047 6.32439 14.2047 6.71492 13.8142L5.30071 12.4ZM13.0789 6.03599L14.0787 6.05567C14.0839 5.78863 13.9821 5.53058 13.796 5.33904C13.6098 5.1475 13.3548 5.03839 13.0877 5.03603L13.0789 6.03599ZM9.00968 5.00004C8.45741 4.99516 8.00576 5.43891 8.00089 5.99117C7.99601 6.54344 8.43976 6.99509 8.99202 6.99996L9.00968 5.00004ZM12.001 9.98032C11.9902 10.5325 12.429 10.9889 12.9812 10.9998C13.5333 11.0107 13.9898 10.5719 14.0007 10.0197L12.001 9.98032ZM18.6429 11.6C19.0334 11.2095 19.0334 10.5764 18.6429 10.1858C18.2524 9.79531 17.6192 9.79531 17.2287 10.1858L18.6429 11.6ZM10.8647 17.964L9.8653 17.9297C9.85605 18.1992 9.95602 18.461 10.1426 18.6557C10.3291 18.8505 10.5864 18.9616 10.856 18.964L10.8647 17.964ZM14.9922 19C15.5444 19.0048 15.996 18.561 16.0008 18.0087C16.0056 17.4564 15.5618 17.0048 15.0096 17L14.9922 19ZM12.0003 14.0343C12.0192 13.4824 11.5871 13.0195 11.0352 13.0006C10.4832 12.9816 10.0204 13.4137 10.0014 13.9657L12.0003 14.0343ZM6.71492 13.8142L13.786 6.7431L12.3718 5.32889L5.30071 12.4L6.71492 13.8142ZM8.99202 6.99996L13.0701 7.03595L13.0877 5.03603L9.00968 5.00004L8.99202 6.99996ZM12.0791 6.01631L12.001 9.98032L14.0007 10.0197L14.0787 6.05567L12.0791 6.01631ZM17.2287 10.1858L10.1576 17.2569L11.5718 18.6711L18.6429 11.6L17.2287 10.1858ZM15.0096 17L10.8734 16.964L10.856 18.964L14.9922 19L15.0096 17ZM11.8641 17.9983L12.0003 14.0343L10.0014 13.9657L9.8653 17.9297L11.8641 17.9983Z" fill="#00297A"/>
</g>
<defs>
<clipPath id="clip0_5094_29944">
<rect width="24" height="24" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

View file

@ -0,0 +1,11 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_5094_29949)">
<circle cx="12" cy="12" r="12" fill="#B4C4FF"/>
<path d="M5.30071 12.4C4.91018 12.7905 4.91018 13.4236 5.30071 13.8142C5.69123 14.2047 6.32439 14.2047 6.71492 13.8142L5.30071 12.4ZM13.0789 6.03599L14.0787 6.05567C14.0839 5.78863 13.9821 5.53058 13.796 5.33904C13.6098 5.1475 13.3548 5.03839 13.0877 5.03603L13.0789 6.03599ZM9.00968 5.00004C8.45741 4.99516 8.00576 5.43891 8.00089 5.99117C7.99601 6.54344 8.43976 6.99509 8.99202 6.99996L9.00968 5.00004ZM12.001 9.98032C11.9902 10.5325 12.429 10.9889 12.9812 10.9998C13.5333 11.0107 13.9898 10.5719 14.0007 10.0197L12.001 9.98032ZM18.6429 11.6C19.0334 11.2095 19.0334 10.5764 18.6429 10.1858C18.2524 9.79531 17.6192 9.79531 17.2287 10.1858L18.6429 11.6ZM10.8647 17.964L9.8653 17.9297C9.85604 18.1992 9.95602 18.461 10.1426 18.6557C10.3291 18.8505 10.5864 18.9616 10.856 18.964L10.8647 17.964ZM14.9922 19C15.5444 19.0048 15.996 18.561 16.0008 18.0087C16.0056 17.4564 15.5618 17.0048 15.0096 17L14.9922 19ZM12.0003 14.0343C12.0192 13.4824 11.5871 13.0195 11.0352 13.0006C10.4832 12.9816 10.0204 13.4137 10.0014 13.9657L12.0003 14.0343ZM6.71492 13.8142L13.786 6.7431L12.3718 5.32889L5.30071 12.4L6.71492 13.8142ZM8.99202 6.99996L13.0701 7.03595L13.0877 5.03603L9.00968 5.00004L8.99202 6.99996ZM12.0791 6.01631L12.001 9.98032L14.0007 10.0197L14.0787 6.05567L12.0791 6.01631ZM17.2287 10.1858L10.1576 17.2569L11.5718 18.6711L18.6429 11.6L17.2287 10.1858ZM15.0096 17L10.8734 16.964L10.856 18.964L14.9922 19L15.0096 17ZM11.8641 17.9983L12.0003 14.0343L10.0014 13.9657L9.8653 17.9297L11.8641 17.9983Z" fill="#00297A"/>
</g>
<defs>
<clipPath id="clip0_5094_29949">
<rect width="24" height="24" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View file

@ -0,0 +1,14 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_5094_29925)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M23.0154 16.7681C23.6489 15.3066 24 13.6943 24 12C24 5.37258 18.6274 0 12 0C5.37258 0 0 5.37258 0 12C0 18.6274 5.37258 24 12 24C13.6943 24 15.3066 23.6489 16.7681 23.0154C16.2832 22.2973 16 21.4317 16 20.5C16 18.0147 18.0147 16 20.5 16C21.4317 16 22.2973 16.2832 23.0154 16.7681Z" fill="#8EF5C3"/>
<circle cx="20.5" cy="20.5" r="3.5" fill="#D34E50"/>
<path d="M16 8L8 16M8 16H14M8 16V10" stroke="#003921" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M19.4395 19.4395L20.5001 20.5001L21.5608 21.5608" stroke="#2A2D34" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M19.5 21.5605L20.5607 20.4999L21.6213 19.4392" stroke="#2A2D34" stroke-linecap="round" stroke-linejoin="round"/>
</g>
<defs>
<clipPath id="clip0_5094_29925">
<rect width="24" height="24" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1,020 B

View file

@ -0,0 +1,12 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_5094_29921)">
<path d="M23.0154 16.7681C23.6489 15.3066 24 13.6943 24 12C24 5.37258 18.6274 0 12 0C5.37258 0 0 5.37258 0 12C0 18.6274 5.37258 24 12 24C13.6943 24 15.3066 23.6489 16.7681 23.0154C16.2832 22.2973 16 21.4317 16 20.5C16 18.0147 18.0147 16 20.5 16C21.4317 16 22.2973 16.2832 23.0154 16.7681Z" fill="#8EF5C3"/>
<path d="M16 8L8 16M8 16H14M8 16V10" stroke="#003921" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M20.5 24C22.433 24 24 22.433 24 20.5C24 18.567 22.433 17 20.5 17C18.567 17 17 18.567 17 20.5C17 22.433 18.567 24 20.5 24ZM21 19C21 18.7239 20.7761 18.5 20.5 18.5C20.2239 18.5 20 18.7239 20 19V20.5C20 20.7761 20.2239 21 20.5 21H21.5C21.7761 21 22 20.7761 22 20.5C22 20.2239 21.7761 20 21.5 20H21V19Z" fill="#F7D65D"/>
</g>
<defs>
<clipPath id="clip0_5094_29921">
<rect width="24" height="24" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1 KiB

View file

@ -0,0 +1,11 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_5094_29958)">
<circle cx="12" cy="12" r="12" fill="#8EF5C3"/>
<path d="M16 8L8 16M8 16H14M8 16V10" stroke="#003921" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>
</g>
<defs>
<clipPath id="clip0_5094_29958">
<rect width="24" height="24" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 421 B

View file

@ -0,0 +1,14 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_5094_29938)">
<path d="M23.0154 16.7681C23.6489 15.3066 24 13.6943 24 12C24 5.37258 18.6274 0 12 0C5.37258 0 0 5.37258 0 12C0 18.6274 5.37258 24 12 24C13.6943 24 15.3066 23.6489 16.7681 23.0154C16.2832 22.2973 16 21.4317 16 20.5C16 18.0147 18.0147 16 20.5 16C21.4317 16 22.2973 16.2832 23.0154 16.7681Z" fill="#FFB4A9"/>
<path d="M8 16L16 8M16 8L10 8M16 8L16 14" stroke="#690001" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>
<circle cx="20.5" cy="20.5" r="3.5" fill="#D34E50"/>
<path d="M19.4395 19.4395L20.5001 20.5001L21.5608 21.5608" stroke="#2A2D34" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M19.5 21.5605L20.5607 20.4999L21.6213 19.4392" stroke="#2A2D34" stroke-linecap="round" stroke-linejoin="round"/>
</g>
<defs>
<clipPath id="clip0_5094_29938">
<rect width="24" height="24" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 985 B

View file

@ -0,0 +1,13 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_5094_29933)">
<path d="M23.0154 16.7681C23.6489 15.3066 24 13.6943 24 12C24 5.37258 18.6274 0 12 0C5.37258 0 0 5.37258 0 12C0 18.6274 5.37258 24 12 24C13.6943 24 15.3066 23.6489 16.7681 23.0154C16.2832 22.2973 16 21.4317 16 20.5C16 18.0147 18.0147 16 20.5 16C21.4317 16 22.2973 16.2832 23.0154 16.7681Z" fill="#FFB4A9"/>
<path d="M8 16L16 8M16 8L10 8M16 8L16 14" stroke="#690001" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>
<circle cx="20.5" cy="20.5" r="3.5" fill="#F7D65D"/>
<path d="M20.5 19V20.5H21.5" stroke="#2A2D34" stroke-linecap="round" stroke-linejoin="round"/>
</g>
<defs>
<clipPath id="clip0_5094_29933">
<rect width="24" height="24" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 833 B

View file

@ -0,0 +1,11 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_5094_29961)">
<circle cx="12" cy="12" r="12" fill="#FFB4A9"/>
<path d="M8 16L16 8M16 8L10 8M16 8L16 14" stroke="#690001" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>
</g>
<defs>
<clipPath id="clip0_5094_29961">
<rect width="24" height="24" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 426 B

View file

@ -0,0 +1,4 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="24" height="24" rx="4" fill="#999999"/>
<path d="M4.11878 12.405C3.62916 12.8917 3.62678 13.6832 4.11346 14.1728C4.60014 14.6624 5.3916 14.6648 5.88122 14.1781L4.11878 12.405ZM13.2994 5.04199L14.5492 5.06674C14.5558 4.7329 14.4285 4.41028 14.1958 4.17083C13.9631 3.93137 13.6443 3.79497 13.3104 3.79204L13.2994 5.04199ZM8.52393 3.75005C7.8336 3.74399 7.26907 4.2987 7.26301 4.98903C7.25696 5.67936 7.81167 6.2439 8.502 6.24995L8.52393 3.75005ZM11.9581 9.64191C11.9444 10.3321 12.4928 10.9028 13.1831 10.9164C13.8733 10.9301 14.4439 10.3816 14.4576 9.69141L11.9581 9.64191ZM19.8812 11.595C20.3708 11.1083 20.3732 10.3168 19.8865 9.82721C19.3999 9.33759 18.6084 9.3352 18.1188 9.82189L19.8812 11.595ZM10.7006 18.958L9.45135 18.9148C9.4397 19.2518 9.56465 19.5791 9.79784 19.8226C10.031 20.0661 10.3527 20.205 10.6898 20.208L10.7006 18.958ZM15.5444 20.25C16.2348 20.2559 16.7992 19.7011 16.8052 19.0108C16.8112 18.3205 16.2564 17.756 15.5661 17.75L15.5444 20.25ZM12.1096 14.3765C12.1335 13.6866 11.5935 13.1079 10.9036 13.0841C10.2136 13.0602 9.63497 13.6002 9.61114 14.2902L12.1096 14.3765ZM5.88122 14.1781L14.1806 5.92853L12.4182 4.15545L4.11878 12.405L5.88122 14.1781ZM8.502 6.24995L13.2884 6.29194L13.3104 3.79204L8.52393 3.75005L8.502 6.24995ZM12.0496 5.01724L11.9581 9.64191L14.4576 9.69141L14.5492 5.06674L12.0496 5.01724ZM18.1188 9.82189L9.81938 18.0715L11.5818 19.8445L19.8812 11.595L18.1188 9.82189ZM15.5661 17.75L10.7114 17.708L10.6898 20.208L15.5444 20.25L15.5661 17.75ZM11.9499 19.0012L12.1096 14.3765L9.61114 14.2902L9.45135 18.9148L11.9499 19.0012Z" fill="#232323"/>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View file

Before

Width:  |  Height:  |  Size: 895 B

After

Width:  |  Height:  |  Size: 895 B

View file

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

View file

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -0,0 +1,5 @@
<svg width="70" height="70" viewBox="0 0 70 70" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M41.3715 9.57675C37.2965 7.22564 32.2041 10.1695 32.2041 14.8717C32.2041 19.5739 34.4762 23.6489 38.2004 26.163L53.9717 35.3057L54.0112 35.2908L69.9948 26.0543L41.3715 9.57675Z" fill="#B3B3B3"/>
<path d="M38.2014 26.163C34.4771 23.6489 32.205 19.4159 32.205 14.8717C32.205 12.6342 33.3757 10.7671 35.0402 9.7101C34.9612 9.75455 35.1192 9.66564 35.0402 9.7101L10.0917 23.7279L6.08593 26.1481L3.35449 27.7188C5.07337 26.8446 7.22692 26.7754 9.14831 27.8917L16.0189 31.8037L22.0399 35.2859L38.0236 44.5076L53.9677 35.2958L38.1964 26.1531L38.2014 26.163Z" fill="#666666"/>
<path d="M70 44.5187L38.0278 62.9917L31.992 59.5095L31.9673 59.4848L6.06054 44.5187C4.28733 43.3629 2.84505 41.7872 1.82755 40.014C0.642111 37.9691 0 35.618 0 33.1829C0 30.9899 1.10147 29.1771 2.70181 28.1004C2.91914 27.967 3.13153 27.8435 3.35874 27.725C5.07762 26.8507 7.23116 26.7816 9.15256 27.8979L15.9836 31.8394L22.0047 35.3068L22.0442 35.292L38.0278 44.5137L53.9719 35.3019L70 44.5137V44.5187Z" fill="#232323"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

View file

Before

Width:  |  Height:  |  Size: 2 KiB

After

Width:  |  Height:  |  Size: 2 KiB

View file

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View file

Before

Width:  |  Height:  |  Size: 882 B

After

Width:  |  Height:  |  Size: 882 B

View file

Before

Width:  |  Height:  |  Size: 912 B

After

Width:  |  Height:  |  Size: 912 B

View file

Before

Width:  |  Height:  |  Size: 287 B

After

Width:  |  Height:  |  Size: 287 B

View file

Before

Width:  |  Height:  |  Size: 847 B

After

Width:  |  Height:  |  Size: 847 B

View file

Before

Width:  |  Height:  |  Size: 697 B

After

Width:  |  Height:  |  Size: 697 B

View file

Before

Width:  |  Height:  |  Size: 292 B

After

Width:  |  Height:  |  Size: 292 B

View file

@ -0,0 +1,10 @@
<svg width="22" height="22" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_5241_16732)">
<path d="M19.25 0H2.75C1.2302 0 0 1.22977 0 2.71133V15.0477C0 16.6461 1.2302 17.8363 2.75 17.8363H6.875V21.407C6.875 21.8313 7.3584 22.0739 7.69656 21.8216L13.0625 17.8363H19.25C20.7702 17.8363 22 16.6061 22 15.125V2.71133C22 1.22977 20.7711 0 19.25 0ZM10.7035 13.75C10.1148 13.75 9.625 13.2602 9.625 12.6328C9.625 12.0055 10.1148 11.5156 10.7035 11.5156C11.3695 11.5156 11.8594 12.0055 11.8594 12.6328C11.8594 13.2602 11.3695 13.75 10.7035 13.75ZM13.2215 8.73984L11.5745 9.73371V9.8047C11.5745 10.2662 11.1806 10.6568 10.7151 10.6568C10.2498 10.6568 9.85574 10.2663 9.85574 9.8047V9.19961C9.85574 8.91563 9.99891 8.63156 10.2854 8.4541L12.3264 7.24711C12.577 7.14141 12.7188 6.89219 12.7188 6.60859C12.7188 6.1826 12.3606 5.82785 11.9311 5.82785H10.0676C9.63789 5.82785 9.27996 6.18277 9.27996 6.60859C9.27996 7.07008 8.88611 7.46066 8.42059 7.46066C7.95506 7.46066 7.5625 7.07266 7.5625 6.60859C7.5625 5.225 8.67109 4.125 10.0676 4.125H11.9294C13.3289 4.125 14.4375 5.225 14.4375 6.60859C14.4375 7.46367 13.9734 8.28008 13.2215 8.73984Z" fill="#232323"/>
</g>
<defs>
<clipPath id="clip0_5241_16732">
<rect width="22" height="22" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

10
assets/svg/minimize.svg Normal file
View file

@ -0,0 +1,10 @@
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_5203_31720)">
<path d="M1.28098 11.7793L4.12559 8.93633V10.1246C4.12559 10.5392 4.46098 10.8746 4.87559 10.8746C5.29019 10.8746 5.62559 10.5392 5.62559 10.1246V7.12461C5.62559 7.02702 5.60572 6.9298 5.56781 6.8382C5.49199 6.65352 5.34668 6.5082 5.16152 6.4332C5.07012 6.39336 4.97402 6.37461 4.87559 6.37461H1.87559C1.46098 6.37461 1.12559 6.71 1.12559 7.12461C1.12559 7.53922 1.46098 7.87461 1.87559 7.87461H3.06504L0.219727 10.7199C-0.0732422 11.0129 -0.0732422 11.4875 0.219727 11.7805C0.512695 12.0734 0.988008 12.0723 1.28098 11.7793ZM6.43418 5.16055C6.51016 5.3443 6.65634 5.49055 6.84012 5.56648C6.93105 5.60586 7.02715 5.62461 7.12559 5.62461H10.1256C10.5402 5.62461 10.8756 5.28922 10.8756 4.87461C10.8756 4.46 10.5402 4.12461 10.1256 4.12461H8.93613L11.7814 1.2793C12.0744 0.986328 12.0744 0.511719 11.7814 0.21875C11.4887 -0.0739843 11.0141 -0.0744531 10.7209 0.21875L7.87559 3.06523V1.87461C7.87559 1.46 7.54019 1.12461 7.12559 1.12461C6.71098 1.12461 6.37559 1.46 6.37559 1.87461V4.85352C6.37559 4.97305 6.39434 5.06914 6.43418 5.16055Z" fill="#E0E3E3"/>
</g>
<defs>
<clipPath id="clip0_5203_31720">
<rect width="12" height="12" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

@ -1,12 +0,0 @@
<svg width="102" height="102" viewBox="0 0 102 102" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_3358_84804)">
<path d="M60.2849 13.9547C54.3472 10.5288 46.9268 14.8184 46.9268 21.6702C46.9268 28.522 50.2375 34.4598 55.6643 38.1232L78.6452 51.4454L78.7028 51.4238L101.993 37.9649L60.2849 13.9547Z" fill="#B3B3B3"/>
<path d="M55.6646 38.1228C50.2378 34.4593 46.9271 28.2913 46.9271 21.6697C46.9271 18.4094 48.6328 15.6888 51.0583 14.1486C50.9431 14.2134 51.1735 14.0838 51.0583 14.1486L14.7048 34.5745L8.8678 38.1012L4.8877 40.3899C7.39235 39.116 10.5304 39.0152 13.3301 40.6418L23.3415 46.3421L32.115 51.4161L55.4055 64.8535L78.6383 51.4305L55.6574 38.1084L55.6646 38.1228Z" fill="#666666"/>
<path d="M102 64.8678L55.4119 91.7857L46.6168 86.7116L46.5809 86.6756L8.83108 64.8678C6.24725 63.1837 4.14564 60.8877 2.663 58.3039C0.935648 55.3242 0 51.8983 0 48.3501C0 45.1545 1.605 42.513 3.93692 40.944C4.2536 40.7497 4.56308 40.5698 4.89416 40.397C7.39882 39.1231 10.5368 39.0224 13.3366 40.649L23.2904 46.3924L32.0639 51.4449L32.1215 51.4233L55.4119 64.8606L78.6448 51.4377L102 64.8606V64.8678Z" fill="#232323"/>
</g>
<defs>
<clipPath id="clip0_3358_84804">
<rect width="102" height="102" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

4
assets/svg/wallet-fa.svg Normal file
View file

@ -0,0 +1,4 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M2.25 5.95781L21 6C21.0187 6 21.0422 6 21.0609 6C21.5859 6.01406 22.0734 6.16875 22.5 6.41719V6.40313C23.3953 6.91875 24 7.88906 24 9V19.5C24 21.1547 22.6547 22.5 21 22.5H3C1.34297 22.5 0 21.1547 0 19.5V3.75C0 4.99219 1.00734 6 2.25 6V5.95781ZM19.5 15.75C20.3297 15.75 21 15.0797 21 14.25C21 13.4203 20.3297 12.75 19.5 12.75C18.6703 12.75 18 13.4203 18 14.25C18 15.0797 18.6703 15.75 19.5 15.75Z" fill="#232323"/>
<path opacity="0.4" d="M0 3.75C0 2.50734 1.00734 1.5 2.25 1.5H20.25C21.4922 1.5 22.5 2.50734 22.5 3.75V6.40313C22.0594 6.14531 21.5484 6 21 6H2.25C1.00734 6 0 4.99219 0 3.75Z" fill="#232323"/>
</svg>

After

Width:  |  Height:  |  Size: 719 B

View file

@ -9,7 +9,6 @@ import 'package:stackwallet/models/notification_model.dart';
import 'package:stackwallet/models/trade_wallet_lookup.dart';
import 'package:stackwallet/services/wallets_service.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
import 'package:stackwallet/utilities/logger.dart';
class DB {
@ -30,6 +29,7 @@ class DB {
static const String boxNameWalletsToDeleteOnStart = "walletsToDeleteOnStart";
static const String boxNamePriceCache = "priceAPIPrice24hCache";
static const String boxNameDBInfo = "dbInfo";
static const String boxNameTheme = "theme";
String boxNameTxCache({required Coin coin}) => "${coin.name}_txCache";
String boxNameSetCache({required Coin coin}) =>

View file

@ -29,6 +29,7 @@ import 'package:stackwallet/pages/loading_view.dart';
import 'package:stackwallet/pages/pinpad_views/create_pin_view.dart';
import 'package:stackwallet/pages/pinpad_views/lock_screen_view.dart';
import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/restore_from_encrypted_string_view.dart';
import 'package:stackwallet/pages_desktop_specific/home/desktop_home_view.dart';
import 'package:stackwallet/providers/exchange/available_currencies_state_provider.dart';
import 'package:stackwallet/providers/exchange/available_floating_rate_pairs_state_provider.dart';
import 'package:stackwallet/providers/exchange/change_now_provider.dart';
@ -41,6 +42,7 @@ import 'package:stackwallet/providers/global/base_currencies_provider.dart';
// import 'package:stackwallet/providers/global/has_authenticated_start_state_provider.dart';
import 'package:stackwallet/providers/global/trades_service_provider.dart';
import 'package:stackwallet/providers/providers.dart';
import 'package:stackwallet/providers/ui/color_theme_provider.dart';
import 'package:stackwallet/route_generator.dart';
import 'package:stackwallet/services/debug_service.dart';
import 'package:stackwallet/services/locale_service.dart';
@ -49,13 +51,17 @@ import 'package:stackwallet/services/notifications_api.dart';
import 'package:stackwallet/services/notifications_service.dart';
import 'package:stackwallet/services/trade_service.dart';
import 'package:stackwallet/services/wallets.dart';
import 'package:stackwallet/utilities/cfcolors.dart';
import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/db_version_migration.dart';
import 'package:stackwallet/utilities/enums/backup_frequency_type.dart';
import 'package:stackwallet/utilities/logger.dart';
import 'package:stackwallet/utilities/prefs.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/color_theme.dart';
import 'package:stackwallet/utilities/theme/dark_colors.dart';
import 'package:stackwallet/utilities/theme/light_colors.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/utilities/util.dart';
import 'package:window_size/window_size.dart';
final openedFromSWBFileStringStateProvider =
StateProvider<String?>((ref) => null);
@ -65,6 +71,13 @@ final openedFromSWBFileStringStateProvider =
// miscellaneous box for later use
void main() async {
WidgetsBinding widgetsBinding = WidgetsFlutterBinding.ensureInitialized();
if (Util.isDesktop) {
setWindowTitle('Stack Wallet');
setWindowMinSize(const Size(1200, 900));
setWindowMaxSize(Size.infinite);
}
Directory appDirectory = (await getApplicationDocumentsDirectory());
if (Platform.isIOS) {
appDirectory = (await getLibraryDirectory());
@ -130,6 +143,8 @@ void main() async {
monero.onStartup();
await Hive.openBox<dynamic>(DB.boxNameTheme);
// SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual,
// overlays: [SystemUiOverlay.bottom]);
await NotificationApi.init();
@ -333,6 +348,18 @@ class _MaterialAppWithThemeState extends ConsumerState<MaterialAppWithTheme>
@override
void initState() {
final colorScheme = DB.instance
.get<dynamic>(boxName: DB.boxNameTheme, key: "colorScheme") as String?;
ThemeType themeType;
switch (colorScheme) {
case "dark":
themeType = ThemeType.dark;
break;
case "light":
default:
themeType = ThemeType.light;
}
loadingCompleter = Completer();
WidgetsBinding.instance.addObserver(this);
// load locale and prefs
@ -343,8 +370,12 @@ class _MaterialAppWithThemeState extends ConsumerState<MaterialAppWithTheme>
_prefs = ref.read(prefsChangeNotifierProvider);
_wallets = ref.read(walletsChangeNotifierProvider);
if (Platform.isAndroid) {
WidgetsBinding.instance.addPostFrameCallback((_) async {
WidgetsBinding.instance.addPostFrameCallback((_) async {
ref.read(colorThemeProvider.state).state =
StackColors.fromStackColorTheme(
themeType == ThemeType.dark ? DarkColors() : LightColors());
if (Platform.isAndroid) {
// fetch open file if it exists
await getOpenFile();
@ -358,8 +389,8 @@ class _MaterialAppWithThemeState extends ConsumerState<MaterialAppWithTheme>
ref.read(openedFromSWBFileStringStateProvider.state).state = null;
}
// ref.read(shouldShowLockscreenOnResumeStateProvider.state).state = false;
});
}
}
});
super.initState();
}
@ -491,36 +522,45 @@ class _MaterialAppWithThemeState extends ConsumerState<MaterialAppWithTheme>
// addToDebugMessagesDB: false);
// });
final colorScheme = ref.watch(colorThemeProvider.state).state;
return MaterialApp(
key: GlobalKey(),
navigatorKey: navigatorKey,
title: 'Stack Wallet',
onGenerateRoute: RouteGenerator.generateRoute,
theme: ThemeData(
highlightColor: CFColors.splashLight,
extensions: [colorScheme],
highlightColor: colorScheme.highlight,
brightness: Brightness.light,
fontFamily: GoogleFonts.inter().fontFamily,
textTheme: GoogleFonts.interTextTheme().copyWith(
button: STextStyles.button,
),
unselectedWidgetColor: colorScheme.radioButtonBorderDisabled,
// textTheme: GoogleFonts.interTextTheme().copyWith(
// button: STextStyles.button(context),
// subtitle1: STextStyles.field(context).copyWith(
// color: colorScheme.textDark,
// ),
// ),
radioTheme: const RadioThemeData(
splashRadius: 0,
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
),
// splashFactory: NoSplash.splashFactory,
splashColor: Colors.transparent,
buttonTheme: const ButtonThemeData(
splashColor: CFColors.splashMed,
buttonTheme: ButtonThemeData(
splashColor: colorScheme.splash,
),
textButtonTheme: TextButtonThemeData(
style: ButtonStyle(
// splashFactory: NoSplash.splashFactory,
overlayColor: MaterialStateProperty.all(CFColors.splashMed),
overlayColor: MaterialStateProperty.all(colorScheme.splash),
minimumSize: MaterialStateProperty.all<Size>(const Size(46, 46)),
textStyle: MaterialStateProperty.all<TextStyle>(STextStyles.button),
foregroundColor: MaterialStateProperty.all(CFColors.white),
backgroundColor:
MaterialStateProperty.all<Color>(CFColors.buttonGray),
// textStyle: MaterialStateProperty.all<TextStyle>(
// STextStyles.button(context)),
foregroundColor:
MaterialStateProperty.all(colorScheme.buttonTextSecondary),
backgroundColor: MaterialStateProperty.all<Color>(
colorScheme.buttonBackSecondary),
shape: MaterialStateProperty.all<OutlinedBorder>(
RoundedRectangleBorder(
// 1000 to be relatively sure it keeps its pill shape
@ -529,8 +569,8 @@ class _MaterialAppWithThemeState extends ConsumerState<MaterialAppWithTheme>
),
),
),
primaryColor: CFColors.stackAccent,
primarySwatch: CFColors.createMaterialColor(CFColors.stackAccent),
primaryColor: colorScheme.accentColorDark,
primarySwatch: Util.createMaterialColor(colorScheme.accentColorDark),
checkboxTheme: CheckboxThemeData(
splashRadius: 0,
shape: RoundedRectangleBorder(
@ -540,40 +580,44 @@ class _MaterialAppWithThemeState extends ConsumerState<MaterialAppWithTheme>
checkColor: MaterialStateColor.resolveWith(
(state) {
if (state.contains(MaterialState.selected)) {
return CFColors.white;
return colorScheme.checkboxIconChecked;
}
return CFColors.link2;
return colorScheme.checkboxBGChecked;
},
),
fillColor: MaterialStateColor.resolveWith(
(states) {
if (states.contains(MaterialState.selected)) {
return CFColors.link2;
return colorScheme.checkboxBGChecked;
}
return CFColors.disabledButton;
return colorScheme.checkboxBorderEmpty;
},
),
),
appBarTheme: const AppBarTheme(
appBarTheme: AppBarTheme(
centerTitle: false,
color: CFColors.almostWhite,
color: colorScheme.background,
elevation: 0,
),
inputDecorationTheme: InputDecorationTheme(
focusColor: CFColors.fieldGray,
fillColor: CFColors.fieldGray,
focusColor: colorScheme.textFieldDefaultBG,
fillColor: colorScheme.textFieldDefaultBG,
filled: true,
contentPadding: const EdgeInsets.symmetric(
vertical: 6,
horizontal: 12,
),
labelStyle: STextStyles.fieldLabel,
hintStyle: STextStyles.fieldLabel,
enabledBorder: _buildOutlineInputBorder(CFColors.fieldGray),
focusedBorder: _buildOutlineInputBorder(CFColors.fieldGray),
errorBorder: _buildOutlineInputBorder(CFColors.fieldGray),
disabledBorder: _buildOutlineInputBorder(CFColors.fieldGray),
focusedErrorBorder: _buildOutlineInputBorder(CFColors.fieldGray),
// labelStyle: STextStyles.fieldLabel(context),
// hintStyle: STextStyles.fieldLabel(context),
enabledBorder:
_buildOutlineInputBorder(colorScheme.textFieldDefaultBG),
focusedBorder:
_buildOutlineInputBorder(colorScheme.textFieldDefaultBG),
errorBorder: _buildOutlineInputBorder(colorScheme.textFieldDefaultBG),
disabledBorder:
_buildOutlineInputBorder(colorScheme.textFieldDefaultBG),
focusedErrorBorder:
_buildOutlineInputBorder(colorScheme.textFieldDefaultBG),
),
),
home: FutureBuilder(
@ -595,6 +639,14 @@ class _MaterialAppWithThemeState extends ConsumerState<MaterialAppWithTheme>
ref.read(prefsChangeNotifierProvider).startupWalletId;
}
// TODO proper desktop auth view
if (Util.isDesktop) {
Future<void>.delayed(Duration.zero).then((value) =>
Navigator.of(context).pushNamedAndRemoveUntil(
DesktopHomeView.routeName, (route) => false));
return Container();
}
return LockscreenView(
isInitialAppLogin: true,
routeOnSuccess: HomeView.routeName,

View file

@ -1,9 +1,9 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:stackwallet/models/notification_model.dart';
import 'package:stackwallet/utilities/cfcolors.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/rounded_container.dart';
import 'package:stackwallet/widgets/rounded_white_container.dart';
@ -42,7 +42,9 @@ class NotificationCard extends StatelessWidget {
),
child: SvgPicture.asset(
notification.iconAssetName,
color: CFColors.stackAccent,
color: Theme.of(context)
.extension<StackColors>()!
.accentColorDark,
width: 24,
height: 24,
),
@ -56,7 +58,7 @@ class NotificationCard extends StatelessWidget {
children: [
Text(
notification.title,
style: STextStyles.titleBold12,
style: STextStyles.titleBold12(context),
),
const SizedBox(
height: 2,
@ -66,11 +68,11 @@ class NotificationCard extends StatelessWidget {
children: [
Text(
notification.description,
style: STextStyles.label,
style: STextStyles.label(context),
),
Text(
extractPrettyDateString(notification.date),
style: STextStyles.label,
style: STextStyles.label(context),
),
],
),
@ -83,7 +85,10 @@ class NotificationCard extends StatelessWidget {
if (notification.read)
Positioned.fill(
child: RoundedContainer(
color: CFColors.almostWhite.withOpacity(0.5),
color: Theme.of(context)
.extension<StackColors>()!
.background
.withOpacity(0.5),
),
),
],

View file

@ -2,9 +2,9 @@ import 'package:another_flushbar/flushbar.dart';
import 'package:another_flushbar/flushbar_route.dart' as flushRoute;
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:stackwallet/utilities/cfcolors.dart';
import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/enums/flush_bar_type.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
Future<dynamic> showFloatingFlushBar({
required FlushBarType type,
@ -19,16 +19,16 @@ Future<dynamic> showFloatingFlushBar({
Color fg;
switch (type) {
case FlushBarType.success:
fg = CFColors.notificationGreenForeground;
bg = CFColors.notificationGreenBackground;
fg = Theme.of(context).extension<StackColors>()!.snackBarTextSuccess;
bg = Theme.of(context).extension<StackColors>()!.snackBarBackSuccess;
break;
case FlushBarType.info:
fg = CFColors.notificationBlueForeground;
bg = CFColors.notificationBlueBackground;
fg = Theme.of(context).extension<StackColors>()!.snackBarTextInfo;
bg = Theme.of(context).extension<StackColors>()!.snackBarBackInfo;
break;
case FlushBarType.warning:
fg = CFColors.notificationRedForeground;
bg = CFColors.notificationRedBackground;
fg = Theme.of(context).extension<StackColors>()!.snackBarTextError;
bg = Theme.of(context).extension<StackColors>()!.snackBarBackError;
break;
}
final bar = Flushbar<dynamic>(
@ -53,6 +53,7 @@ Future<dynamic> showFloatingFlushBar({
Constants.size.circularBorderRadius,
),
margin: const EdgeInsets.all(20),
maxWidth: 550,
);
final _route = flushRoute.showFlushbar<dynamic>(

View file

@ -1,85 +1,223 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:stackwallet/pages/add_wallet_views/add_wallet_view/sub_widgets/coin_select_item.dart';
import 'package:flutter_svg/svg.dart';
import 'package:stackwallet/pages/add_wallet_views/add_wallet_view/sub_widgets/add_wallet_text.dart';
import 'package:stackwallet/pages/add_wallet_views/add_wallet_view/sub_widgets/mobile_coin_list.dart';
import 'package:stackwallet/pages/add_wallet_views/add_wallet_view/sub_widgets/next_button.dart';
import 'package:stackwallet/providers/global/prefs_provider.dart';
import 'package:stackwallet/utilities/cfcolors.dart';
import 'package:stackwallet/pages/add_wallet_views/add_wallet_view/sub_widgets/searchable_coin_list.dart';
import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/exit_to_my_stack_button.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/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/utilities/util.dart';
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart';
import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart';
import 'package:stackwallet/widgets/icon_widgets/x_icon.dart';
import 'package:stackwallet/widgets/rounded_white_container.dart';
import 'package:stackwallet/widgets/stack_text_field.dart';
import 'package:stackwallet/widgets/textfield_icon_button.dart';
class AddWalletView extends StatelessWidget {
class AddWalletView extends StatefulWidget {
const AddWalletView({Key? key}) : super(key: key);
static const routeName = "/addWallet";
@override
Widget build(BuildContext context) {
List<Coin> coins = [...Coin.values];
coins.remove(Coin.firoTestNet);
return Scaffold(
appBar: AppBar(
leading: AppBarBackButton(
onPressed: () {
Navigator.of(context).pop();
},
),
),
body: Container(
color: CFColors.almostWhite,
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text(
"Add wallet",
textAlign: TextAlign.center,
style: STextStyles.pageTitleH1,
),
const SizedBox(
height: 16,
),
Text(
"Select wallet currency",
textAlign: TextAlign.center,
style: STextStyles.subtitle,
),
const SizedBox(
height: 16,
),
Expanded(
child: Consumer(
builder: (_, ref, __) {
bool showTestNet = ref.watch(
prefsChangeNotifierProvider
.select((value) => value.showTestNetCoins),
);
State<AddWalletView> createState() => _AddWalletViewState();
}
return ListView.builder(
itemCount: showTestNet
? coins.length
: coins.length - (kTestNetCoinCount),
itemBuilder: (ctx, index) {
return Padding(
padding: const EdgeInsets.all(4),
child: CoinSelectItem(
coin: coins[index],
class _AddWalletViewState extends State<AddWalletView> {
late final TextEditingController _searchFieldController;
late final FocusNode _searchFocusNode;
String _searchTerm = "";
final List<Coin> coins = [...Coin.values];
@override
void initState() {
_searchFieldController = TextEditingController();
_searchFocusNode = FocusNode();
coins.remove(Coin.firoTestNet);
super.initState();
}
@override
void dispose() {
_searchFieldController.dispose();
_searchFocusNode.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
debugPrint("BUILD: $runtimeType");
if (Util.isDesktop) {
return DesktopScaffold(
appBar: const DesktopAppBar(
isCompactHeight: false,
leading: AppBarBackButton(),
trailing: ExitToMyStackButton(),
),
body: Column(
children: [
const AddWalletText(
isDesktop: true,
),
const SizedBox(
height: 16,
),
Expanded(
child: SizedBox(
width: 480,
child: RoundedWhiteContainer(
radiusMultiplier: 2,
padding: const EdgeInsets.only(
left: 16,
top: 16,
right: 16,
bottom: 0,
),
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(4.0),
child: ClipRRect(
borderRadius: BorderRadius.circular(
Constants.size.circularBorderRadius,
),
);
},
);
},
child: TextField(
controller: _searchFieldController,
focusNode: _searchFocusNode,
onChanged: (value) {
setState(() {
_searchTerm = value;
});
},
style:
STextStyles.desktopTextMedium(context).copyWith(
height: 2,
),
decoration: standardInputDecoration(
"Search",
_searchFocusNode,
context,
).copyWith(
contentPadding: const EdgeInsets.symmetric(
vertical: 10,
),
prefixIcon: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 16,
// vertical: 20,
),
child: SvgPicture.asset(
Assets.svg.search,
width: 24,
height: 24,
color: Theme.of(context)
.extension<StackColors>()!
.textFieldDefaultSearchIconLeft,
),
),
suffixIcon: _searchFieldController.text.isNotEmpty
? Padding(
padding: const EdgeInsets.only(right: 10),
child: UnconstrainedBox(
child: Row(
children: [
TextFieldIconButton(
child: const XIcon(
width: 24,
height: 24,
),
onTap: () async {
setState(() {
_searchFieldController.text =
"";
_searchTerm = "";
});
},
),
],
),
),
)
: null,
),
),
),
),
Expanded(
child: SearchableCoinList(
coins: coins,
isDesktop: true,
searchTerm: _searchTerm,
),
),
],
),
),
),
const SizedBox(
height: 16,
),
const SizedBox(
height: 16,
),
const SizedBox(
height: 70,
width: 480,
child: AddWalletNextButton(
isDesktop: true,
),
const AddWalletNextButton(),
],
),
const SizedBox(
height: 32,
),
],
),
);
} else {
return Scaffold(
appBar: AppBar(
leading: AppBarBackButton(
onPressed: () {
Navigator.of(context).pop();
},
),
),
),
);
body: Container(
color: Theme.of(context).extension<StackColors>()!.background,
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const AddWalletText(
isDesktop: false,
),
const SizedBox(
height: 16,
),
Expanded(
child: MobileCoinList(
coins: coins,
isDesktop: false,
),
),
const SizedBox(
height: 16,
),
const AddWalletNextButton(
isDesktop: false,
),
],
),
),
),
);
}
}
}

View file

@ -0,0 +1,34 @@
import 'package:flutter/material.dart';
import 'package:stackwallet/utilities/text_styles.dart';
class AddWalletText extends StatelessWidget {
const AddWalletText({Key? key, required this.isDesktop}) : super(key: key);
final bool isDesktop;
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text(
"Add wallet",
textAlign: TextAlign.center,
style: isDesktop
? STextStyles.desktopH2(context)
: STextStyles.pageTitleH1(context),
),
const SizedBox(
height: 16,
),
Text(
"Select wallet currency",
textAlign: TextAlign.center,
style: isDesktop
? STextStyles.desktopSubtitleH2(context)
: STextStyles.subtitle(context),
),
],
);
}
}

View file

@ -3,10 +3,11 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/svg.dart';
import 'package:stackwallet/providers/providers.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/cfcolors.dart';
import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/utilities/util.dart';
class CoinSelectItem extends ConsumerWidget {
const CoinSelectItem({
@ -20,40 +21,71 @@ class CoinSelectItem extends ConsumerWidget {
Widget build(BuildContext context, WidgetRef ref) {
debugPrint("BUILD: CoinSelectItem for ${coin.name}");
final selectedCoin = ref.watch(addWalletSelectedCoinStateProvider);
final isDesktop = Util.isDesktop;
return Container(
decoration: BoxDecoration(
// color: selectedCoin == coin ? CFColors.selection : CFColors.white,
color: selectedCoin == coin ? CFColors.selected2 : CFColors.white,
color: selectedCoin == coin
? Theme.of(context).extension<StackColors>()!.textFieldActiveBG
: Theme.of(context).extension<StackColors>()!.popupBG,
borderRadius:
BorderRadius.circular(Constants.size.circularBorderRadius),
),
child: MaterialButton(
// splashColor: CFColors.splashLight,
// splashColor: Theme.of(context).extension<StackColors>()!.highlight,
key: Key("coinSelectItemButtonKey_${coin.name}"),
padding: const EdgeInsets.all(12),
padding: isDesktop
? const EdgeInsets.only(left: 24)
: const EdgeInsets.all(12),
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(Constants.size.circularBorderRadius),
),
child: Row(
children: [
SvgPicture.asset(
Assets.svg.iconFor(coin: coin),
width: 26,
height: 26,
),
const SizedBox(
width: 10,
),
Text(
coin.prettyName,
style: STextStyles.subtitle.copyWith(
fontWeight: FontWeight.w600,
fontSize: 14,
child: ConstrainedBox(
constraints: BoxConstraints(
minHeight: isDesktop ? 70 : 0,
),
child: Row(
children: [
SvgPicture.asset(
Assets.svg.iconFor(coin: coin),
width: 26,
height: 26,
),
),
],
SizedBox(
width: isDesktop ? 12 : 10,
),
Text(
coin.prettyName,
style: isDesktop
? STextStyles.desktopTextMedium(context)
: STextStyles.subtitle(context).copyWith(
fontWeight: FontWeight.w600,
fontSize: 14,
),
),
if (isDesktop && selectedCoin == coin) const Spacer(),
if (isDesktop && selectedCoin == coin)
Padding(
padding: const EdgeInsets.only(
right: 18,
),
child: SizedBox(
width: 24,
height: 24,
child: SvgPicture.asset(
Assets.svg.check,
color: Theme.of(context)
.extension<StackColors>()!
.accentColorDark,
),
),
),
],
),
),
onPressed: () =>
ref.read(addWalletSelectedCoinStateProvider.state).state = coin,

View file

@ -0,0 +1,40 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:stackwallet/pages/add_wallet_views/add_wallet_view/sub_widgets/coin_select_item.dart';
import 'package:stackwallet/providers/global/prefs_provider.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
class MobileCoinList extends StatelessWidget {
const MobileCoinList({
Key? key,
required this.coins,
required this.isDesktop,
}) : super(key: key);
final List<Coin> coins;
final bool isDesktop;
@override
Widget build(BuildContext context) {
return Consumer(
builder: (_, ref, __) {
bool showTestNet = ref.watch(
prefsChangeNotifierProvider.select((value) => value.showTestNetCoins),
);
return ListView.builder(
itemCount:
showTestNet ? coins.length : coins.length - (kTestNetCoinCount),
itemBuilder: (ctx, index) {
return Padding(
padding: const EdgeInsets.all(4),
child: CoinSelectItem(
coin: coins[index],
),
);
},
);
},
);
}
}

View file

@ -2,19 +2,27 @@ import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:stackwallet/pages/add_wallet_views/create_or_restore_wallet_view/create_or_restore_wallet_view.dart';
import 'package:stackwallet/providers/providers.dart';
import 'package:stackwallet/utilities/cfcolors.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
class AddWalletNextButton extends ConsumerWidget {
const AddWalletNextButton({Key? key}) : super(key: key);
const AddWalletNextButton({
Key? key,
required this.isDesktop,
}) : super(key: key);
final bool isDesktop;
@override
Widget build(BuildContext context, WidgetRef ref) {
debugPrint("BUILD: NextButton");
final selectedCoin =
ref.watch(addWalletSelectedCoinStateProvider.state).state;
final enabled = selectedCoin != null;
return TextButton(
onPressed: selectedCoin == null
onPressed: !enabled
? null
: () {
final selectedCoin =
@ -25,22 +33,20 @@ class AddWalletNextButton extends ConsumerWidget {
arguments: selectedCoin,
);
},
style: selectedCoin == null
? Theme.of(context).textButtonTheme.style?.copyWith(
backgroundColor: MaterialStateProperty.all<Color>(
CFColors.stackAccent.withOpacity(
0.25,
),
),
)
: Theme.of(context).textButtonTheme.style?.copyWith(
backgroundColor: MaterialStateProperty.all<Color>(
CFColors.stackAccent,
),
),
style: enabled
? Theme.of(context)
.extension<StackColors>()!
.getPrimaryEnabledButtonColor(context)
: Theme.of(context)
.extension<StackColors>()!
.getPrimaryDisabledButtonColor(context),
child: Text(
"Next",
style: STextStyles.button,
style: isDesktop
? enabled
? STextStyles.desktopButtonEnabled(context)
: STextStyles.desktopButtonDisabled(context)
: STextStyles.button(context),
),
);
}

View file

@ -0,0 +1,57 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:stackwallet/pages/add_wallet_views/add_wallet_view/sub_widgets/coin_select_item.dart';
import 'package:stackwallet/providers/global/prefs_provider.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
class SearchableCoinList extends ConsumerWidget {
const SearchableCoinList({
Key? key,
required this.coins,
required this.isDesktop,
required this.searchTerm,
}) : super(key: key);
final List<Coin> coins;
final bool isDesktop;
final String searchTerm;
List<Coin> filterCoins(String text, bool showTestNetCoins) {
final _coins = [...coins];
if (text.isNotEmpty) {
final lowercaseTerm = text.toLowerCase();
_coins.retainWhere((e) =>
e.ticker.toLowerCase().contains(lowercaseTerm) ||
e.prettyName.toLowerCase().contains(lowercaseTerm) ||
e.name.toLowerCase().contains(lowercaseTerm));
}
if (!showTestNetCoins) {
_coins.removeWhere((e) => e.name.endsWith("TestNet"));
}
// remove firo testnet regardless
_coins.remove(Coin.firoTestNet);
return _coins;
}
@override
Widget build(BuildContext context, WidgetRef ref) {
bool showTestNet = ref.watch(
prefsChangeNotifierProvider.select((value) => value.showTestNetCoins),
);
final _coins = filterCoins(searchTerm, showTestNet);
return ListView.builder(
itemCount: _coins.length,
itemBuilder: (ctx, index) {
return Padding(
padding: const EdgeInsets.all(4),
child: CoinSelectItem(
coin: _coins[index],
),
);
},
);
}
}

View file

@ -1,12 +1,15 @@
import 'package:flutter/material.dart';
import 'package:stackwallet/pages/add_wallet_views/name_your_wallet_view/name_your_wallet_view.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/cfcolors.dart';
import 'package:stackwallet/utilities/enums/add_wallet_type_enum.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/create_or_restore_wallet_view/sub_widgets/create_or_restore_wallet_subtitle.dart';
import 'package:stackwallet/pages/add_wallet_views/create_or_restore_wallet_view/sub_widgets/create_or_restore_wallet_title.dart';
import 'package:stackwallet/pages/add_wallet_views/create_or_restore_wallet_view/sub_widgets/create_wallet_button_group.dart';
import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/exit_to_my_stack_button.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/utilities/util.dart';
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
import 'package:tuple/tuple.dart';
import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart';
import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart';
class CreateOrRestoreWalletView extends StatelessWidget {
const CreateOrRestoreWalletView({
@ -22,97 +25,100 @@ class CreateOrRestoreWalletView extends StatelessWidget {
Widget build(BuildContext context) {
debugPrint("BUILD: $runtimeType");
return Scaffold(
appBar: AppBar(
leading: AppBarBackButton(
onPressed: () {
Navigator.of(context).pop();
},
final isDesktop = Util.isDesktop;
if (isDesktop) {
return DesktopScaffold(
appBar: const DesktopAppBar(
isCompactHeight: false,
leading: AppBarBackButton(),
trailing: ExitToMyStackButton(),
),
),
body: Container(
color: CFColors.almostWhite,
child: Padding(
padding: const EdgeInsets.all(16),
body: SizedBox(
width: 480,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.all(31),
child: Image(
image: AssetImage(
Assets.png.imageFor(coin: coin),
),
width: MediaQuery.of(context).size.width / 3,
),
),
const Spacer(
flex: 2,
),
Text(
"Add ${coin.prettyName} wallet",
textAlign: TextAlign.center,
style: STextStyles.pageTitleH1,
CreateRestoreWalletTitle(
coin: coin,
isDesktop: isDesktop,
),
const SizedBox(
height: 8,
height: 16,
),
Text(
"Create a new wallet or restore an existing wallet from seed.",
textAlign: TextAlign.center,
style: STextStyles.subtitle),
const Spacer(
flex: 5,
),
TextButton(
style: Theme.of(context).textButtonTheme.style?.copyWith(
backgroundColor: MaterialStateProperty.all<Color>(
CFColors.stackAccent,
),
),
onPressed: () {
Navigator.of(context).pushNamed(
NameYourWalletView.routeName,
arguments: Tuple2(
AddWalletType.New,
coin,
),
);
},
child: Text(
"Create new wallet",
style: STextStyles.button,
SizedBox(
width: 324,
child: CreateRestoreWalletSubTitle(
isDesktop: isDesktop,
),
),
const SizedBox(
height: 12,
height: 32,
),
TextButton(
style: Theme.of(context).textButtonTheme.style?.copyWith(
backgroundColor: MaterialStateProperty.all<Color>(
CFColors.stackAccent.withOpacity(0.25),
),
),
onPressed: () {
Navigator.of(context).pushNamed(
NameYourWalletView.routeName,
arguments: Tuple2(
AddWalletType.Restore,
coin,
),
);
},
child: Text(
"Restore wallet",
style: STextStyles.button.copyWith(
color: CFColors.stackAccent,
),
),
CoinImage(
coin: coin,
isDesktop: isDesktop,
),
const SizedBox(
height: 32,
),
CreateWalletButtonGroup(
coin: coin,
isDesktop: isDesktop,
),
],
),
),
),
);
);
} else {
return Scaffold(
appBar: AppBar(
leading: AppBarBackButton(
onPressed: () {
Navigator.of(context).pop();
},
),
),
body: Container(
color: Theme.of(context).extension<StackColors>()!.background,
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Padding(
padding: const EdgeInsets.all(31),
child: CoinImage(
coin: coin,
isDesktop: isDesktop,
),
),
const Spacer(
flex: 2,
),
CreateRestoreWalletTitle(
coin: coin,
isDesktop: isDesktop,
),
const SizedBox(
height: 8,
),
CreateRestoreWalletSubTitle(
isDesktop: isDesktop,
),
const Spacer(
flex: 5,
),
CreateWalletButtonGroup(
coin: coin,
isDesktop: isDesktop,
),
],
),
),
),
);
}
}
}

View file

@ -0,0 +1,24 @@
import 'package:flutter/material.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
class CoinImage extends StatelessWidget {
const CoinImage({
Key? key,
required this.coin,
required this.isDesktop,
}) : super(key: key);
final Coin coin;
final bool isDesktop;
@override
Widget build(BuildContext context) {
return Image(
image: AssetImage(
Assets.png.imageFor(coin: coin),
),
width: isDesktop ? 324 : MediaQuery.of(context).size.width / 3,
);
}
}

View file

@ -0,0 +1,22 @@
import 'package:flutter/material.dart';
import 'package:stackwallet/utilities/text_styles.dart';
class CreateRestoreWalletSubTitle extends StatelessWidget {
const CreateRestoreWalletSubTitle({
Key? key,
required this.isDesktop,
}) : super(key: key);
final bool isDesktop;
@override
Widget build(BuildContext context) {
return Text(
"Create a new wallet or restore an existing wallet from seed.",
textAlign: TextAlign.center,
style: isDesktop
? STextStyles.desktopSubtitleH2(context)
: STextStyles.subtitle(context),
);
}
}

View file

@ -0,0 +1,25 @@
import 'package:flutter/material.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
import 'package:stackwallet/utilities/text_styles.dart';
class CreateRestoreWalletTitle extends StatelessWidget {
const CreateRestoreWalletTitle({
Key? key,
required this.coin,
required this.isDesktop,
}) : super(key: key);
final Coin coin;
final bool isDesktop;
@override
Widget build(BuildContext context) {
return Text(
"Add ${coin.prettyName} wallet",
textAlign: TextAlign.center,
style: isDesktop
? STextStyles.desktopH2(context)
: STextStyles.pageTitleH1(context),
);
}
}

View file

@ -0,0 +1,86 @@
import 'package:flutter/material.dart';
import 'package:stackwallet/pages/add_wallet_views/name_your_wallet_view/name_your_wallet_view.dart';
import 'package:stackwallet/utilities/enums/add_wallet_type_enum.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:tuple/tuple.dart';
class CreateWalletButtonGroup extends StatelessWidget {
const CreateWalletButtonGroup({
Key? key,
required this.coin,
required this.isDesktop,
}) : super(key: key);
final Coin coin;
final bool isDesktop;
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment:
isDesktop ? CrossAxisAlignment.center : CrossAxisAlignment.stretch,
children: [
ConstrainedBox(
constraints: BoxConstraints(
minHeight: isDesktop ? 70 : 0,
minWidth: isDesktop ? 480 : 0,
),
child: TextButton(
style: Theme.of(context)
.extension<StackColors>()!
.getPrimaryEnabledButtonColor(context),
onPressed: () {
Navigator.of(context).pushNamed(
NameYourWalletView.routeName,
arguments: Tuple2(
AddWalletType.New,
coin,
),
);
},
child: Text(
"Create new wallet",
style: isDesktop
? STextStyles.desktopButtonEnabled(context)
: STextStyles.button(context),
),
),
),
SizedBox(
height: isDesktop ? 16 : 12,
),
ConstrainedBox(
constraints: BoxConstraints(
minHeight: isDesktop ? 70 : 0,
minWidth: isDesktop ? 480 : 0,
),
child: TextButton(
style: Theme.of(context)
.extension<StackColors>()!
.getSecondaryEnabledButtonColor(context),
onPressed: () {
Navigator.of(context).pushNamed(
NameYourWalletView.routeName,
arguments: Tuple2(
AddWalletType.Restore,
coin,
),
);
},
child: Text(
"Restore wallet",
style: isDesktop
? STextStyles.desktopButtonSecondaryEnabled(context)
: STextStyles.button(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.accentColorDark),
),
),
),
],
);
}
}

View file

@ -1,19 +1,25 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:stackwallet/notifications/show_flush_bar.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.dart';
import 'package:stackwallet/pages/add_wallet_views/restore_wallet_view/restore_options_view/restore_options_view.dart';
import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/exit_to_my_stack_button.dart';
import 'package:stackwallet/providers/global/wallets_service_provider.dart';
import 'package:stackwallet/providers/ui/verify_recovery_phrase/mnemonic_word_count_state_provider.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/cfcolors.dart';
import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/enums/add_wallet_type_enum.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
import 'package:stackwallet/utilities/enums/flush_bar_type.dart';
import 'package:stackwallet/utilities/name_generator.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/utilities/util.dart';
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart';
import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart';
import 'package:stackwallet/widgets/icon_widgets/dice_icon.dart';
import 'package:stackwallet/widgets/icon_widgets/x_icon.dart';
import 'package:stackwallet/widgets/rounded_white_container.dart';
@ -21,14 +27,6 @@ import 'package:stackwallet/widgets/stack_text_field.dart';
import 'package:stackwallet/widgets/textfield_icon_button.dart';
import 'package:tuple/tuple.dart';
// TODO replace with real list and move out of this file
const kWalletNameWordList = [
"Bubby",
"Baby",
"Bobby",
"Booby",
];
class NameYourWalletView extends ConsumerStatefulWidget {
const NameYourWalletView({
Key? key,
@ -59,6 +57,8 @@ class _NameYourWalletViewState extends ConsumerState<NameYourWalletView> {
Set<String> namesToExclude = {};
late final NameGenerator generator;
late final bool isDesktop;
Future<String> _generateRandomWalletName() async {
final name = generator.generate(namesToExclude: namesToExclude);
namesToExclude.add(name);
@ -67,6 +67,8 @@ class _NameYourWalletViewState extends ConsumerState<NameYourWalletView> {
@override
void initState() {
isDesktop = Util.isDesktop;
ref.read(walletsServiceChangeNotifierProvider).walletNames.then(
(value) => namesToExclude.addAll(
value.values.map((e) => e.name),
@ -92,231 +94,270 @@ class _NameYourWalletViewState extends ConsumerState<NameYourWalletView> {
Widget build(BuildContext context) {
debugPrint(
"BUILD: NameYourWalletView with ${coin.name} ${addWalletType.name}");
return Scaffold(
appBar: AppBar(
leading: AppBarBackButton(
onPressed: () {
if (textFieldFocusNode.hasFocus) {
textFieldFocusNode.unfocus();
Future<void>.delayed(const Duration(milliseconds: 100))
.then((value) => Navigator.of(context).pop());
} else {
if (mounted) {
Navigator.of(context).pop();
}
}
},
if (isDesktop) {
return DesktopScaffold(
appBar: const DesktopAppBar(
leading: AppBarBackButton(),
trailing: ExitToMyStackButton(),
isCompactHeight: false,
),
),
body: Container(
color: CFColors.almostWhite,
child: Padding(
padding: const EdgeInsets.all(16),
child: LayoutBuilder(
builder: (ctx, constraints) {
return SingleChildScrollView(
child: ConstrainedBox(
constraints: BoxConstraints(minHeight: constraints.maxHeight),
child: IntrinsicHeight(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
body: SizedBox(
width: 480,
child: _content(),
),
);
} else {
return Scaffold(
appBar: AppBar(
leading: AppBarBackButton(
onPressed: () {
if (textFieldFocusNode.hasFocus) {
textFieldFocusNode.unfocus();
Future<void>.delayed(const Duration(milliseconds: 100))
.then((value) => Navigator.of(context).pop());
} else {
if (mounted) {
Navigator.of(context).pop();
}
}
},
),
),
body: Container(
color: Theme.of(context).extension<StackColors>()!.background,
child: Padding(
padding: const EdgeInsets.all(16),
child: LayoutBuilder(
builder: (ctx, constraints) {
return SingleChildScrollView(
child: ConstrainedBox(
constraints:
BoxConstraints(minHeight: constraints.maxHeight),
child: IntrinsicHeight(
child: _content(),
),
),
);
},
),
),
),
);
}
}
Widget _content() => Column(
crossAxisAlignment:
isDesktop ? CrossAxisAlignment.center : CrossAxisAlignment.stretch,
children: [
if (!isDesktop)
const Spacer(
flex: 1,
),
if (!isDesktop)
Image(
image: AssetImage(
Assets.png.imageFor(coin: coin),
),
height: 100,
),
SizedBox(
height: isDesktop ? 24 : 16,
),
Text(
"Name your ${coin.prettyName} wallet",
textAlign: TextAlign.center,
style: isDesktop
? STextStyles.desktopH2(context)
: STextStyles.pageTitleH1(context),
),
SizedBox(
height: isDesktop ? 16 : 8,
),
Text(
"Enter a label for your wallet (e.g. Savings)",
textAlign: TextAlign.center,
style: isDesktop
? STextStyles.desktopSubtitleH2(context)
: STextStyles.subtitle(context),
),
SizedBox(
height: isDesktop ? 40 : 16,
),
ClipRRect(
borderRadius: BorderRadius.circular(
Constants.size.circularBorderRadius,
),
child: TextField(
onChanged: (string) {
if (string.isEmpty) {
if (_nextEnabled) {
setState(() {
_nextEnabled = false;
_showDiceIcon = true;
});
}
} else {
if (!_nextEnabled) {
setState(() {
_nextEnabled = true;
_showDiceIcon = false;
});
}
}
},
focusNode: textFieldFocusNode,
controller: textEditingController,
style: isDesktop
? STextStyles.desktopTextMedium(context).copyWith(
height: 2,
)
: STextStyles.field(context),
decoration: standardInputDecoration(
"Enter wallet name",
textFieldFocusNode,
context,
).copyWith(
suffixIcon: Padding(
padding: EdgeInsets.only(right: isDesktop ? 6 : 0),
child: UnconstrainedBox(
child: Row(
children: [
const Spacer(
flex: 1,
),
Image(
image: AssetImage(
Assets.png.imageFor(coin: coin),
),
height: 100,
),
const SizedBox(
height: 16,
),
Text(
"Name your ${coin.prettyName} wallet",
textAlign: TextAlign.center,
style: STextStyles.pageTitleH1,
),
const SizedBox(
height: 8,
),
Text(
"Enter a label for your wallet (e.g. Savings)",
textAlign: TextAlign.center,
style: STextStyles.subtitle,
),
const SizedBox(
height: 16,
),
ClipRRect(
borderRadius: BorderRadius.circular(
Constants.size.circularBorderRadius,
),
child: TextField(
onChanged: (string) {
if (string.isEmpty) {
if (_nextEnabled) {
setState(() {
_nextEnabled = false;
_showDiceIcon = true;
});
}
} else {
if (!_nextEnabled) {
setState(() {
_nextEnabled = true;
_showDiceIcon = false;
});
}
}
},
focusNode: textFieldFocusNode,
controller: textEditingController,
style: STextStyles.field,
decoration: standardInputDecoration(
"Enter wallet name",
textFieldFocusNode,
).copyWith(
suffixIcon: Padding(
padding: const EdgeInsets.only(right: 0),
child: UnconstrainedBox(
child: Row(
children: [
TextFieldIconButton(
key: const Key(
"genRandomWalletNameButtonKey"),
child: _showDiceIcon
? const DiceIcon()
: const XIcon(),
onTap: () async {
if (_showDiceIcon) {
textEditingController.text =
await _generateRandomWalletName();
setState(() {
_nextEnabled = true;
_showDiceIcon = false;
});
} else {
textEditingController.text = "";
setState(() {
_nextEnabled = false;
_showDiceIcon = true;
});
}
},
)
],
),
TextFieldIconButton(
key: const Key("genRandomWalletNameButtonKey"),
child: _showDiceIcon
? DiceIcon(
width: isDesktop ? 20 : 17,
height: isDesktop ? 20 : 17,
)
: XIcon(
width: isDesktop ? 21 : 18,
height: isDesktop ? 21 : 18,
),
),
),
),
),
const SizedBox(
height: 8,
),
RoundedWhiteContainer(
child: Center(
child: Text(
"Roll the dice to pick a random name.",
style: STextStyles.itemSubtitle,
),
),
),
const Spacer(
flex: 4,
),
TextButton(
onPressed: _nextEnabled
? () async {
final walletsService = ref.read(
walletsServiceChangeNotifierProvider);
final name = textEditingController.text;
if (await walletsService
.checkForDuplicate(name)) {
showFloatingFlushBar(
type: FlushBarType.warning,
message: "Wallet name already in use.",
iconAsset: Assets.svg.circleAlert,
context: context,
);
} else {
// hide keyboard if has focus
if (FocusScope.of(context).hasFocus) {
FocusScope.of(context).unfocus();
await Future<void>.delayed(
const Duration(milliseconds: 50));
}
if (mounted) {
switch (widget.addWalletType) {
case AddWalletType.New:
Navigator.of(context).pushNamed(
NewWalletRecoveryPhraseWarningView
.routeName,
arguments: Tuple2(
name,
coin,
),
);
break;
case AddWalletType.Restore:
ref
.read(
mnemonicWordCountStateProvider
.state)
.state = Constants
.possibleLengthsForCoin(coin)
.first;
Navigator.of(context).pushNamed(
RestoreOptionsView.routeName,
arguments: Tuple2(
name,
coin,
),
);
break;
}
}
}
}
: null,
style: _nextEnabled
? Theme.of(context)
.textButtonTheme
.style
?.copyWith(
backgroundColor:
MaterialStateProperty.all<Color>(
CFColors.stackAccent,
))
: Theme.of(context)
.textButtonTheme
.style
?.copyWith(
backgroundColor:
MaterialStateProperty.all<Color>(
CFColors.stackAccent.withOpacity(
0.25,
),
),
),
child: Text(
"Next",
style: STextStyles.button,
),
),
onTap: () async {
if (_showDiceIcon) {
textEditingController.text =
await _generateRandomWalletName();
setState(() {
_nextEnabled = true;
_showDiceIcon = false;
});
} else {
textEditingController.text = "";
setState(() {
_nextEnabled = false;
_showDiceIcon = true;
});
}
},
)
],
),
),
),
);
},
),
),
),
),
),
);
}
SizedBox(
height: isDesktop ? 16 : 8,
),
RoundedWhiteContainer(
child: Center(
child: Text(
"Roll the dice to pick a random name.",
style: isDesktop
? STextStyles.desktopTextExtraSmall(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textSubtitle1,
)
: STextStyles.itemSubtitle(context),
),
),
),
if (!isDesktop)
const Spacer(
flex: 4,
),
if (isDesktop)
const SizedBox(
height: 32,
),
ConstrainedBox(
constraints: BoxConstraints(
minWidth: isDesktop ? 480 : 0,
minHeight: isDesktop ? 70 : 0,
),
child: TextButton(
onPressed: _nextEnabled
? () async {
final walletsService =
ref.read(walletsServiceChangeNotifierProvider);
final name = textEditingController.text;
if (await walletsService.checkForDuplicate(name)) {
unawaited(showFloatingFlushBar(
type: FlushBarType.warning,
message: "Wallet name already in use.",
iconAsset: Assets.svg.circleAlert,
context: context,
));
} else {
// hide keyboard if has focus
if (FocusScope.of(context).hasFocus) {
FocusScope.of(context).unfocus();
await Future<void>.delayed(
const Duration(milliseconds: 50));
}
if (mounted) {
switch (widget.addWalletType) {
case AddWalletType.New:
unawaited(Navigator.of(context).pushNamed(
NewWalletRecoveryPhraseWarningView.routeName,
arguments: Tuple2(
name,
coin,
),
));
break;
case AddWalletType.Restore:
ref
.read(mnemonicWordCountStateProvider.state)
.state = Constants.possibleLengthsForCoin(
coin)
.first;
unawaited(Navigator.of(context).pushNamed(
RestoreOptionsView.routeName,
arguments: Tuple2(
name,
coin,
),
));
break;
}
}
}
}
: null,
style: _nextEnabled
? Theme.of(context)
.extension<StackColors>()!
.getPrimaryEnabledButtonColor(context)
: Theme.of(context)
.extension<StackColors>()!
.getPrimaryDisabledButtonColor(context),
child: Text(
"Next",
style: isDesktop
? _nextEnabled
? STextStyles.desktopButtonEnabled(context)
: STextStyles.desktopButtonDisabled(context)
: STextStyles.button(context),
),
),
),
],
);
}

View file

@ -1,3 +1,4 @@
import 'dart:async';
import 'dart:math';
import 'package:flutter/material.dart';
@ -8,15 +9,20 @@ import 'package:stackwallet/notifications/show_flush_bar.dart';
import 'package:stackwallet/pages/add_wallet_views/new_wallet_recovery_phrase_view/sub_widgets/mnemonic_table.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/verify_recovery_phrase_view/verify_recovery_phrase_view.dart';
import 'package:stackwallet/pages_desktop_specific/home/desktop_home_view.dart';
import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/exit_to_my_stack_button.dart';
import 'package:stackwallet/providers/providers.dart';
import 'package:stackwallet/services/coins/manager.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/cfcolors.dart';
import 'package:stackwallet/utilities/clipboard_interface.dart';
import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/enums/flush_bar_type.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/utilities/util.dart';
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart';
import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart';
import 'package:tuple/tuple.dart';
class NewWalletRecoveryPhraseView extends ConsumerStatefulWidget {
@ -46,12 +52,14 @@ class _NewWalletRecoveryPhraseViewState
late Manager _manager;
late List<String> _mnemonic;
late ClipboardInterface _clipboardInterface;
late final bool isDesktop;
@override
void initState() {
_manager = widget.manager;
_mnemonic = widget.mnemonic;
_clipboardInterface = widget.clipboardInterface;
isDesktop = Util.isDesktop;
super.initState();
}
@ -67,144 +75,239 @@ class _NewWalletRecoveryPhraseViewState
await _manager.exitCurrentWallet();
}
Future<void> _copy() async {
final words = await _manager.mnemonic;
await _clipboardInterface.setData(ClipboardData(text: words.join(" ")));
unawaited(showFloatingFlushBar(
type: FlushBarType.info,
message: "Copied to clipboard",
iconAsset: Assets.svg.copy,
context: context,
));
}
@override
Widget build(BuildContext context) {
debugPrint("BUILD: $runtimeType");
return WillPopScope(
onWillPop: onWillPop,
child: Scaffold(
appBar: AppBar(
leading: AppBarBackButton(
onPressed: () async {
await delete();
onWillPop: onWillPop,
child: MasterScaffold(
isDesktop: isDesktop,
appBar: isDesktop
? DesktopAppBar(
isCompactHeight: false,
leading: AppBarBackButton(
onPressed: () async {
await delete();
if (mounted) {
Navigator.of(context).popUntil(
ModalRoute.withName(
NewWalletRecoveryPhraseWarningView.routeName,
if (mounted) {
Navigator.of(context).popUntil(
ModalRoute.withName(
NewWalletRecoveryPhraseWarningView.routeName,
),
);
}
// Navigator.of(context).pop();
},
),
);
}
// Navigator.of(context).pop();
},
),
actions: [
Padding(
padding: const EdgeInsets.all(10),
child: AspectRatio(
aspectRatio: 1,
child: AppBarIconButton(
color: CFColors.almostWhite,
shadows: const [],
icon: SvgPicture.asset(
Assets.svg.copy,
width: 24,
height: 24,
trailing: ExitToMyStackButton(
onPressed: () async {
await delete();
if (mounted) {
Navigator.of(context).popUntil(
ModalRoute.withName(DesktopHomeView.routeName),
);
}
},
),
onPressed: () async {
final words = await _manager.mnemonic;
await _clipboardInterface
.setData(ClipboardData(text: words.join(" ")));
showFloatingFlushBar(
type: FlushBarType.info,
message: "Copied to clipboard",
iconAsset: Assets.svg.copy,
context: context,
);
},
),
),
),
],
),
body: Container(
color: CFColors.almostWhite,
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const SizedBox(
height: 4,
),
Text(
_manager.walletName,
textAlign: TextAlign.center,
style: STextStyles.label.copyWith(
fontSize: 12,
),
),
const SizedBox(
height: 4,
),
Text(
"Recovery Phrase",
textAlign: TextAlign.center,
style: STextStyles.pageTitleH1,
),
const SizedBox(
height: 16,
),
Container(
decoration: BoxDecoration(
color: CFColors.white,
borderRadius: BorderRadius.circular(
Constants.size.circularBorderRadius),
),
child: Padding(
padding: const EdgeInsets.all(12),
child: Text(
"Please write down your recovery phrase in the correct order and save it to keep your funds secure. You will also be asked to verify the words on the next screen.",
style: STextStyles.label.copyWith(
color: CFColors.stackAccent,
),
),
),
),
const SizedBox(
height: 8,
),
Expanded(
child: SingleChildScrollView(
child: MnemonicTable(
words: _mnemonic,
),
),
),
const SizedBox(
height: 16,
),
TextButton(
onPressed: () async {
final int next = Random().nextInt(_mnemonic.length);
ref
.read(verifyMnemonicWordIndexStateProvider.state)
.update((state) => next);
)
: AppBar(
leading: AppBarBackButton(
onPressed: () async {
await delete();
ref
.read(verifyMnemonicCorrectWordStateProvider.state)
.update((state) => _mnemonic[next]);
Navigator.of(context).pushNamed(
VerifyRecoveryPhraseView.routeName,
arguments: Tuple2(_manager, _mnemonic),
);
},
style: Theme.of(context).textButtonTheme.style?.copyWith(
backgroundColor: MaterialStateProperty.all<Color>(
CFColors.stackAccent,
if (mounted) {
Navigator.of(context).popUntil(
ModalRoute.withName(
NewWalletRecoveryPhraseWarningView.routeName,
),
);
}
},
),
actions: [
Padding(
padding: const EdgeInsets.all(10),
child: AspectRatio(
aspectRatio: 1,
child: AppBarIconButton(
color: Theme.of(context)
.extension<StackColors>()!
.background,
shadows: const [],
icon: SvgPicture.asset(
Assets.svg.copy,
width: 24,
height: 24,
color: Theme.of(context)
.extension<StackColors>()!
.topNavIconPrimary,
),
onPressed: () async {
await _copy();
},
),
),
child: Text(
"I saved my recovery phrase",
style: STextStyles.button,
),
),
],
),
],
body: Container(
color: Theme.of(context).extension<StackColors>()!.background,
width: isDesktop ? 600 : null,
child: Padding(
padding: isDesktop
? const EdgeInsets.all(0)
: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
if (!isDesktop)
const SizedBox(
height: 4,
),
if (!isDesktop)
Text(
_manager.walletName,
textAlign: TextAlign.center,
style: STextStyles.label(context).copyWith(
fontSize: 12,
),
),
SizedBox(
height: isDesktop ? 24 : 4,
),
Text(
"Recovery Phrase",
textAlign: TextAlign.center,
style: isDesktop
? STextStyles.desktopH2(context)
: STextStyles.pageTitleH1(context),
),
const SizedBox(
height: 16,
),
Container(
decoration: BoxDecoration(
color: isDesktop
? Theme.of(context)
.extension<StackColors>()!
.background
: Theme.of(context).extension<StackColors>()!.popupBG,
borderRadius: BorderRadius.circular(
Constants.size.circularBorderRadius),
),
child: Padding(
padding: isDesktop
? const EdgeInsets.all(0)
: const EdgeInsets.all(12),
child: Text(
"Please write down your recovery phrase in the correct order and save it to keep your funds secure. You will also be asked to verify the words on the next screen.",
textAlign: TextAlign.center,
style: isDesktop
? STextStyles.desktopSubtitleH2(context)
: STextStyles.label(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.accentColorDark),
),
),
),
SizedBox(
height: isDesktop ? 21 : 8,
),
if (!isDesktop)
Expanded(
child: SingleChildScrollView(
child: MnemonicTable(
words: _mnemonic,
isDesktop: isDesktop,
),
),
),
if (isDesktop)
MnemonicTable(
words: _mnemonic,
isDesktop: isDesktop,
),
SizedBox(
height: isDesktop ? 24 : 16,
),
if (isDesktop)
SizedBox(
height: 70,
child: TextButton(
onPressed: () async {
await _copy();
},
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SvgPicture.asset(
Assets.svg.copy,
width: 20,
height: 20,
),
const SizedBox(
width: 10,
),
Text(
"Copy to clipboard",
style: STextStyles.desktopButtonSecondaryEnabled(
context),
)
],
),
),
),
if (isDesktop)
const SizedBox(
height: 16,
),
ConstrainedBox(
constraints: BoxConstraints(
minHeight: isDesktop ? 70 : 0,
),
child: TextButton(
onPressed: () async {
final int next = Random().nextInt(_mnemonic.length);
ref
.read(verifyMnemonicWordIndexStateProvider.state)
.update((state) => next);
ref
.read(verifyMnemonicCorrectWordStateProvider.state)
.update((state) => _mnemonic[next]);
unawaited(Navigator.of(context).pushNamed(
VerifyRecoveryPhraseView.routeName,
arguments: Tuple2(_manager, _mnemonic),
));
},
style: Theme.of(context)
.extension<StackColors>()!
.getPrimaryEnabledButtonColor(context),
child: Text(
"I saved my recovery phrase",
style: isDesktop
? STextStyles.desktopButtonEnabled(context)
: STextStyles.button(context),
),
),
),
],
),
),
),
),
),
);
));
}
}

View file

@ -1,19 +1,20 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:stackwallet/pages/add_wallet_views/new_wallet_recovery_phrase_view/sub_widgets/mnemonic_table_item.dart';
class MnemonicTable extends StatelessWidget {
const MnemonicTable({
Key? key,
required this.words,
required this.isDesktop,
}) : super(key: key);
final List<String> words;
static const wordsPerRow = 3;
final bool isDesktop;
@override
Widget build(BuildContext context) {
debugPrint("BUILD: $runtimeType");
final wordsPerRow = isDesktop ? 4 : 3;
final int rows = words.length ~/ wordsPerRow;
@ -26,51 +27,54 @@ class MnemonicTable extends StatelessWidget {
children: [
for (int i = 1; i <= rows; i++)
Padding(
padding: const EdgeInsets.symmetric(vertical: 5),
padding: EdgeInsets.symmetric(vertical: isDesktop ? 8 : 5),
child: Row(
children: [
for (int j = 1; j <= wordsPerRow; j++) ...[
if (j > 1)
const SizedBox(
width: 6,
SizedBox(
width: isDesktop ? 10 : 6,
),
Expanded(
child: MnemonicTableItem(
number: ++index,
word: words[index - 1],
isDesktop: isDesktop,
),
),
],
],
),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 5),
child: Row(
children: [
for (int i = index; i < words.length; i++) ...[
if (i > index)
if (index != words.length)
Padding(
padding: EdgeInsets.symmetric(vertical: isDesktop ? 8 : 5),
child: Row(
children: [
for (int i = index; i < words.length; i++) ...[
if (i > index)
SizedBox(
width: isDesktop ? 10 : 6,
),
Expanded(
child: MnemonicTableItem(
number: i + 1,
word: words[i],
isDesktop: isDesktop,
),
),
],
for (int i = remainder; i < wordsPerRow; i++) ...[
const SizedBox(
width: 6,
),
Expanded(
child: MnemonicTableItem(
number: i + 1,
word: words[i],
Expanded(
child: Container(),
),
),
],
],
for (int i = remainder; i < wordsPerRow; i++) ...[
const SizedBox(
width: 6,
),
Expanded(
child: Container(),
),
],
],
),
),
),
],
);
}

View file

@ -1,49 +1,57 @@
import 'package:flutter/material.dart';
import 'package:stackwallet/utilities/cfcolors.dart';
import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/widgets/rounded_white_container.dart';
class MnemonicTableItem extends StatelessWidget {
const MnemonicTableItem({
Key? key,
required this.number,
required this.word,
required this.isDesktop,
}) : super(key: key);
final int number;
final String word;
final bool isDesktop;
@override
Widget build(BuildContext context) {
debugPrint("BUILD: $runtimeType");
return Container(
decoration: BoxDecoration(
color: CFColors.white,
borderRadius: BorderRadius.circular(
Constants.size.circularBorderRadius,
),
),
child: Padding(
padding: const EdgeInsets.all(8),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(
number.toString(),
style: STextStyles.baseXS.copyWith(
color: CFColors.gray3,
fontSize: 10,
),
),
const SizedBox(
width: 8,
),
Text(
word,
style: STextStyles.baseXS,
),
],
),
return RoundedWhiteContainer(
padding: isDesktop
? const EdgeInsets.symmetric(horizontal: 12, vertical: 9)
: const EdgeInsets.all(8),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(
number.toString(),
style: isDesktop
? STextStyles.desktopTextExtraSmall(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textSubtitle2,
)
: STextStyles.baseXS(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textSubtitle2,
fontSize: 10,
),
),
const SizedBox(
width: 8,
),
Text(
word,
style: isDesktop
? STextStyles.desktopTextExtraSmall(context).copyWith(
color: Theme.of(context).extension<StackColors>()!.textDark,
)
: STextStyles.baseXS(context),
),
],
),
);
}

View file

@ -1,18 +1,25 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:stackwallet/pages/add_wallet_views/new_wallet_recovery_phrase_view/new_wallet_recovery_phrase_view.dart';
import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/exit_to_my_stack_button.dart';
import 'package:stackwallet/providers/providers.dart';
import 'package:stackwallet/services/coins/coin_service.dart';
import 'package:stackwallet/services/coins/manager.dart';
import 'package:stackwallet/services/transaction_notification_tracker.dart';
import 'package:stackwallet/utilities/cfcolors.dart';
import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/default_nodes.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
import 'package:stackwallet/utilities/logger.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/utilities/util.dart';
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart';
import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart';
import 'package:stackwallet/widgets/loading_indicator.dart';
import 'package:stackwallet/widgets/rounded_white_container.dart';
import 'package:tuple/tuple.dart';
class NewWalletRecoveryPhraseWarningView extends StatefulWidget {
@ -36,11 +43,13 @@ class _NewWalletRecoveryPhraseWarningViewState
extends State<NewWalletRecoveryPhraseWarningView> {
late final Coin coin;
late final String walletName;
late final bool isDesktop;
@override
void initState() {
coin = widget.coin;
walletName = widget.walletName;
isDesktop = Util.isDesktop;
super.initState();
}
@ -52,60 +61,72 @@ class _NewWalletRecoveryPhraseWarningViewState
? Constants.seedPhraseWordCountMonero
: Constants.seedPhraseWordCountBip39;
return Scaffold(
appBar: AppBar(
leading: AppBarBackButton(
onPressed: () {
Navigator.of(context).pop();
},
),
),
body: Container(
color: CFColors.almostWhite,
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const SizedBox(
height: 4,
),
return MasterScaffold(
isDesktop: isDesktop,
appBar: isDesktop
? const DesktopAppBar(
isCompactHeight: false,
leading: AppBarBackButton(),
trailing: ExitToMyStackButton(),
)
: AppBar(
leading: const AppBarBackButton(),
),
body: Padding(
padding: EdgeInsets.all(isDesktop ? 0 : 16),
child: Column(
crossAxisAlignment: isDesktop
? CrossAxisAlignment.center
: CrossAxisAlignment.stretch,
children: [
const SizedBox(
height: 4,
),
if (!isDesktop)
Text(
walletName,
textAlign: TextAlign.center,
style: STextStyles.label.copyWith(
style: STextStyles.label(context).copyWith(
fontSize: 12,
),
),
const SizedBox(
height: 4,
),
Text(
"Recovery Phrase",
textAlign: TextAlign.center,
style: isDesktop
? STextStyles.desktopH2(context)
: STextStyles.pageTitleH1(context),
),
SizedBox(
height: isDesktop ? 32 : 16,
),
RoundedWhiteContainer(
padding: isDesktop
? const EdgeInsets.all(32)
: const EdgeInsets.all(12),
width: isDesktop ? 480 : null,
child: Text(
"On the next screen you will see $_numberOfPhraseWords words that make up your recovery phrase.\n\nPlease write it down. Keep it safe and never share it with anyone. Your recovery phrase is the only way you can access your funds if you forget your PIN, lose your phone, etc.\n\nStack Wallet does not keep nor is able to restore your recover phrase. Only you have access to your wallet.",
style: isDesktop
? STextStyles.desktopTextMediumRegular(context)
: STextStyles.subtitle(context).copyWith(
fontSize: 12,
),
),
),
if (!isDesktop) const Spacer(),
if (isDesktop)
const SizedBox(
height: 4,
height: 32,
),
Text(
"Recovery Phrase",
textAlign: TextAlign.center,
style: STextStyles.pageTitleH1,
ConstrainedBox(
constraints: BoxConstraints(
maxWidth: isDesktop ? 480 : 0,
),
const SizedBox(
height: 16,
),
Container(
decoration: BoxDecoration(
color: CFColors.white,
borderRadius: BorderRadius.circular(
Constants.size.circularBorderRadius),
),
child: Padding(
padding: const EdgeInsets.all(12),
child: Text(
"On the next screen you will see $_numberOfPhraseWords words that make up your recovery phrase.\n\nPlease write it down. Keep it safe and never share it with anyone. Your recovery phrase is the only way you can access your funds if you forget your PIN, lose your phone, etc.\n\nStack Wallet does not keep nor is able to restore your recover phrase. Only you have access to your wallet.",
style: STextStyles.subtitle.copyWith(
fontSize: 12,
),
),
),
),
const Spacer(),
Consumer(
child: Consumer(
builder: (_, ref, __) {
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
@ -119,6 +140,9 @@ class _NewWalletRecoveryPhraseWarningViewState
child: Container(
color: Colors.transparent,
child: Row(
crossAxisAlignment: isDesktop
? CrossAxisAlignment.start
: CrossAxisAlignment.center,
children: [
Checkbox(
materialTapTargetSize:
@ -131,138 +155,143 @@ class _NewWalletRecoveryPhraseWarningViewState
newValue!;
},
),
const SizedBox(
width: 4,
SizedBox(
width: isDesktop ? 14 : 4,
),
Flexible(
child: Text(
"I understand that if I lose my recovery phrase, I will not be able to access my funds.",
style: STextStyles.baseXS,
style: isDesktop
? STextStyles.desktopTextMedium(context)
: STextStyles.baseXS(context),
),
),
],
),
),
),
const SizedBox(
height: 16,
SizedBox(
height: isDesktop ? 32 : 16,
),
TextButton(
onPressed: ref.read(checkBoxStateProvider.state).state
? () async {
try {
showDialog<dynamic>(
context: context,
barrierDismissible: false,
useSafeArea: true,
builder: (ctx) {
return const Center(
child: LoadingIndicator(
width: 50,
height: 50,
),
);
},
);
final walletsService = ref.read(
walletsServiceChangeNotifierProvider);
final walletId =
await walletsService.addNewWallet(
name: walletName,
coin: coin,
shouldNotifyListeners: false,
);
var node = ref
.read(nodeServiceChangeNotifierProvider)
.getPrimaryNodeFor(coin: coin);
if (node == null) {
node = DefaultNodes.getNodeFor(coin);
ref
.read(nodeServiceChangeNotifierProvider)
.setPrimaryNodeFor(
coin: coin,
node: node,
ConstrainedBox(
constraints: BoxConstraints(
minHeight: isDesktop ? 70 : 0,
),
child: TextButton(
onPressed: ref.read(checkBoxStateProvider.state).state
? () async {
try {
unawaited(showDialog<dynamic>(
context: context,
barrierDismissible: false,
useSafeArea: true,
builder: (ctx) {
return const Center(
child: LoadingIndicator(
width: 50,
height: 50,
),
);
}
},
));
final txTracker =
TransactionNotificationTracker(
walletId: walletId!);
final walletsService = ref.read(
walletsServiceChangeNotifierProvider);
final failovers = ref
.read(nodeServiceChangeNotifierProvider)
.failoverNodesFor(coin: widget.coin);
final wallet = CoinServiceAPI.from(
coin,
walletId,
walletName,
node,
txTracker,
ref.read(prefsChangeNotifierProvider),
failovers,
);
final manager = Manager(wallet);
await manager.initializeNew();
// pop progress dialog
if (mounted) {
Navigator.pop(context);
}
// set checkbox back to unchecked to annoy users to agree again :P
ref.read(checkBoxStateProvider.state).state =
false;
if (mounted) {
Navigator.of(context).pushNamed(
NewWalletRecoveryPhraseView.routeName,
arguments: Tuple2(
manager,
await manager.mnemonic,
),
final walletId =
await walletsService.addNewWallet(
name: walletName,
coin: coin,
shouldNotifyListeners: false,
);
var node = ref
.read(nodeServiceChangeNotifierProvider)
.getPrimaryNodeFor(coin: coin);
if (node == null) {
node = DefaultNodes.getNodeFor(coin);
await ref
.read(
nodeServiceChangeNotifierProvider)
.setPrimaryNodeFor(
coin: coin,
node: node,
);
}
final txTracker =
TransactionNotificationTracker(
walletId: walletId!);
final failovers = ref
.read(nodeServiceChangeNotifierProvider)
.failoverNodesFor(coin: widget.coin);
final wallet = CoinServiceAPI.from(
coin,
walletId,
walletName,
node,
txTracker,
ref.read(prefsChangeNotifierProvider),
failovers,
);
final manager = Manager(wallet);
await manager.initializeNew();
// pop progress dialog
if (mounted) {
Navigator.pop(context);
}
// set checkbox back to unchecked to annoy users to agree again :P
ref
.read(checkBoxStateProvider.state)
.state = false;
if (mounted) {
unawaited(Navigator.of(context).pushNamed(
NewWalletRecoveryPhraseView.routeName,
arguments: Tuple2(
manager,
await manager.mnemonic,
),
));
}
} catch (e, s) {
Logging.instance
.log("$e\n$s", level: LogLevel.Fatal);
// TODO: handle gracefully
// any network/socket exception here will break new wallet creation
rethrow;
}
} catch (e, s) {
Logging.instance
.log("$e\n$s", level: LogLevel.Fatal);
// TODO: handle gracefully
// any network/socket exception here will break new wallet creation
rethrow;
}
}
: null,
style: ref.read(checkBoxStateProvider.state).state
? Theme.of(context).textButtonTheme.style?.copyWith(
backgroundColor:
MaterialStateProperty.all<Color>(
CFColors.stackAccent,
),
)
: Theme.of(context).textButtonTheme.style?.copyWith(
backgroundColor:
MaterialStateProperty.all<Color>(
CFColors.stackAccent.withOpacity(
0.25,
),
),
),
child: Text(
"View recovery phrase",
style: STextStyles.button,
: null,
style: ref.read(checkBoxStateProvider.state).state
? Theme.of(context)
.extension<StackColors>()!
.getPrimaryEnabledButtonColor(context)
: Theme.of(context)
.extension<StackColors>()!
.getPrimaryDisabledButtonColor(context),
child: Text(
"View recovery phrase",
style: isDesktop
? ref.read(checkBoxStateProvider.state).state
? STextStyles.desktopButtonEnabled(context)
: STextStyles.desktopButtonDisabled(context)
: STextStyles.button(context),
),
),
),
],
);
},
),
],
),
),
],
),
),
);

View file

@ -1,6 +1,6 @@
import 'package:flutter/material.dart';
import 'package:stackwallet/utilities/cfcolors.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/widgets/stack_dialog.dart';
class ConfirmRecoveryDialog extends StatelessWidget {
@ -20,28 +20,24 @@ class ConfirmRecoveryDialog extends StatelessWidget {
message:
"Restoring your wallet may take a while. Please do not exit this screen once the process is started.",
leftButton: TextButton(
style: Theme.of(context).textButtonTheme.style?.copyWith(
backgroundColor: MaterialStateProperty.all<Color>(
CFColors.buttonGray,
),
),
style: Theme.of(context)
.extension<StackColors>()!
.getSecondaryEnabledButtonColor(context),
child: Text(
"Cancel",
style: STextStyles.itemSubtitle12,
style: STextStyles.itemSubtitle12(context),
),
onPressed: () {
Navigator.of(context).pop();
},
),
rightButton: TextButton(
style: Theme.of(context).textButtonTheme.style?.copyWith(
backgroundColor: MaterialStateProperty.all<Color>(
CFColors.stackAccent,
),
),
style: Theme.of(context)
.extension<StackColors>()!
.getPrimaryEnabledButtonColor(context),
child: Text(
"Restore",
style: STextStyles.button,
style: STextStyles.button(context),
),
onPressed: () {
Navigator.of(context).pop();

View file

@ -1,409 +0,0 @@
import 'package:flutter/material.dart';
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/restore_wallet_view/restore_wallet_view.dart';
import 'package:stackwallet/pages/add_wallet_views/restore_wallet_view/sub_widgets/mnemonic_word_count_select_sheet.dart';
import 'package:stackwallet/providers/ui/verify_recovery_phrase/mnemonic_word_count_state_provider.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/cfcolors.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/widgets/custom_buttons/app_bar_icon_button.dart';
import 'package:stackwallet/widgets/rounded_white_container.dart';
import 'package:tuple/tuple.dart';
class RestoreOptionsView extends ConsumerStatefulWidget {
const RestoreOptionsView({
Key? key,
required this.walletName,
required this.coin,
}) : super(key: key);
static const routeName = "/restoreOptions";
final String walletName;
final Coin coin;
@override
ConsumerState<RestoreOptionsView> createState() => _RestoreOptionsViewState();
}
class _RestoreOptionsViewState extends ConsumerState<RestoreOptionsView> {
late final String walletName;
late final Coin coin;
late TextEditingController _dateController;
late TextEditingController _lengthController;
late FocusNode textFieldFocusNode;
final bool _nextEnabled = true;
DateTime _restoreFromDate = DateTime.fromMillisecondsSinceEpoch(0);
@override
void initState() {
walletName = widget.walletName;
coin = widget.coin;
_dateController = TextEditingController();
_lengthController = TextEditingController();
textFieldFocusNode = FocusNode();
super.initState();
}
@override
void dispose() {
_dateController.dispose();
_lengthController.dispose();
textFieldFocusNode.dispose();
super.dispose();
}
final _datePickerTextStyleBase = GoogleFonts.inter(
color: CFColors.gray3,
fontSize: 12,
fontWeight: FontWeight.w400,
letterSpacing: 0.5,
);
MaterialRoundedDatePickerStyle _buildDatePickerStyle() {
return MaterialRoundedDatePickerStyle(
paddingMonthHeader: const EdgeInsets.only(top: 11),
colorArrowNext: CFColors.neutral60,
colorArrowPrevious: CFColors.neutral60,
textStyleButtonNegative: _datePickerTextStyleBase.copyWith(
fontSize: 16, fontWeight: FontWeight.w600),
textStyleButtonPositive: _datePickerTextStyleBase.copyWith(
fontSize: 16, fontWeight: FontWeight.w600),
textStyleCurrentDayOnCalendar: _datePickerTextStyleBase.copyWith(
color: CFColors.stackAccent,
),
textStyleDayHeader: _datePickerTextStyleBase.copyWith(
color: CFColors.stackAccent,
fontSize: 16,
fontWeight: FontWeight.w600,
),
textStyleDayOnCalendar: _datePickerTextStyleBase,
textStyleDayOnCalendarDisabled: _datePickerTextStyleBase.copyWith(
color: CFColors.neutral80,
),
textStyleDayOnCalendarSelected: _datePickerTextStyleBase.copyWith(
color: CFColors.white,
),
textStyleMonthYearHeader: _datePickerTextStyleBase.copyWith(
color: CFColors.neutral60,
fontSize: 16,
fontWeight: FontWeight.w600,
),
textStyleYearButton: _datePickerTextStyleBase.copyWith(
color: CFColors.white,
fontSize: 16,
fontWeight: FontWeight.w600,
),
textStyleButtonAction: GoogleFonts.inter(),
);
}
MaterialRoundedYearPickerStyle _buildYearPickerStyle() {
return MaterialRoundedYearPickerStyle(
textStyleYear: _datePickerTextStyleBase.copyWith(
color: CFColors.gray3,
fontWeight: FontWeight.w600,
fontSize: 16,
),
textStyleYearSelected: _datePickerTextStyleBase.copyWith(
color: CFColors.stackAccent,
fontWeight: FontWeight.w600,
fontSize: 18,
),
);
}
@override
Widget build(BuildContext context) {
debugPrint("BUILD: $runtimeType with ${coin.name} $walletName");
return Scaffold(
appBar: AppBar(
leading: AppBarBackButton(
onPressed: () {
if (textFieldFocusNode.hasFocus) {
textFieldFocusNode.unfocus();
Future<void>.delayed(const Duration(milliseconds: 100))
.then((value) => Navigator.of(context).pop());
} else {
Navigator.of(context).pop();
}
},
),
),
body: Container(
color: CFColors.almostWhite,
child: Padding(
padding: const EdgeInsets.all(16),
child: LayoutBuilder(
builder: (ctx, constraints) {
return SingleChildScrollView(
child: ConstrainedBox(
constraints: BoxConstraints(minHeight: constraints.maxHeight),
child: IntrinsicHeight(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const Spacer(
flex: 1,
),
Image(
image: AssetImage(
Assets.png.imageFor(coin: coin),
),
height: 100,
),
const SizedBox(
height: 16,
),
Text(
"Restore options",
textAlign: TextAlign.center,
style: STextStyles.pageTitleH1,
),
const SizedBox(
height: 24,
),
if (coin == Coin.monero || coin == Coin.epicCash)
Text(
"Choose start date",
style: STextStyles.smallMed12,
textAlign: TextAlign.left,
),
if (coin == Coin.monero || coin == Coin.epicCash)
const SizedBox(
height: 8,
),
if (coin == Coin.monero || coin == Coin.epicCash)
Container(
color: Colors.transparent,
child: TextField(
onTap: () async {
final height =
MediaQuery.of(context).size.height;
// check and hide keyboard
if (FocusScope.of(context).hasFocus) {
FocusScope.of(context).unfocus();
await Future<void>.delayed(
const Duration(milliseconds: 125));
}
final date = await showRoundedDatePicker(
context: context,
initialDate: DateTime.now(),
height: height * 0.5,
theme: ThemeData(
primarySwatch: CFColors.createMaterialColor(
CFColors.stackAccent),
),
//TODO pick a better initial date
// 2007 chosen as that is just before bitcoin launched
firstDate: DateTime(2007),
lastDate: DateTime.now(),
borderRadius:
Constants.size.circularBorderRadius * 2,
textPositiveButton: "SELECT",
styleDatePicker: _buildDatePickerStyle(),
styleYearPicker: _buildYearPickerStyle(),
);
if (date != null) {
_restoreFromDate = date;
_dateController.text =
Format.formatDate(date);
}
},
controller: _dateController,
style: STextStyles.field,
decoration: InputDecoration(
hintText: "Restore from...",
suffixIcon: UnconstrainedBox(
child: Row(
children: [
const SizedBox(
width: 16,
),
SvgPicture.asset(
Assets.svg.calendar,
color: CFColors.neutral50,
width: 16,
height: 16,
),
const SizedBox(
width: 12,
),
],
),
),
),
key: const Key("restoreOptionsViewDatePickerKey"),
readOnly: true,
toolbarOptions: const ToolbarOptions(
copy: true,
cut: false,
paste: false,
selectAll: false,
),
onChanged: (newValue) {},
),
),
if (coin == Coin.monero || coin == Coin.epicCash)
const SizedBox(
height: 8,
),
if (coin == Coin.monero || coin == Coin.epicCash)
RoundedWhiteContainer(
child: Center(
child: Text(
"Choose the date you made the wallet (approximate is fine)",
style: STextStyles.smallMed12.copyWith(
fontSize: 10,
),
),
),
),
if (coin == Coin.monero || coin == Coin.epicCash)
const SizedBox(
height: 16,
),
Text(
"Choose recovery phrase length",
style: STextStyles.smallMed12,
textAlign: TextAlign.left,
),
const SizedBox(
height: 8,
),
Stack(
children: [
TextField(
controller: _lengthController,
readOnly: true,
textInputAction: TextInputAction.none,
),
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 12,
),
child: RawMaterialButton(
splashColor: CFColors.splashLight,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(
Constants.size.circularBorderRadius,
),
),
onPressed: () {
showModalBottomSheet<dynamic>(
backgroundColor: Colors.transparent,
context: context,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(
top: Radius.circular(20),
),
),
builder: (_) {
return MnemonicWordCountSelectSheet(
lengthOptions:
Constants.possibleLengthsForCoin(
coin),
);
},
);
},
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
"${ref.watch(mnemonicWordCountStateProvider.state).state} words",
style: STextStyles.itemSubtitle12,
),
SvgPicture.asset(
Assets.svg.chevronDown,
width: 8,
height: 4,
color: CFColors.gray3,
),
],
),
),
)
],
),
const Spacer(
flex: 3,
),
TextButton(
onPressed: _nextEnabled
? () async {
// hide keyboard if has focus
if (FocusScope.of(context).hasFocus) {
FocusScope.of(context).unfocus();
await Future<void>.delayed(
const Duration(milliseconds: 75));
}
if (mounted) {
Navigator.of(context).pushNamed(
RestoreWalletView.routeName,
arguments: Tuple4(
walletName,
coin,
ref
.read(mnemonicWordCountStateProvider
.state)
.state,
_restoreFromDate,
),
);
}
}
: null,
style: _nextEnabled
? Theme.of(context)
.textButtonTheme
.style
?.copyWith(
backgroundColor:
MaterialStateProperty.all<Color>(
CFColors.stackAccent,
),
)
: Theme.of(context)
.textButtonTheme
.style
?.copyWith(
backgroundColor:
MaterialStateProperty.all<Color>(
CFColors.stackAccent.withOpacity(
0.25,
),
),
),
child: Text(
"Next",
style: STextStyles.button,
),
),
],
),
),
),
);
},
),
),
),
);
}
}

View file

@ -0,0 +1,405 @@
import 'package:dropdown_button2/dropdown_button2.dart';
import 'package:flutter/material.dart';
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/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';
import 'package:stackwallet/pages/add_wallet_views/restore_wallet_view/restore_options_view/sub_widgets/restore_options_platform_layout.dart';
import 'package:stackwallet/pages/add_wallet_views/restore_wallet_view/restore_wallet_view.dart';
import 'package:stackwallet/pages/add_wallet_views/restore_wallet_view/sub_widgets/mnemonic_word_count_select_sheet.dart';
import 'package:stackwallet/providers/ui/color_theme_provider.dart';
import 'package:stackwallet/providers/ui/verify_recovery_phrase/mnemonic_word_count_state_provider.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/utilities/util.dart';
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart';
import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart';
import 'package:stackwallet/widgets/rounded_white_container.dart';
import 'package:tuple/tuple.dart';
class RestoreOptionsView extends ConsumerStatefulWidget {
const RestoreOptionsView({
Key? key,
required this.walletName,
required this.coin,
}) : super(key: key);
static const routeName = "/restoreOptions";
final String walletName;
final Coin coin;
@override
ConsumerState<RestoreOptionsView> createState() => _RestoreOptionsViewState();
}
class _RestoreOptionsViewState extends ConsumerState<RestoreOptionsView> {
late final String walletName;
late final Coin coin;
late final bool isDesktop;
late TextEditingController _dateController;
late FocusNode textFieldFocusNode;
final bool _nextEnabled = true;
DateTime _restoreFromDate = DateTime.fromMillisecondsSinceEpoch(0);
late final Color baseColor;
@override
void initState() {
baseColor = ref.read(colorThemeProvider.state).state.textSubtitle2;
walletName = widget.walletName;
coin = widget.coin;
isDesktop = Util.isDesktop;
_dateController = TextEditingController();
textFieldFocusNode = FocusNode();
super.initState();
}
@override
void dispose() {
_dateController.dispose();
textFieldFocusNode.dispose();
super.dispose();
}
TextStyle get _datePickerTextStyleBase => GoogleFonts.inter(
color: baseColor,
fontSize: 12,
fontWeight: FontWeight.w400,
letterSpacing: 0.5,
);
MaterialRoundedDatePickerStyle _buildDatePickerStyle() {
return MaterialRoundedDatePickerStyle(
paddingMonthHeader: const EdgeInsets.only(top: 11),
colorArrowNext: Theme.of(context).extension<StackColors>()!.textSubtitle1,
colorArrowPrevious:
Theme.of(context).extension<StackColors>()!.textSubtitle1,
textStyleButtonNegative: _datePickerTextStyleBase.copyWith(
fontSize: 16, fontWeight: FontWeight.w600),
textStyleButtonPositive: _datePickerTextStyleBase.copyWith(
fontSize: 16, fontWeight: FontWeight.w600),
textStyleCurrentDayOnCalendar: _datePickerTextStyleBase.copyWith(
color: Theme.of(context).extension<StackColors>()!.accentColorDark,
),
textStyleDayHeader: _datePickerTextStyleBase.copyWith(
color: Theme.of(context).extension<StackColors>()!.accentColorDark,
fontSize: 16,
fontWeight: FontWeight.w600,
),
textStyleDayOnCalendar: _datePickerTextStyleBase,
textStyleDayOnCalendarDisabled: _datePickerTextStyleBase.copyWith(
color: Theme.of(context).extension<StackColors>()!.textSubtitle3,
),
textStyleDayOnCalendarSelected: _datePickerTextStyleBase.copyWith(
color: Theme.of(context).extension<StackColors>()!.popupBG,
),
textStyleMonthYearHeader: _datePickerTextStyleBase.copyWith(
color: Theme.of(context).extension<StackColors>()!.textSubtitle1,
fontSize: 16,
fontWeight: FontWeight.w600,
),
textStyleYearButton: _datePickerTextStyleBase.copyWith(
color: Theme.of(context).extension<StackColors>()!.textWhite,
fontSize: 16,
fontWeight: FontWeight.w600,
),
textStyleButtonAction: GoogleFonts.inter(),
);
}
MaterialRoundedYearPickerStyle _buildYearPickerStyle() {
return MaterialRoundedYearPickerStyle(
textStyleYear: _datePickerTextStyleBase.copyWith(
color: Theme.of(context).extension<StackColors>()!.textSubtitle2,
fontWeight: FontWeight.w600,
fontSize: 16,
),
textStyleYearSelected: _datePickerTextStyleBase.copyWith(
color: Theme.of(context).extension<StackColors>()!.accentColorDark,
fontWeight: FontWeight.w600,
fontSize: 18,
),
);
}
Future<void> nextPressed() async {
if (!isDesktop) {
// hide keyboard if has focus
if (FocusScope.of(context).hasFocus) {
FocusScope.of(context).unfocus();
await Future<void>.delayed(const Duration(milliseconds: 75));
}
}
if (mounted) {
await Navigator.of(context).pushNamed(
RestoreWalletView.routeName,
arguments: Tuple4(
walletName,
coin,
ref.read(mnemonicWordCountStateProvider.state).state,
_restoreFromDate,
),
);
}
}
Future<void> chooseDate() async {
final height = MediaQuery.of(context).size.height;
// check and hide keyboard
if (FocusScope.of(context).hasFocus) {
FocusScope.of(context).unfocus();
await Future<void>.delayed(const Duration(milliseconds: 125));
}
final date = await showRoundedDatePicker(
context: context,
initialDate: DateTime.now(),
height: height * 0.5,
theme: ThemeData(
primarySwatch: Util.createMaterialColor(
Theme.of(context).extension<StackColors>()!.accentColorDark),
),
//TODO pick a better initial date
// 2007 chosen as that is just before bitcoin launched
firstDate: DateTime(2007),
lastDate: DateTime.now(),
borderRadius: Constants.size.circularBorderRadius * 2,
textPositiveButton: "SELECT",
styleDatePicker: _buildDatePickerStyle(),
styleYearPicker: _buildYearPickerStyle(),
);
if (date != null) {
_restoreFromDate = date;
_dateController.text = Format.formatDate(date);
}
}
Future<void> chooseMnemonicLength() async {
await showModalBottomSheet<dynamic>(
backgroundColor: Colors.transparent,
context: context,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(
top: Radius.circular(20),
),
),
builder: (_) {
return MnemonicWordCountSelectSheet(
lengthOptions: Constants.possibleLengthsForCoin(coin),
);
},
);
}
@override
Widget build(BuildContext context) {
debugPrint("BUILD: $runtimeType with ${coin.name} $walletName");
final lengths = Constants.possibleLengthsForCoin(coin).toList();
return DesktopScaffold(
appBar: isDesktop
? const DesktopAppBar(
isCompactHeight: false,
leading: AppBarBackButton(),
)
: AppBar(
leading: AppBarBackButton(
onPressed: () {
if (textFieldFocusNode.hasFocus) {
textFieldFocusNode.unfocus();
Future<void>.delayed(const Duration(milliseconds: 100))
.then((value) => Navigator.of(context).pop());
} else {
Navigator.of(context).pop();
}
},
),
),
body: RestoreOptionsPlatformLayout(
isDesktop: isDesktop,
child: ConstrainedBox(
constraints: BoxConstraints(
maxWidth: isDesktop ? 480 : double.infinity,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
if (!isDesktop)
const Spacer(
flex: 1,
),
if (!isDesktop)
Image(
image: AssetImage(
Assets.png.imageFor(coin: coin),
),
height: 100,
),
SizedBox(
height: isDesktop ? 24 : 16,
),
Text(
"Restore options",
textAlign: TextAlign.center,
style: isDesktop
? STextStyles.desktopH2(context)
: STextStyles.pageTitleH1(context),
),
SizedBox(
height: isDesktop ? 40 : 24,
),
if (coin == Coin.monero || coin == Coin.epicCash)
Text(
"Choose start date",
style: isDesktop
? STextStyles.desktopTextExtraSmall(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textDark3,
)
: STextStyles.smallMed12(context),
textAlign: TextAlign.left,
),
if (coin == Coin.monero || coin == Coin.epicCash)
SizedBox(
height: isDesktop ? 16 : 8,
),
if (coin == Coin.monero || coin == Coin.epicCash)
// if (!isDesktop)
RestoreFromDatePicker(
onTap: chooseDate,
),
// if (isDesktop)
// // TODO desktop date picker
if (coin == Coin.monero || coin == Coin.epicCash)
const SizedBox(
height: 8,
),
if (coin == Coin.monero || coin == Coin.epicCash)
RoundedWhiteContainer(
child: Center(
child: Text(
"Choose the date you made the wallet (approximate is fine)",
style: isDesktop
? STextStyles.desktopTextExtraSmall(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textSubtitle1,
)
: STextStyles.smallMed12(context).copyWith(
fontSize: 10,
),
),
),
),
if (coin == Coin.monero || coin == Coin.epicCash)
SizedBox(
height: isDesktop ? 24 : 16,
),
Text(
"Choose recovery phrase length",
style: isDesktop
? STextStyles.desktopTextExtraSmall(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textDark3,
)
: STextStyles.smallMed12(context),
textAlign: TextAlign.left,
),
SizedBox(
height: isDesktop ? 16 : 8,
),
if (isDesktop)
DropdownButtonHideUnderline(
child: DropdownButton2<int>(
value:
ref.watch(mnemonicWordCountStateProvider.state).state,
items: [
...lengths.map(
(e) => DropdownMenuItem(
value: e,
child: Text(
"$e words",
style: STextStyles.desktopTextMedium(context),
),
),
),
],
onChanged: (value) {
if (value is int) {
ref.read(mnemonicWordCountStateProvider.state).state =
value;
}
},
isExpanded: true,
icon: SvgPicture.asset(
Assets.svg.chevronDown,
width: 12,
height: 6,
color: Theme.of(context)
.extension<StackColors>()!
.textFieldActiveSearchIconRight,
),
buttonPadding: const EdgeInsets.symmetric(
horizontal: 16,
vertical: 8,
),
buttonDecoration: BoxDecoration(
color: Theme.of(context)
.extension<StackColors>()!
.textFieldDefaultBG,
borderRadius: BorderRadius.circular(
Constants.size.circularBorderRadius,
),
),
dropdownDecoration: BoxDecoration(
color: Theme.of(context)
.extension<StackColors>()!
.textFieldDefaultBG,
borderRadius: BorderRadius.circular(
Constants.size.circularBorderRadius,
),
),
),
),
if (!isDesktop)
MobileMnemonicLengthSelector(
chooseMnemonicLength: chooseMnemonicLength,
),
if (!isDesktop)
const Spacer(
flex: 3,
),
if (isDesktop)
const SizedBox(
height: 32,
),
RestoreOptionsNextButton(
isDesktop: isDesktop,
onPressed: _nextEnabled ? nextPressed : null,
),
],
),
),
),
);
}
}

View file

@ -0,0 +1,60 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/svg.dart';
import 'package:stackwallet/providers/ui/verify_recovery_phrase/mnemonic_word_count_state_provider.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
class MobileMnemonicLengthSelector extends ConsumerWidget {
const MobileMnemonicLengthSelector({
Key? key,
required this.chooseMnemonicLength,
}) : super(key: key);
final VoidCallback chooseMnemonicLength;
@override
Widget build(BuildContext context, WidgetRef ref) {
return Stack(
children: [
const TextField(
// controller: _lengthController,
readOnly: true,
textInputAction: TextInputAction.none,
),
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 12,
),
child: RawMaterialButton(
splashColor: Theme.of(context).extension<StackColors>()!.highlight,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(
Constants.size.circularBorderRadius,
),
),
onPressed: chooseMnemonicLength,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"${ref.watch(mnemonicWordCountStateProvider.state).state} words",
style: STextStyles.itemSubtitle12(context),
),
SvgPicture.asset(
Assets.svg.chevronDown,
width: 8,
height: 4,
color:
Theme.of(context).extension<StackColors>()!.textSubtitle2,
),
],
),
),
)
],
);
}
}

View file

@ -0,0 +1,76 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
class RestoreFromDatePicker extends StatefulWidget {
const RestoreFromDatePicker({Key? key, required this.onTap})
: super(key: key);
final VoidCallback onTap;
@override
State<RestoreFromDatePicker> createState() => _RestoreFromDatePickerState();
}
class _RestoreFromDatePickerState extends State<RestoreFromDatePicker> {
late final TextEditingController _dateController;
late final VoidCallback onTap;
@override
void initState() {
onTap = widget.onTap;
_dateController = TextEditingController();
super.initState();
}
@override
void dispose() {
_dateController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Container(
color: Colors.transparent,
child: TextField(
onTap: onTap,
controller: _dateController,
style: STextStyles.field(context),
decoration: InputDecoration(
hintText: "Restore from...",
suffixIcon: UnconstrainedBox(
child: Row(
children: [
const SizedBox(
width: 16,
),
SvgPicture.asset(
Assets.svg.calendar,
color: Theme.of(context).extension<StackColors>()!.textDark3,
width: 16,
height: 16,
),
const SizedBox(
width: 12,
),
],
),
),
),
key: const Key("restoreOptionsViewDatePickerKey"),
readOnly: true,
toolbarOptions: const ToolbarOptions(
copy: true,
cut: false,
paste: false,
selectAll: false,
),
onChanged: (newValue) {},
),
);
}
}

View file

@ -0,0 +1,37 @@
import 'package:flutter/material.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
class RestoreOptionsNextButton extends StatelessWidget {
const RestoreOptionsNextButton({
Key? key,
required this.isDesktop,
this.onPressed,
}) : super(key: key);
final bool isDesktop;
final VoidCallback? onPressed;
@override
Widget build(BuildContext context) {
return ConstrainedBox(
constraints: BoxConstraints(
minHeight: isDesktop ? 70 : 0,
),
child: TextButton(
onPressed: onPressed,
style: onPressed != null
? Theme.of(context)
.extension<StackColors>()!
.getPrimaryEnabledButtonColor(context)
: Theme.of(context)
.extension<StackColors>()!
.getPrimaryDisabledButtonColor(context),
child: Text(
"Next",
style: STextStyles.button(context),
),
),
);
}
}

View file

@ -0,0 +1,39 @@
import 'package:flutter/material.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
class RestoreOptionsPlatformLayout extends StatelessWidget {
const RestoreOptionsPlatformLayout({
Key? key,
required this.isDesktop,
required this.child,
}) : super(key: key);
final bool isDesktop;
final Widget child;
@override
Widget build(BuildContext context) {
if (isDesktop) {
return child;
} else {
return Container(
color: Theme.of(context).extension<StackColors>()!.background,
child: Padding(
padding: const EdgeInsets.all(16),
child: LayoutBuilder(
builder: (ctx, constraints) {
return SingleChildScrollView(
child: ConstrainedBox(
constraints: BoxConstraints(minHeight: constraints.maxHeight),
child: IntrinsicHeight(
child: child,
),
),
);
},
),
),
);
}
}
}

View file

@ -16,6 +16,7 @@ import 'package:stackwallet/pages/add_wallet_views/restore_wallet_view/sub_widge
import 'package:stackwallet/pages/add_wallet_views/restore_wallet_view/sub_widgets/restore_succeeded_dialog.dart';
import 'package:stackwallet/pages/add_wallet_views/restore_wallet_view/sub_widgets/restoring_dialog.dart';
import 'package:stackwallet/pages/home_view/home_view.dart';
import 'package:stackwallet/pages_desktop_specific/home/desktop_home_view.dart';
import 'package:stackwallet/providers/providers.dart';
import 'package:stackwallet/services/coins/coin_service.dart';
import 'package:stackwallet/services/coins/manager.dart';
@ -23,7 +24,6 @@ import 'package:stackwallet/services/transaction_notification_tracker.dart';
import 'package:stackwallet/utilities/address_utils.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/barcode_scanner_interface.dart';
import 'package:stackwallet/utilities/cfcolors.dart';
import 'package:stackwallet/utilities/clipboard_interface.dart';
import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/custom_text_selection_controls.dart';
@ -33,6 +33,8 @@ import 'package:stackwallet/utilities/enums/flush_bar_type.dart';
import 'package:stackwallet/utilities/enums/form_input_status_enum.dart';
import 'package:stackwallet/utilities/logger.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/utilities/util.dart';
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
import 'package:stackwallet/widgets/icon_widgets/clipboard_icon.dart';
import 'package:stackwallet/widgets/icon_widgets/qrcode_icon.dart';
@ -66,6 +68,7 @@ class RestoreWalletView extends ConsumerStatefulWidget {
class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
final _formKey = GlobalKey<FormState>();
late final int _seedWordCount;
late final bool isDesktop;
final HashSet<String> _wordListHashSet = HashSet.from(bip39wordlist.WORDLIST);
final ScrollController controller = ScrollController();
@ -85,13 +88,13 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
final text = data!.text!.trim();
if (text.isEmpty || _controllers.isEmpty) {
delegate.pasteText(SelectionChangedCause.toolbar);
unawaited(delegate.pasteText(SelectionChangedCause.toolbar));
return;
}
final words = text.split(" ");
if (words.isEmpty) {
delegate.pasteText(SelectionChangedCause.toolbar);
unawaited(delegate.pasteText(SelectionChangedCause.toolbar));
return;
}
@ -115,6 +118,7 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
@override
void initState() {
_seedWordCount = widget.seedWordsLength;
isDesktop = Util.isDesktop;
textSelectionControls = Platform.isIOS
? CustomCupertinoTextSelectionControls(onPaste: onControlsPaste)
@ -190,13 +194,13 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
// TODO: do actual check to make sure it is a valid mnemonic for monero
if (bip39.validateMnemonic(mnemonic) == false &&
!(widget.coin == Coin.monero)) {
showFloatingFlushBar(
unawaited(showFloatingFlushBar(
type: FlushBarType.warning,
message: "Invalid seed phrase!",
context: context,
);
));
} else {
if (!Platform.isLinux) Wakelock.enable();
if (!Platform.isLinux) await Wakelock.enable();
final walletsService = ref.read(walletsServiceChangeNotifierProvider);
final walletId = await walletsService.addNewWallet(
@ -206,7 +210,7 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
);
bool isRestoring = true;
// show restoring in progress
showDialog<dynamic>(
unawaited(showDialog<dynamic>(
context: context,
useSafeArea: false,
barrierDismissible: false,
@ -225,7 +229,7 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
},
);
},
);
));
var node = ref
.read(nodeServiceChangeNotifierProvider)
@ -233,7 +237,7 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
if (node == null) {
node = DefaultNodes.getNodeFor(widget.coin);
ref.read(nodeServiceChangeNotifierProvider).setPrimaryNodeFor(
await ref.read(nodeServiceChangeNotifierProvider).setPrimaryNodeFor(
coin: widget.coin,
node: node,
);
@ -282,26 +286,31 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
.addWallet(walletId: manager.walletId, manager: manager);
if (mounted) {
Navigator.of(context).pushNamedAndRemoveUntil(
HomeView.routeName, (route) => false);
if (isDesktop) {
Navigator.of(context)
.popUntil(ModalRoute.withName(DesktopHomeView.routeName));
} else {
unawaited(Navigator.of(context).pushNamedAndRemoveUntil(
HomeView.routeName, (route) => false));
}
}
showDialog<dynamic>(
await showDialog<dynamic>(
context: context,
useSafeArea: false,
barrierDismissible: true,
builder: (context) {
return const RestoreSucceededDialog();
},
).then(
(_) {
if (!Platform.isLinux) Wakelock.disable();
// timer.cancel();
},
);
if (!Platform.isLinux && !isDesktop) {
await Wakelock.disable();
}
}
} catch (e) {
if (!Platform.isLinux) Wakelock.disable();
if (!Platform.isLinux && !isDesktop) {
await Wakelock.disable();
}
// if (e is HiveError &&
// e.message == "Box has already been closed.") {
@ -316,7 +325,7 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
Navigator.pop(context);
// show restoring wallet failed dialog
showDialog<dynamic>(
await showDialog<dynamic>(
context: context,
useSafeArea: false,
barrierDismissible: true,
@ -331,7 +340,9 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
}
}
if (!Platform.isLinux) Wakelock.disable();
if (!Platform.isLinux && !isDesktop) {
await Wakelock.disable();
}
}
}
}
@ -343,27 +354,35 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
Widget? suffixIcon;
switch (status) {
case FormInputStatus.empty:
color = CFColors.fieldGray;
prefixColor = CFColors.gray3;
color = Theme.of(context).extension<StackColors>()!.textFieldDefaultBG;
prefixColor = Theme.of(context).extension<StackColors>()!.textSubtitle2;
break;
case FormInputStatus.invalid:
color = CFColors.notificationRedBackground;
prefixColor = CFColors.notificationRedForeground;
color = Theme.of(context).extension<StackColors>()!.textFieldErrorBG;
prefixColor = Theme.of(context)
.extension<StackColors>()!
.textFieldErrorSearchIconLeft;
suffixIcon = SvgPicture.asset(
Assets.svg.alertCircle,
width: 16,
height: 16,
color: CFColors.notificationRedForeground,
color: Theme.of(context)
.extension<StackColors>()!
.textFieldErrorSearchIconRight,
);
break;
case FormInputStatus.valid:
color = CFColors.notificationGreenBackground;
prefixColor = CFColors.notificationGreenForeground;
color = Theme.of(context).extension<StackColors>()!.textFieldSuccessBG;
prefixColor = Theme.of(context)
.extension<StackColors>()!
.textFieldSuccessSearchIconLeft;
suffixIcon = SvgPicture.asset(
Assets.svg.checkCircle,
width: 16,
height: 16,
color: CFColors.notificationGreenForeground,
color: Theme.of(context)
.extension<StackColors>()!
.textFieldSuccessSearchIconRight,
);
break;
}
@ -383,7 +402,7 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
),
child: Text(
prefix,
style: STextStyles.fieldLabel.copyWith(
style: STextStyles.fieldLabel(context).copyWith(
color: prefixColor,
),
),
@ -441,8 +460,71 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
});
}
controller.animateTo(controller.position.maxScrollExtent,
duration: const Duration(milliseconds: 300), curve: Curves.decelerate);
if (!isDesktop) {
controller.animateTo(
controller.position.maxScrollExtent,
duration: const Duration(milliseconds: 300),
curve: Curves.decelerate,
);
}
}
Future<void> scanMnemonicQr() async {
try {
final qrResult = await scanner.scan();
final results = AddressUtils.decodeQRSeedData(qrResult.rawContent);
Logging.instance.log("scan parsed: $results", level: LogLevel.Info);
if (results["mnemonic"] != null) {
final list = (results["mnemonic"] as List)
.map((value) => value as String)
.toList(growable: false);
if (list.isNotEmpty) {
_clearAndPopulateMnemonic(list);
Logging.instance.log("mnemonic populated", level: LogLevel.Info);
} else {
Logging.instance
.log("mnemonic failed to populate", level: LogLevel.Info);
}
}
} on PlatformException catch (e) {
// likely failed to get camera permissions
Logging.instance
.log("Restore wallet qr scan failed: $e", level: LogLevel.Warning);
}
}
Future<void> pasteMnemonic() async {
debugPrint("restoreWalletPasteButton tapped");
final ClipboardData? data =
await widget.clipboard.getData(Clipboard.kTextPlain);
if (data?.text != null && data!.text!.isNotEmpty) {
final content = data.text!.trim();
final list = content.split(" ");
_clearAndPopulateMnemonic(list);
}
}
Future<void> requestRestore() async {
// wait for keyboard to disappear
FocusScope.of(context).unfocus();
await Future<void>.delayed(
const Duration(milliseconds: 100),
);
await showDialog<dynamic>(
context: context,
useSafeArea: false,
barrierDismissible: true,
builder: (context) {
return ConfirmRecoveryDialog(
onConfirm: attemptRestore,
);
},
);
}
@override
@ -473,41 +555,15 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
key: const Key("restoreWalletViewQrCodeButton"),
size: 36,
shadows: const [],
color: CFColors.almostWhite,
icon: const QrCodeIcon(
color: Theme.of(context).extension<StackColors>()!.background,
icon: QrCodeIcon(
width: 20,
height: 20,
color: CFColors.stackAccent,
color: Theme.of(context)
.extension<StackColors>()!
.accentColorDark,
),
onPressed: () async {
try {
final qrResult = await scanner.scan();
final results =
AddressUtils.decodeQRSeedData(qrResult.rawContent);
Logging.instance
.log("scan parsed: $results", level: LogLevel.Info);
if (results["mnemonic"] != null) {
final list = (results["mnemonic"] as List)
.map((value) => value as String)
.toList(growable: false);
if (list.isNotEmpty) {
_clearAndPopulateMnemonic(list);
Logging.instance
.log("mnemonic populated", level: LogLevel.Info);
} else {
Logging.instance.log("mnemonic failed to populate",
level: LogLevel.Info);
}
}
} on PlatformException catch (e) {
// likely failed to get camera permissions
Logging.instance.log("Restore wallet qr scan failed: $e",
level: LogLevel.Warning);
}
},
onPressed: scanMnemonicQr,
),
),
),
@ -523,51 +579,43 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
key: const Key("restoreWalletPasteButton"),
size: 36,
shadows: const [],
color: CFColors.almostWhite,
icon: const ClipboardIcon(
color: Theme.of(context).extension<StackColors>()!.background,
icon: ClipboardIcon(
width: 20,
height: 20,
color: CFColors.stackAccent,
color: Theme.of(context)
.extension<StackColors>()!
.accentColorDark,
),
onPressed: () async {
debugPrint("restoreWalletPasteButton tapped");
final ClipboardData? data =
await widget.clipboard.getData(Clipboard.kTextPlain);
if (data?.text != null && data!.text!.isNotEmpty) {
final content = data.text!.trim();
final list = content.split(" ");
_clearAndPopulateMnemonic(list);
}
},
onPressed: pasteMnemonic,
),
),
),
],
),
body: Container(
color: CFColors.almostWhite,
color: Theme.of(context).extension<StackColors>()!.background,
child: Padding(
padding: const EdgeInsets.all(12.0),
child: Column(
children: [
Text(
widget.walletName,
style: STextStyles.itemSubtitle,
style: STextStyles.itemSubtitle(context),
),
const SizedBox(
height: 4,
),
Text(
"Recovery phrase",
style: STextStyles.pageTitleH1,
style: STextStyles.pageTitleH1(context),
),
const SizedBox(
height: 8,
),
Text(
"Enter your $_seedWordCount-word recovery phrase.",
style: STextStyles.subtitle,
style: STextStyles.subtitle(context),
),
const SizedBox(
height: 10,
@ -617,7 +665,11 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
}
},
controller: _controllers[i - 1],
style: STextStyles.field,
style: STextStyles.field(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.overlay,
),
),
),
if (_inputStatuses[i - 1] ==
@ -632,78 +684,29 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
child: Text(
"Please check spelling",
textAlign: TextAlign.left,
style: STextStyles.label.copyWith(
color: CFColors
.notificationRedForeground,
style:
STextStyles.label(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textError,
),
),
),
)
],
),
// if (widget.coin == Coin.monero ||
// widget.coin == Coin.epicCash)
// Padding(
// padding: const EdgeInsets.only(
// top: 8.0,
// ),
// child: ClipRRect(
// borderRadius: BorderRadius.circular(
// Constants.size.circularBorderRadius,
// ),
// child: TextField(
// key: Key("restoreMnemonicFormField_height"),
// inputFormatters: <TextInputFormatter>[
// FilteringTextInputFormatter.allow(
// RegExp("[0-9]*")),
// ],
// keyboardType:
// TextInputType.numberWithOptions(),
// controller: _heightController,
// focusNode: _heightFocusNode,
// style: STextStyles.field,
// decoration: standardInputDecoration(
// "Height",
// _heightFocusNode,
// ),
// ),
// ),
// ),
Padding(
padding: const EdgeInsets.only(
top: 8.0,
),
child: TextButton(
style: Theme.of(context)
.textButtonTheme
.style
?.copyWith(
backgroundColor:
MaterialStateProperty.all<Color>(
CFColors.stackAccent,
),
),
onPressed: () async {
// wait for keyboard to disappear
FocusScope.of(context).unfocus();
await Future<void>.delayed(
const Duration(milliseconds: 100),
);
showDialog<dynamic>(
context: context,
useSafeArea: false,
barrierDismissible: true,
builder: (context) {
return ConfirmRecoveryDialog(
onConfirm: attemptRestore,
);
},
);
},
.extension<StackColors>()!
.getPrimaryEnabledButtonColor(context),
onPressed: requestRestore,
child: Text(
"Restore",
style: STextStyles.button,
style: STextStyles.button(context),
),
),
),

View file

@ -1,9 +1,9 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:stackwallet/providers/ui/verify_recovery_phrase/mnemonic_word_count_state_provider.dart';
import 'package:stackwallet/utilities/cfcolors.dart';
import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
class MnemonicWordCountSelectSheet extends ConsumerWidget {
const MnemonicWordCountSelectSheet({
@ -22,9 +22,9 @@ class MnemonicWordCountSelectSheet extends ConsumerWidget {
return false;
},
child: Container(
decoration: const BoxDecoration(
color: CFColors.white,
borderRadius: BorderRadius.vertical(
decoration: BoxDecoration(
color: Theme.of(context).extension<StackColors>()!.popupBG,
borderRadius: const BorderRadius.vertical(
top: Radius.circular(20),
),
),
@ -42,7 +42,9 @@ class MnemonicWordCountSelectSheet extends ConsumerWidget {
Center(
child: Container(
decoration: BoxDecoration(
color: CFColors.fieldGray,
color: Theme.of(context)
.extension<StackColors>()!
.textFieldDefaultBG,
borderRadius: BorderRadius.circular(
Constants.size.circularBorderRadius,
),
@ -62,7 +64,7 @@ class MnemonicWordCountSelectSheet extends ConsumerWidget {
children: [
Text(
"Phrase length",
style: STextStyles.pageTitleH2,
style: STextStyles.pageTitleH2(context),
textAlign: TextAlign.left,
),
const SizedBox(
@ -96,7 +98,9 @@ class MnemonicWordCountSelectSheet extends ConsumerWidget {
width: 20,
height: 20,
child: Radio(
activeColor: CFColors.link2,
activeColor: Theme.of(context)
.extension<StackColors>()!
.radioButtonIconEnabled,
value: lengthOptions[i],
groupValue: ref
.watch(mnemonicWordCountStateProvider
@ -118,9 +122,7 @@ class MnemonicWordCountSelectSheet extends ConsumerWidget {
),
Text(
"${lengthOptions[i]} words",
style: STextStyles.titleBold12.copyWith(
color: const Color(0xFF44464E),
),
style: STextStyles.titleBold12(context),
textAlign: TextAlign.left,
),
],

View file

@ -1,8 +1,8 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:stackwallet/providers/providers.dart';
import 'package:stackwallet/utilities/cfcolors.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/widgets/stack_dialog.dart';
class RestoreFailedDialog extends ConsumerStatefulWidget {
@ -45,14 +45,12 @@ class _RestoreFailedDialogState extends ConsumerState<RestoreFailedDialog> {
title: "Restore failed",
message: errorMessage,
rightButton: TextButton(
style: Theme.of(context).textButtonTheme.style?.copyWith(
backgroundColor: MaterialStateProperty.all<Color>(
CFColors.buttonGray,
),
),
style: Theme.of(context)
.extension<StackColors>()!
.getSecondaryEnabledButtonColor(context),
child: Text(
"Ok",
style: STextStyles.itemSubtitle12,
style: STextStyles.itemSubtitle12(context),
),
onPressed: () async {
ref

View file

@ -1,8 +1,8 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/cfcolors.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/widgets/stack_dialog.dart';
class RestoreSucceededDialog extends StatelessWidget {
@ -17,17 +17,15 @@ class RestoreSucceededDialog extends StatelessWidget {
Assets.svg.checkCircle,
width: 24,
height: 24,
color: CFColors.stackGreen,
color: Theme.of(context).extension<StackColors>()!.accentColorGreen,
),
rightButton: TextButton(
style: Theme.of(context).textButtonTheme.style?.copyWith(
backgroundColor: MaterialStateProperty.all<Color>(
CFColors.buttonGray,
),
),
style: Theme.of(context)
.extension<StackColors>()!
.getSecondaryEnabledButtonColor(context),
child: Text(
"Ok",
style: STextStyles.itemSubtitle12,
style: STextStyles.itemSubtitle12(context),
),
onPressed: () {
Navigator.of(context).pop();

View file

@ -1,8 +1,8 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/cfcolors.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/widgets/stack_dialog.dart';
class RestoringDialog extends StatefulWidget {
@ -59,22 +59,19 @@ class _RestoringDialogState extends State<RestoringDialog>
message: "This may take a while. Please do not exit this screen.",
icon: RotationTransition(
turns: _spinAnimation,
child: SvgPicture.asset(
Assets.svg.arrowRotate3,
width: 24,
height: 24,
color: CFColors.stackAccent,
),
child: SvgPicture.asset(Assets.svg.arrowRotate3,
width: 24,
height: 24,
color:
Theme.of(context).extension<StackColors>()!.accentColorDark),
),
rightButton: TextButton(
style: Theme.of(context).textButtonTheme.style?.copyWith(
backgroundColor: MaterialStateProperty.all<Color>(
CFColors.buttonGray,
),
),
style: Theme.of(context)
.extension<StackColors>()!
.getSecondaryEnabledButtonColor(context),
child: Text(
"Cancel",
style: STextStyles.itemSubtitle12,
style: STextStyles.itemSubtitle12(context),
),
onPressed: () async {
await onCancel.call();

View file

@ -6,9 +6,11 @@ class WordTable extends ConsumerWidget {
const WordTable({
Key? key,
required this.words,
required this.isDesktop,
}) : super(key: key);
final List<String> words;
final bool isDesktop;
static const wordsPerRow = 3;
static const wordsToShow = 9;
@ -24,18 +26,19 @@ class WordTable extends ConsumerWidget {
children: [
for (int i = 1; i <= rows; i++)
Padding(
padding: const EdgeInsets.symmetric(vertical: 5),
padding: EdgeInsets.symmetric(vertical: isDesktop ? 8 : 5),
child: Row(
children: [
for (int j = 1; j <= wordsPerRow; j++) ...[
if (j > 1)
const SizedBox(
width: 6,
SizedBox(
width: isDesktop ? 10 : 6,
),
Expanded(
child: WordTableItem(
number: ++index,
word: words[index - 1],
isDesktop: isDesktop,
),
),
],

View file

@ -1,19 +1,21 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:stackwallet/providers/providers.dart';
import 'package:stackwallet/utilities/cfcolors.dart';
import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
class WordTableItem extends ConsumerWidget {
const WordTableItem({
Key? key,
required this.number,
required this.word,
required this.isDesktop,
}) : super(key: key);
final int number;
final String word;
final bool isDesktop;
@override
Widget build(BuildContext context, WidgetRef ref) {
@ -22,15 +24,22 @@ class WordTableItem extends ConsumerWidget {
ref.watch(verifyMnemonicSelectedWordStateProvider.state).state;
return Container(
decoration: BoxDecoration(
color: selectedWord == word ? CFColors.selection : CFColors.white,
color: selectedWord == word
? Theme.of(context).extension<StackColors>()!.snackBarBackInfo
: Theme.of(context).extension<StackColors>()!.popupBG,
borderRadius: BorderRadius.circular(
Constants.size.circularBorderRadius,
),
),
child: MaterialButton(
splashColor: CFColors.splashLight,
splashColor: Theme.of(context).extension<StackColors>()!.highlight,
key: Key("coinSelectItemButtonKey_$word"),
padding: const EdgeInsets.all(12),
padding: isDesktop
? const EdgeInsets.symmetric(
vertical: 18,
horizontal: 12,
)
: const EdgeInsets.all(12),
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
shape: RoundedRectangleBorder(
borderRadius:
@ -45,7 +54,12 @@ class WordTableItem extends ConsumerWidget {
Text(
word,
textAlign: TextAlign.center,
style: STextStyles.baseXS,
style: isDesktop
? STextStyles.desktopTextExtraSmall(context).copyWith(
color:
Theme.of(context).extension<StackColors>()!.textDark,
)
: STextStyles.baseXS(context),
),
],
),

View file

@ -1,3 +1,4 @@
import 'dart:async';
import 'dart:math';
import 'package:flutter/material.dart';
@ -6,14 +7,19 @@ import 'package:stackwallet/notifications/show_flush_bar.dart';
import 'package:stackwallet/pages/add_wallet_views/new_wallet_recovery_phrase_view/new_wallet_recovery_phrase_view.dart';
import 'package:stackwallet/pages/add_wallet_views/verify_recovery_phrase_view/sub_widgets/word_table.dart';
import 'package:stackwallet/pages/home_view/home_view.dart';
import 'package:stackwallet/pages_desktop_specific/home/desktop_home_view.dart';
import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/exit_to_my_stack_button.dart';
import 'package:stackwallet/providers/providers.dart';
import 'package:stackwallet/services/coins/manager.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/cfcolors.dart';
import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/enums/flush_bar_type.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/utilities/util.dart';
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart';
import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart';
import 'package:tuple/tuple.dart';
class VerifyRecoveryPhraseView extends ConsumerStatefulWidget {
@ -39,11 +45,13 @@ class _VerifyRecoveryPhraseViewState
{
late Manager _manager;
late List<String> _mnemonic;
late final bool isDesktop;
@override
void initState() {
_manager = widget.manager;
_mnemonic = widget.mnemonic;
isDesktop = Util.isDesktop;
// WidgetsBinding.instance?.addObserver(this);
super.initState();
}
@ -75,6 +83,62 @@ class _VerifyRecoveryPhraseViewState
// }
// }
Future<void> _continue(bool isMatch) async {
if (isMatch) {
await ref.read(walletsServiceChangeNotifierProvider).setMnemonicVerified(
walletId: _manager.walletId,
);
ref
.read(walletsChangeNotifierProvider.notifier)
.addWallet(walletId: _manager.walletId, manager: _manager);
if (mounted) {
if (isDesktop) {
Navigator.of(context).popUntil(
ModalRoute.withName(
DesktopHomeView.routeName,
),
);
} else {
unawaited(
Navigator.of(context).pushNamedAndRemoveUntil(
HomeView.routeName,
(route) => false,
),
);
}
}
unawaited(showFloatingFlushBar(
type: FlushBarType.success,
message: "Correct! Your wallet is set up.",
iconAsset: Assets.svg.check,
context: context,
));
} else {
unawaited(showFloatingFlushBar(
type: FlushBarType.warning,
message: "Incorrect. Please try again.",
iconAsset: Assets.svg.circleX,
context: context,
));
final int next = Random().nextInt(_mnemonic.length);
ref
.read(verifyMnemonicWordIndexStateProvider.state)
.update((state) => next);
ref
.read(verifyMnemonicCorrectWordStateProvider.state)
.update((state) => _mnemonic[next]);
ref
.read(verifyMnemonicSelectedWordStateProvider.state)
.update((state) => "");
}
}
Tuple2<List<String>, String> randomize(
List<String> mnemonic, int chosenIndex, int wordsToShow) {
final List<String> remaining = [];
@ -113,12 +177,12 @@ class _VerifyRecoveryPhraseViewState
return false;
}
// Future<void> delete() async {
// await ref
// .read(walletsServiceChangeNotifierProvider)
// .deleteWallet(_manager.walletName, false);
// await _manager.exitCurrentWallet();
// }
Future<void> delete() async {
await ref
.read(walletsServiceChangeNotifierProvider)
.deleteWallet(_manager.walletName, false);
await _manager.exitCurrentWallet();
}
@override
Widget build(BuildContext context) {
@ -128,51 +192,80 @@ class _VerifyRecoveryPhraseViewState
return WillPopScope(
onWillPop: onWillPop,
child: Scaffold(
appBar: AppBar(
leading: AppBarBackButton(
onPressed: () async {
// await delete();
Navigator.of(context).popUntil(
ModalRoute.withName(
// NewWalletRecoveryPhraseWarningView.routeName,
NewWalletRecoveryPhraseView.routeName,
child: MasterScaffold(
isDesktop: isDesktop,
appBar: isDesktop
? DesktopAppBar(
isCompactHeight: false,
leading: AppBarBackButton(
onPressed: () async {
Navigator.of(context).popUntil(
ModalRoute.withName(
NewWalletRecoveryPhraseView.routeName,
),
);
},
),
);
},
),
),
body: Container(
color: CFColors.almostWhite,
trailing: ExitToMyStackButton(
onPressed: () async {
await delete();
if (mounted) {
Navigator.of(context).popUntil(
ModalRoute.withName(DesktopHomeView.routeName),
);
}
},
),
)
: AppBar(
leading: AppBarBackButton(
onPressed: () async {
Navigator.of(context).popUntil(
ModalRoute.withName(
NewWalletRecoveryPhraseView.routeName,
),
);
},
),
),
body: SizedBox(
width: isDesktop ? 410 : null,
child: Padding(
padding: const EdgeInsets.all(16),
padding:
isDesktop ? const EdgeInsets.all(0) : const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const SizedBox(
height: 4,
SizedBox(
height: isDesktop ? 24 : 4,
),
Text(
"Verify recovery phrase",
textAlign: TextAlign.center,
style: STextStyles.label.copyWith(
fontSize: 12,
),
style: isDesktop
? STextStyles.desktopH2(context)
: STextStyles.label(context).copyWith(
fontSize: 12,
),
),
const SizedBox(
height: 4,
SizedBox(
height: isDesktop ? 16 : 4,
),
Text(
"Tap word number ",
isDesktop ? "Select word number" : "Tap word number ",
textAlign: TextAlign.center,
style: STextStyles.pageTitleH1,
style: isDesktop
? STextStyles.desktopSubtitleH1(context)
: STextStyles.pageTitleH1(context),
),
const SizedBox(
height: 12,
SizedBox(
height: isDesktop ? 16 : 12,
),
Container(
decoration: BoxDecoration(
color: CFColors.fieldGray,
color: Theme.of(context)
.extension<StackColors>()!
.textFieldDefaultBG,
borderRadius: BorderRadius.circular(
Constants.size.circularBorderRadius),
),
@ -184,7 +277,7 @@ class _VerifyRecoveryPhraseViewState
child: Text(
"${correctIndex + 1}",
textAlign: TextAlign.center,
style: STextStyles.subtitle.copyWith(
style: STextStyles.subtitle(context).copyWith(
fontWeight: FontWeight.w600,
fontSize: 32,
letterSpacing: 0.25,
@ -192,10 +285,19 @@ class _VerifyRecoveryPhraseViewState
),
),
),
if (isDesktop)
const SizedBox(
height: 40,
),
WordTable(
words: randomize(_mnemonic, correctIndex, 9).item1,
isDesktop: isDesktop,
),
const Spacer(),
if (!isDesktop) const Spacer(),
if (isDesktop)
const SizedBox(
height: 40,
),
Row(
children: [
Expanded(
@ -210,92 +312,37 @@ class _VerifyRecoveryPhraseViewState
verifyMnemonicCorrectWordStateProvider.state)
.state;
return TextButton(
onPressed: selectedWord.isNotEmpty
? () async {
if (correctWord == selectedWord) {
await ref
.read(
walletsServiceChangeNotifierProvider)
.setMnemonicVerified(
walletId: _manager.walletId,
);
ref
.read(walletsChangeNotifierProvider
.notifier)
.addWallet(
walletId: _manager.walletId,
manager: _manager);
if (mounted) {
Navigator.of(context)
.pushNamedAndRemoveUntil(
HomeView.routeName,
(route) => false);
}
showFloatingFlushBar(
type: FlushBarType.success,
message:
"Correct! Your wallet is set up.",
iconAsset: Assets.svg.check,
context: context,
);
} else {
showFloatingFlushBar(
type: FlushBarType.warning,
message: "Incorrect. Please try again.",
iconAsset: Assets.svg.circleX,
context: context,
);
final int next =
Random().nextInt(_mnemonic.length);
ref
.read(
verifyMnemonicWordIndexStateProvider
.state)
.update((state) => next);
ref
.read(
verifyMnemonicCorrectWordStateProvider
.state)
.update((state) => _mnemonic[next]);
ref
.read(
verifyMnemonicSelectedWordStateProvider
.state)
.update((state) => "");
return ConstrainedBox(
constraints: BoxConstraints(
minHeight: isDesktop ? 70 : 0,
),
child: TextButton(
onPressed: selectedWord.isNotEmpty
? () async {
await _continue(
correctWord == selectedWord);
}
}
: null,
style: selectedWord.isNotEmpty
? Theme.of(context)
.textButtonTheme
.style
?.copyWith(
backgroundColor:
MaterialStateProperty.all<Color>(
CFColors.stackAccent,
),
: null,
style: selectedWord.isNotEmpty
? Theme.of(context)
.extension<StackColors>()!
.getPrimaryEnabledButtonColor(context)
: Theme.of(context)
.extension<StackColors>()!
.getPrimaryDisabledButtonColor(context),
child: isDesktop
? Text(
"Verify",
style: selectedWord.isNotEmpty
? STextStyles.desktopButtonEnabled(
context)
: STextStyles.desktopButtonDisabled(
context),
)
: Theme.of(context)
.textButtonTheme
.style
?.copyWith(
backgroundColor:
MaterialStateProperty.all<Color>(
CFColors.stackAccent.withOpacity(
0.25,
),
),
: Text(
"Continue",
style: STextStyles.button(context),
),
child: Text(
"Continue",
style: STextStyles.button,
),
);
},

View file

@ -9,10 +9,10 @@ import 'package:stackwallet/providers/global/address_book_service_provider.dart'
import 'package:stackwallet/providers/providers.dart';
import 'package:stackwallet/providers/ui/address_book_providers/address_book_filter_provider.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/cfcolors.dart';
import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/widgets/address_book_card.dart';
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
import 'package:stackwallet/widgets/icon_widgets/x_icon.dart';
@ -102,7 +102,7 @@ class _AddressBookViewState extends ConsumerState<AddressBookView> {
addressBookServiceProvider.select((value) => value.addressBookEntries));
return Scaffold(
backgroundColor: CFColors.almostWhite,
backgroundColor: Theme.of(context).extension<StackColors>()!.background,
appBar: AppBar(
leading: AppBarBackButton(
onPressed: () {
@ -111,7 +111,7 @@ class _AddressBookViewState extends ConsumerState<AddressBookView> {
),
title: Text(
"Address book",
style: STextStyles.navBarTitle,
style: STextStyles.navBarTitle(context),
),
actions: [
Padding(
@ -126,10 +126,12 @@ class _AddressBookViewState extends ConsumerState<AddressBookView> {
key: const Key("addressBookFilterViewButton"),
size: 36,
shadows: const [],
color: CFColors.almostWhite,
color: Theme.of(context).extension<StackColors>()!.background,
icon: SvgPicture.asset(
Assets.svg.filter,
color: CFColors.stackAccent,
color: Theme.of(context)
.extension<StackColors>()!
.accentColorDark,
width: 20,
height: 20,
),
@ -153,10 +155,12 @@ class _AddressBookViewState extends ConsumerState<AddressBookView> {
key: const Key("addressBookAddNewContactViewButton"),
size: 36,
shadows: const [],
color: CFColors.almostWhite,
color: Theme.of(context).extension<StackColors>()!.background,
icon: SvgPicture.asset(
Assets.svg.plus,
color: CFColors.stackAccent,
color: Theme.of(context)
.extension<StackColors>()!
.accentColorDark,
width: 20,
height: 20,
),
@ -201,10 +205,11 @@ class _AddressBookViewState extends ConsumerState<AddressBookView> {
_searchTerm = value;
});
},
style: STextStyles.field,
style: STextStyles.field(context),
decoration: standardInputDecoration(
"Search",
_searchFocusNode,
context,
).copyWith(
prefixIcon: Padding(
padding: const EdgeInsets.symmetric(
@ -244,7 +249,7 @@ class _AddressBookViewState extends ConsumerState<AddressBookView> {
),
Text(
"Favorites",
style: STextStyles.smallMed12,
style: STextStyles.smallMed12(context),
),
const SizedBox(
height: 12,
@ -297,7 +302,7 @@ class _AddressBookViewState extends ConsumerState<AddressBookView> {
child: Center(
child: Text(
"Your favorite contacts will appear here",
style: STextStyles.itemSubtitle,
style: STextStyles.itemSubtitle(context),
),
),
);
@ -310,7 +315,7 @@ class _AddressBookViewState extends ConsumerState<AddressBookView> {
),
Text(
"All contacts",
style: STextStyles.smallMed12,
style: STextStyles.smallMed12(context),
),
const SizedBox(
height: 12,
@ -360,7 +365,7 @@ class _AddressBookViewState extends ConsumerState<AddressBookView> {
child: Center(
child: Text(
"Your contacts will appear here",
style: STextStyles.itemSubtitle,
style: STextStyles.itemSubtitle(context),
),
),
);

View file

@ -11,10 +11,10 @@ import 'package:stackwallet/providers/ui/address_book_providers/contact_name_is_
import 'package:stackwallet/providers/ui/address_book_providers/valid_contact_state_provider.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/barcode_scanner_interface.dart';
import 'package:stackwallet/utilities/cfcolors.dart';
import 'package:stackwallet/utilities/clipboard_interface.dart';
import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
import 'package:stackwallet/widgets/emoji_select_sheet.dart';
import 'package:stackwallet/widgets/icon_widgets/x_icon.dart';
@ -93,7 +93,7 @@ class _AddAddressBookEntryViewState
debugPrint("BUILD: $runtimeType");
return Scaffold(
backgroundColor: CFColors.almostWhite,
backgroundColor: Theme.of(context).extension<StackColors>()!.background,
appBar: AppBar(
leading: AppBarBackButton(
onPressed: () async {
@ -108,7 +108,7 @@ class _AddAddressBookEntryViewState
),
title: Text(
"New contact",
style: STextStyles.navBarTitle,
style: STextStyles.navBarTitle(context),
),
actions: [
Padding(
@ -123,10 +123,16 @@ class _AddAddressBookEntryViewState
key: const Key("addAddressBookEntryFavoriteButtonKey"),
size: 36,
shadows: const [],
color: CFColors.almostWhite,
color: Theme.of(context).extension<StackColors>()!.background,
icon: SvgPicture.asset(
Assets.svg.star,
color: _isFavorite ? CFColors.link2 : CFColors.buttonGray,
color: _isFavorite
? Theme.of(context)
.extension<StackColors>()!
.favoriteStarActive
: Theme.of(context)
.extension<StackColors>()!
.favoriteStarInactive,
width: 20,
height: 20,
),
@ -198,7 +204,9 @@ class _AddAddressBookEntryViewState
width: 48,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(24),
color: CFColors.textFieldActive,
color: Theme.of(context)
.extension<StackColors>()!
.textFieldActiveBG,
),
child: Center(
child: _selectedEmoji == null
@ -209,7 +217,8 @@ class _AddAddressBookEntryViewState
)
: Text(
_selectedEmoji!.char,
style: STextStyles.pageTitleH1,
style:
STextStyles.pageTitleH1(context),
),
),
),
@ -219,20 +228,25 @@ class _AddAddressBookEntryViewState
height: 14,
width: 14,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(14),
color: CFColors.stackAccent,
),
borderRadius: BorderRadius.circular(14),
color: Theme.of(context)
.extension<StackColors>()!
.accentColorDark),
child: Center(
child: _selectedEmoji == null
? SvgPicture.asset(
Assets.svg.plus,
color: CFColors.white,
color: Theme.of(context)
.extension<StackColors>()!
.textWhite,
width: 12,
height: 12,
)
: SvgPicture.asset(
Assets.svg.thickX,
color: CFColors.white,
color: Theme.of(context)
.extension<StackColors>()!
.textWhite,
width: 8,
height: 8,
),
@ -253,10 +267,11 @@ class _AddAddressBookEntryViewState
child: TextField(
controller: nameController,
focusNode: nameFocusNode,
style: STextStyles.field,
style: STextStyles.field(context),
decoration: standardInputDecoration(
"Enter contact name",
nameFocusNode,
context,
).copyWith(
suffixIcon: ref
.read(contactNameIsNotEmptyStateProvider
@ -303,7 +318,7 @@ class _AddAddressBookEntryViewState
),
Text(
"Address ${i + 1}",
style: STextStyles.smallMed12,
style: STextStyles.smallMed12(context),
),
const SizedBox(
height: 8,
@ -325,7 +340,7 @@ class _AddAddressBookEntryViewState
},
child: Text(
"+ Add another address",
style: STextStyles.largeMedium14,
style: STextStyles.largeMedium14(context),
),
),
const SizedBox(
@ -336,17 +351,15 @@ class _AddAddressBookEntryViewState
children: [
Expanded(
child: TextButton(
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all<Color>(
CFColors.buttonGray,
),
),
style: Theme.of(context)
.extension<StackColors>()!
.getSecondaryEnabledButtonColor(context),
child: Text(
"Cancel",
style: STextStyles.button.copyWith(
color: CFColors.stackAccent,
),
style: STextStyles.button(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.accentColorDark),
),
onPressed: () async {
if (FocusScope.of(context).hasFocus) {
@ -380,13 +393,14 @@ class _AddAddressBookEntryViewState
validForms && nameExists;
return TextButton(
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all<Color>(
shouldEnableSave
? CFColors.stackAccent
: CFColors.disabledButton,
)),
style: shouldEnableSave
? Theme.of(context)
.extension<StackColors>()!
.getPrimaryEnabledButtonColor(context)
: Theme.of(context)
.extension<StackColors>()!
.getPrimaryDisabledButtonColor(
context),
onPressed: shouldEnableSave
? () async {
if (FocusScope.of(context).hasFocus) {
@ -424,7 +438,7 @@ class _AddAddressBookEntryViewState
: null,
child: Text(
"Save",
style: STextStyles.button,
style: STextStyles.button(context),
),
);
},

View file

@ -9,9 +9,9 @@ import 'package:stackwallet/providers/ui/address_book_providers/address_entry_da
import 'package:stackwallet/providers/ui/address_book_providers/valid_contact_state_provider.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/barcode_scanner_interface.dart';
import 'package:stackwallet/utilities/cfcolors.dart';
import 'package:stackwallet/utilities/clipboard_interface.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
class AddNewContactAddressView extends ConsumerStatefulWidget {
@ -56,7 +56,7 @@ class _AddNewContactAddressViewState
.select((value) => value.getContactById(contactId)));
return Scaffold(
backgroundColor: CFColors.almostWhite,
backgroundColor: Theme.of(context).extension<StackColors>()!.background,
appBar: AppBar(
leading: AppBarBackButton(
onPressed: () async {
@ -71,7 +71,7 @@ class _AddNewContactAddressViewState
),
title: Text(
"Add new address",
style: STextStyles.navBarTitle,
style: STextStyles.navBarTitle(context),
),
),
body: LayoutBuilder(
@ -99,7 +99,9 @@ class _AddNewContactAddressViewState
width: 48,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(24),
color: CFColors.textFieldActive,
color: Theme.of(context)
.extension<StackColors>()!
.textFieldActiveBG,
),
child: Center(
child: contact.emojiChar == null
@ -110,7 +112,7 @@ class _AddNewContactAddressViewState
)
: Text(
contact.emojiChar!,
style: STextStyles.pageTitleH1,
style: STextStyles.pageTitleH1(context),
),
),
),
@ -122,7 +124,7 @@ class _AddNewContactAddressViewState
fit: BoxFit.scaleDown,
child: Text(
contact.name,
style: STextStyles.pageTitleH2,
style: STextStyles.pageTitleH2(context),
),
),
),
@ -144,17 +146,15 @@ class _AddNewContactAddressViewState
children: [
Expanded(
child: TextButton(
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all<Color>(
CFColors.buttonGray,
),
),
style: Theme.of(context)
.extension<StackColors>()!
.getSecondaryEnabledButtonColor(context),
child: Text(
"Cancel",
style: STextStyles.button.copyWith(
color: CFColors.stackAccent,
),
style: STextStyles.button(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.accentColorDark),
),
onPressed: () async {
if (FocusScope.of(context).hasFocus) {
@ -178,14 +178,15 @@ class _AddNewContactAddressViewState
ref.watch(validContactStateProvider([0]));
return TextButton(
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all<Color>(
shouldEnableSave
? CFColors.stackAccent
: CFColors.disabledButton,
),
),
style: shouldEnableSave
? Theme.of(context)
.extension<StackColors>()!
.getPrimaryEnabledButtonColor(
context)
: Theme.of(context)
.extension<StackColors>()!
.getPrimaryDisabledButtonColor(
context),
onPressed: shouldEnableSave
? () async {
if (FocusScope.of(context)
@ -222,7 +223,7 @@ class _AddNewContactAddressViewState
: null,
child: Text(
"Save",
style: STextStyles.button,
style: STextStyles.button(context),
),
);
},

View file

@ -2,9 +2,9 @@ import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:stackwallet/providers/global/prefs_provider.dart';
import 'package:stackwallet/providers/ui/address_book_providers/address_book_filter_provider.dart';
import 'package:stackwallet/utilities/cfcolors.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
import 'package:stackwallet/widgets/rounded_white_container.dart';
@ -42,9 +42,9 @@ class _AddressBookFilterViewState extends ConsumerState<AddressBookFilterView> {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: CFColors.almostWhite,
backgroundColor: Theme.of(context).extension<StackColors>()!.background,
appBar: AppBar(
backgroundColor: CFColors.almostWhite,
backgroundColor: Theme.of(context).extension<StackColors>()!.background,
leading: AppBarBackButton(
onPressed: () async {
Navigator.of(context).pop();
@ -52,7 +52,7 @@ class _AddressBookFilterViewState extends ConsumerState<AddressBookFilterView> {
),
title: Text(
"Filter addresses",
style: STextStyles.navBarTitle,
style: STextStyles.navBarTitle(context),
),
),
body: Padding(
@ -72,7 +72,7 @@ class _AddressBookFilterViewState extends ConsumerState<AddressBookFilterView> {
RoundedWhiteContainer(
child: Text(
"Only selected cryptocurrency addresses will be displayed.",
style: STextStyles.itemSubtitle,
style: STextStyles.itemSubtitle(context),
),
),
const SizedBox(
@ -80,7 +80,7 @@ class _AddressBookFilterViewState extends ConsumerState<AddressBookFilterView> {
),
Text(
"Select cryptocurrency",
style: STextStyles.smallMed12,
style: STextStyles.smallMed12(context),
),
const SizedBox(
height: 12,
@ -154,7 +154,8 @@ class _AddressBookFilterViewState extends ConsumerState<AddressBookFilterView> {
Text(
coin.prettyName,
style:
STextStyles.largeMedium14,
STextStyles.largeMedium14(
context),
),
const SizedBox(
height: 2,
@ -162,7 +163,8 @@ class _AddressBookFilterViewState extends ConsumerState<AddressBookFilterView> {
Text(
coin.ticker,
style:
STextStyles.itemSubtitle,
STextStyles.itemSubtitle(
context),
),
],
)

View file

@ -3,10 +3,10 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/svg.dart';
import 'package:stackwallet/providers/global/prefs_provider.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/cfcolors.dart';
import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
class CoinSelectSheet extends StatelessWidget {
const CoinSelectSheet({Key? key}) : super(key: key);
@ -17,9 +17,9 @@ class CoinSelectSheet extends StatelessWidget {
var coins_ = [...Coin.values];
coins_.remove(Coin.firoTestNet);
return Container(
decoration: const BoxDecoration(
color: CFColors.white,
borderRadius: BorderRadius.vertical(
decoration: BoxDecoration(
color: Theme.of(context).extension<StackColors>()!.popupBG,
borderRadius: const BorderRadius.vertical(
top: Radius.circular(20),
),
),
@ -39,7 +39,9 @@ class CoinSelectSheet extends StatelessWidget {
Center(
child: Container(
decoration: BoxDecoration(
color: CFColors.fieldGray,
color: Theme.of(context)
.extension<StackColors>()!
.textFieldDefaultBG,
borderRadius: BorderRadius.circular(
Constants.size.circularBorderRadius,
),
@ -53,7 +55,7 @@ class CoinSelectSheet extends StatelessWidget {
),
Text(
"Select address cryptocurrency",
style: STextStyles.pageTitleH2,
style: STextStyles.pageTitleH2(context),
textAlign: TextAlign.left,
),
const SizedBox(
@ -77,7 +79,7 @@ class CoinSelectSheet extends StatelessWidget {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 4),
child: RawMaterialButton(
// splashColor: CFColors.splashLight,
// splashColor: Theme.of(context).extension<StackColors>()!.highlight,
onPressed: () {
Navigator.of(context).pop(coin);
},
@ -95,7 +97,7 @@ class CoinSelectSheet extends StatelessWidget {
),
Text(
coin.prettyName,
style: STextStyles.itemSubtitle12,
style: STextStyles.itemSubtitle12(context),
),
],
),

View file

@ -13,11 +13,11 @@ import 'package:stackwallet/providers/providers.dart';
import 'package:stackwallet/providers/ui/address_book_providers/address_entry_data_provider.dart';
import 'package:stackwallet/services/coins/manager.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/cfcolors.dart';
import 'package:stackwallet/utilities/clipboard_interface.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
import 'package:stackwallet/utilities/enums/flush_bar_type.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
import 'package:stackwallet/widgets/custom_buttons/blue_text_button.dart';
import 'package:stackwallet/widgets/loading_indicator.dart';
@ -105,7 +105,7 @@ class _ContactDetailsViewState extends ConsumerState<ContactDetailsView> {
.select((value) => value.getContactById(_contactId)));
return Scaffold(
backgroundColor: CFColors.almostWhite,
backgroundColor: Theme.of(context).extension<StackColors>()!.background,
appBar: AppBar(
leading: AppBarBackButton(
onPressed: () {
@ -114,7 +114,7 @@ class _ContactDetailsViewState extends ConsumerState<ContactDetailsView> {
),
title: Text(
"Contact details",
style: STextStyles.navBarTitle,
style: STextStyles.navBarTitle(context),
),
actions: [
Padding(
@ -129,12 +129,16 @@ class _ContactDetailsViewState extends ConsumerState<ContactDetailsView> {
key: const Key("contactDetails"),
size: 36,
shadows: const [],
color: CFColors.almostWhite,
color: Theme.of(context).extension<StackColors>()!.background,
icon: SvgPicture.asset(
Assets.svg.star,
color: _contact.isFavorite
? CFColors.link2
: CFColors.buttonGray,
? Theme.of(context)
.extension<StackColors>()!
.favoriteStarActive
: Theme.of(context)
.extension<StackColors>()!
.favoriteStarInactive,
width: 20,
height: 20,
),
@ -160,10 +164,12 @@ class _ContactDetailsViewState extends ConsumerState<ContactDetailsView> {
key: const Key("contactDetailsViewDeleteContactButtonKey"),
size: 36,
shadows: const [],
color: CFColors.almostWhite,
color: Theme.of(context).extension<StackColors>()!.background,
icon: SvgPicture.asset(
Assets.svg.trash,
color: CFColors.stackAccent,
color: Theme.of(context)
.extension<StackColors>()!
.accentColorDark,
width: 20,
height: 20,
),
@ -177,16 +183,11 @@ class _ContactDetailsViewState extends ConsumerState<ContactDetailsView> {
message: "Contact will be deleted permanently!",
leftButton: TextButton(
style: Theme.of(context)
.textButtonTheme
.style
?.copyWith(
backgroundColor: MaterialStateProperty.all<Color>(
CFColors.buttonGray,
),
),
.extension<StackColors>()!
.getSecondaryEnabledButtonColor(context),
child: Text(
"Cancel",
style: STextStyles.itemSubtitle12,
style: STextStyles.itemSubtitle12(context),
),
onPressed: () {
Navigator.of(context).pop();
@ -194,16 +195,11 @@ class _ContactDetailsViewState extends ConsumerState<ContactDetailsView> {
),
rightButton: TextButton(
style: Theme.of(context)
.textButtonTheme
.style
?.copyWith(
backgroundColor: MaterialStateProperty.all<Color>(
CFColors.stackAccent,
),
),
.extension<StackColors>()!
.getPrimaryEnabledButtonColor(context),
child: Text(
"Delete",
style: STextStyles.button,
style: STextStyles.button(context),
),
onPressed: () {
ref
@ -246,7 +242,9 @@ class _ContactDetailsViewState extends ConsumerState<ContactDetailsView> {
width: 48,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(24),
color: CFColors.textFieldActive,
color: Theme.of(context)
.extension<StackColors>()!
.textFieldActiveBG,
),
child: Center(
child: _contact.emojiChar == null
@ -257,7 +255,7 @@ class _ContactDetailsViewState extends ConsumerState<ContactDetailsView> {
)
: Text(
_contact.emojiChar!,
style: STextStyles.pageTitleH1,
style: STextStyles.pageTitleH1(context),
),
),
),
@ -269,7 +267,7 @@ class _ContactDetailsViewState extends ConsumerState<ContactDetailsView> {
child: Text(
_contact.name,
textAlign: TextAlign.left,
style: STextStyles.pageTitleH2,
style: STextStyles.pageTitleH2(context),
),
),
const Spacer(),
@ -280,29 +278,29 @@ class _ContactDetailsViewState extends ConsumerState<ContactDetailsView> {
arguments: _contact.id,
);
},
style: ButtonStyle(
minimumSize:
MaterialStateProperty.all<Size>(const Size(46, 32)),
backgroundColor: MaterialStateProperty.all(
CFColors.buttonGray,
),
),
style: Theme.of(context)
.extension<StackColors>()!
.getSecondaryEnabledButtonColor(context)!
.copyWith(
minimumSize: MaterialStateProperty.all<Size>(
const Size(46, 32)),
),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 12),
child: Row(
children: [
SvgPicture.asset(
Assets.svg.pencil,
width: 10,
height: 10,
color: CFColors.stackAccent,
),
SvgPicture.asset(Assets.svg.pencil,
width: 10,
height: 10,
color: Theme.of(context)
.extension<StackColors>()!
.accentColorDark),
const SizedBox(
width: 4,
),
Text(
"Edit",
style: STextStyles.buttonSmall,
style: STextStyles.buttonSmall(context),
),
],
),
@ -318,7 +316,7 @@ class _ContactDetailsViewState extends ConsumerState<ContactDetailsView> {
children: [
Text(
"Addresses",
style: STextStyles.itemSubtitle,
style: STextStyles.itemSubtitle(context),
),
BlueTextButton(
text: "Add new",
@ -356,7 +354,8 @@ class _ContactDetailsViewState extends ConsumerState<ContactDetailsView> {
children: [
Text(
"${e.label} (${e.coin.ticker})",
style: STextStyles.itemSubtitle12,
style:
STextStyles.itemSubtitle12(context),
),
const SizedBox(
height: 2,
@ -365,8 +364,8 @@ class _ContactDetailsViewState extends ConsumerState<ContactDetailsView> {
fit: BoxFit.scaleDown,
child: Text(
e.address,
style:
STextStyles.itemSubtitle.copyWith(
style: STextStyles.itemSubtitle(context)
.copyWith(
fontSize: 8,
),
),
@ -391,14 +390,16 @@ class _ContactDetailsViewState extends ConsumerState<ContactDetailsView> {
);
},
child: RoundedContainer(
color: CFColors.fieldGray,
color: Theme.of(context)
.extension<StackColors>()!
.textFieldDefaultBG,
padding: const EdgeInsets.all(4),
child: SvgPicture.asset(
Assets.svg.pencil,
width: 12,
height: 12,
color: CFColors.stackAccent,
),
child: SvgPicture.asset(Assets.svg.pencil,
width: 12,
height: 12,
color: Theme.of(context)
.extension<StackColors>()!
.accentColorDark),
),
),
const SizedBox(
@ -417,14 +418,16 @@ class _ContactDetailsViewState extends ConsumerState<ContactDetailsView> {
);
},
child: RoundedContainer(
color: CFColors.fieldGray,
color: Theme.of(context)
.extension<StackColors>()!
.textFieldDefaultBG,
padding: const EdgeInsets.all(4),
child: SvgPicture.asset(
Assets.svg.copy,
width: 12,
height: 12,
color: CFColors.stackAccent,
),
child: SvgPicture.asset(Assets.svg.copy,
width: 12,
height: 12,
color: Theme.of(context)
.extension<StackColors>()!
.accentColorDark),
),
),
],
@ -439,7 +442,7 @@ class _ContactDetailsViewState extends ConsumerState<ContactDetailsView> {
),
Text(
"Transaction history",
style: STextStyles.itemSubtitle,
style: STextStyles.itemSubtitle(context),
),
const SizedBox(
height: 12,
@ -475,7 +478,7 @@ class _ContactDetailsViewState extends ConsumerState<ContactDetailsView> {
child: Center(
child: Text(
"No transactions found",
style: STextStyles.itemSubtitle,
style: STextStyles.itemSubtitle(context),
),
),
);

View file

@ -10,11 +10,11 @@ import 'package:stackwallet/providers/exchange/exchange_flow_is_active_state_pro
import 'package:stackwallet/providers/global/address_book_service_provider.dart';
import 'package:stackwallet/providers/providers.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/cfcolors.dart';
import 'package:stackwallet/utilities/clipboard_interface.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
import 'package:stackwallet/utilities/enums/flush_bar_type.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/widgets/rounded_container.dart';
import 'package:stackwallet/widgets/rounded_white_container.dart';
import 'package:tuple/tuple.dart';
@ -71,7 +71,8 @@ class ContactPopUp extends ConsumerWidget {
),
child: Container(
decoration: BoxDecoration(
color: CFColors.white,
color:
Theme.of(context).extension<StackColors>()!.popupBG,
borderRadius: BorderRadius.circular(
20,
),
@ -98,13 +99,15 @@ class ContactPopUp extends ConsumerWidget {
width: 32,
height: 32,
decoration: BoxDecoration(
color: CFColors.contactIconBackground,
color: Theme.of(context)
.extension<StackColors>()!
.textFieldDefaultBG,
borderRadius: BorderRadius.circular(32),
),
child: contact.id == "default"
? Center(
child: SvgPicture.asset(
Assets.svg.stackIcon,
Assets.svg.stackIcon(context),
width: 20,
),
)
@ -126,7 +129,8 @@ class ContactPopUp extends ConsumerWidget {
Expanded(
child: Text(
contact.name,
style: STextStyles.itemSubtitle12,
style:
STextStyles.itemSubtitle12(context),
),
),
if (contact.id != "default")
@ -138,20 +142,21 @@ class ContactPopUp extends ConsumerWidget {
arguments: contact.id,
);
},
style: ButtonStyle(
minimumSize:
MaterialStateProperty.all<Size>(
const Size(46, 32)),
backgroundColor:
MaterialStateProperty.all(
CFColors.buttonGray,
),
),
style: Theme.of(context)
.extension<StackColors>()!
.getSecondaryEnabledButtonColor(
context)!
.copyWith(
minimumSize:
MaterialStateProperty.all<
Size>(const Size(46, 32)),
),
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 18),
child: Text("Details",
style: STextStyles.buttonSmall),
style: STextStyles.buttonSmall(
context)),
),
),
],
@ -162,7 +167,9 @@ class ContactPopUp extends ConsumerWidget {
),
Container(
height: 1,
color: CFColors.almostWhite,
color: Theme.of(context)
.extension<StackColors>()!
.background,
),
if (addresses.isEmpty)
Padding(
@ -172,7 +179,8 @@ class ContactPopUp extends ConsumerWidget {
child: Center(
child: Text(
"No ${active[0].coin.prettyName} addresses found",
style: STextStyles.itemSubtitle,
style:
STextStyles.itemSubtitle(context),
),
),
),
@ -212,20 +220,23 @@ class ContactPopUp extends ConsumerWidget {
Text(
e.other!,
style:
STextStyles.itemSubtitle12,
STextStyles.itemSubtitle12(
context),
),
if (contact.id != "default")
Text(
"${e.label} (${e.coin.ticker})",
style:
STextStyles.itemSubtitle12,
STextStyles.itemSubtitle12(
context),
),
const SizedBox(
height: 2,
),
Text(
e.address,
style: STextStyles.itemSubtitle
style: STextStyles.itemSubtitle(
context)
.copyWith(
fontSize: 8,
),
@ -254,14 +265,17 @@ class ContactPopUp extends ConsumerWidget {
);
},
child: RoundedContainer(
color: CFColors.fieldGray,
color: Theme.of(context)
.extension<StackColors>()!
.textFieldDefaultBG,
padding: const EdgeInsets.all(4),
child: SvgPicture.asset(
Assets.svg.copy,
width: 12,
height: 12,
color: CFColors.stackAccent,
),
Assets.svg.copy,
width: 12,
height: 12,
color: Theme.of(context)
.extension<StackColors>()!
.accentColorDark),
),
),
],
@ -304,15 +318,20 @@ class ContactPopUp extends ConsumerWidget {
}
},
child: RoundedContainer(
color: CFColors.fieldGray,
color: Theme.of(context)
.extension<StackColors>()!
.textFieldDefaultBG,
padding:
const EdgeInsets.all(4),
child: SvgPicture.asset(
Assets.svg.circleArrowUpRight,
width: 12,
height: 12,
color: CFColors.stackAccent,
),
Assets
.svg.circleArrowUpRight,
width: 12,
height: 12,
color: Theme.of(context)
.extension<
StackColors>()!
.accentColorDark),
),
),
],

View file

@ -9,9 +9,9 @@ import 'package:stackwallet/providers/ui/address_book_providers/address_entry_da
import 'package:stackwallet/providers/ui/address_book_providers/valid_contact_state_provider.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/barcode_scanner_interface.dart';
import 'package:stackwallet/utilities/cfcolors.dart';
import 'package:stackwallet/utilities/clipboard_interface.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
class EditContactAddressView extends ConsumerStatefulWidget {
@ -60,7 +60,7 @@ class _EditContactAddressViewState
.select((value) => value.getContactById(contactId)));
return Scaffold(
backgroundColor: CFColors.almostWhite,
backgroundColor: Theme.of(context).extension<StackColors>()!.background,
appBar: AppBar(
leading: AppBarBackButton(
onPressed: () async {
@ -75,7 +75,7 @@ class _EditContactAddressViewState
),
title: Text(
"Edit address",
style: STextStyles.navBarTitle,
style: STextStyles.navBarTitle(context),
),
),
body: LayoutBuilder(
@ -103,7 +103,9 @@ class _EditContactAddressViewState
width: 48,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(24),
color: CFColors.textFieldActive,
color: Theme.of(context)
.extension<StackColors>()!
.textFieldActiveBG,
),
child: Center(
child: contact.emojiChar == null
@ -114,7 +116,7 @@ class _EditContactAddressViewState
)
: Text(
contact.emojiChar!,
style: STextStyles.pageTitleH1,
style: STextStyles.pageTitleH1(context),
),
),
),
@ -126,7 +128,7 @@ class _EditContactAddressViewState
fit: BoxFit.scaleDown,
child: Text(
contact.name,
style: STextStyles.pageTitleH2,
style: STextStyles.pageTitleH2(context),
),
),
),
@ -168,7 +170,7 @@ class _EditContactAddressViewState
},
child: Text(
"Delete address",
style: STextStyles.link,
style: STextStyles.link(context),
),
),
const Spacer(),
@ -179,17 +181,15 @@ class _EditContactAddressViewState
children: [
Expanded(
child: TextButton(
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all<Color>(
CFColors.buttonGray,
),
),
style: Theme.of(context)
.extension<StackColors>()!
.getSecondaryEnabledButtonColor(context),
child: Text(
"Cancel",
style: STextStyles.button.copyWith(
color: CFColors.stackAccent,
),
style: STextStyles.button(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.accentColorDark),
),
onPressed: () async {
if (FocusScope.of(context).hasFocus) {
@ -213,14 +213,15 @@ class _EditContactAddressViewState
ref.watch(validContactStateProvider([0]));
return TextButton(
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all<Color>(
shouldEnableSave
? CFColors.stackAccent
: CFColors.disabledButton,
),
),
style: shouldEnableSave
? Theme.of(context)
.extension<StackColors>()!
.getPrimaryEnabledButtonColor(
context)
: Theme.of(context)
.extension<StackColors>()!
.getPrimaryDisabledButtonColor(
context),
onPressed: shouldEnableSave
? () async {
if (FocusScope.of(context)
@ -272,7 +273,7 @@ class _EditContactAddressViewState
: null,
child: Text(
"Save",
style: STextStyles.button,
style: STextStyles.button(context),
),
);
},

View file

@ -4,9 +4,9 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/svg.dart';
import 'package:stackwallet/providers/global/address_book_service_provider.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/cfcolors.dart';
import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
import 'package:stackwallet/widgets/emoji_select_sheet.dart';
import 'package:stackwallet/widgets/icon_widgets/x_icon.dart';
@ -68,7 +68,7 @@ class _EditContactNameEmojiViewState
.select((value) => value.getContactById(contactId)));
return Scaffold(
backgroundColor: CFColors.almostWhite,
backgroundColor: Theme.of(context).extension<StackColors>()!.background,
appBar: AppBar(
leading: AppBarBackButton(
onPressed: () async {
@ -83,7 +83,7 @@ class _EditContactNameEmojiViewState
),
title: Text(
"Edit contact",
style: STextStyles.navBarTitle,
style: STextStyles.navBarTitle(context),
),
),
body: LayoutBuilder(
@ -139,7 +139,9 @@ class _EditContactNameEmojiViewState
width: 48,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(24),
color: CFColors.textFieldActive,
color: Theme.of(context)
.extension<StackColors>()!
.textFieldActiveBG,
),
child: Center(
child: _selectedEmoji == null
@ -150,7 +152,8 @@ class _EditContactNameEmojiViewState
)
: Text(
_selectedEmoji!.char,
style: STextStyles.pageTitleH1,
style: STextStyles.pageTitleH1(
context),
),
),
),
@ -160,20 +163,25 @@ class _EditContactNameEmojiViewState
height: 14,
width: 14,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(14),
color: CFColors.stackAccent,
),
borderRadius: BorderRadius.circular(14),
color: Theme.of(context)
.extension<StackColors>()!
.accentColorDark),
child: Center(
child: _selectedEmoji == null
? SvgPicture.asset(
Assets.svg.plus,
color: CFColors.white,
color: Theme.of(context)
.extension<StackColors>()!
.textWhite,
width: 12,
height: 12,
)
: SvgPicture.asset(
Assets.svg.thickX,
color: CFColors.white,
color: Theme.of(context)
.extension<StackColors>()!
.textWhite,
width: 8,
height: 8,
),
@ -194,11 +202,12 @@ class _EditContactNameEmojiViewState
child: TextField(
controller: nameController,
focusNode: nameFocusNode,
style: STextStyles.field,
style: STextStyles.field(context),
onChanged: (_) => setState(() {}),
decoration: standardInputDecoration(
"Enter contact name",
nameFocusNode,
context,
).copyWith(
suffixIcon: nameController.text.isNotEmpty
? Padding(
@ -230,17 +239,15 @@ class _EditContactNameEmojiViewState
children: [
Expanded(
child: TextButton(
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all<Color>(
CFColors.buttonGray,
),
),
style: Theme.of(context)
.extension<StackColors>()!
.getSecondaryEnabledButtonColor(context),
child: Text(
"Cancel",
style: STextStyles.button.copyWith(
color: CFColors.stackAccent,
),
style: STextStyles.button(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.accentColorDark),
),
onPressed: () async {
if (FocusScope.of(context).hasFocus) {
@ -264,14 +271,15 @@ class _EditContactNameEmojiViewState
nameController.text.isNotEmpty;
return TextButton(
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all<Color>(
shouldEnableSave
? CFColors.stackAccent
: CFColors.disabledButton,
),
),
style: shouldEnableSave
? Theme.of(context)
.extension<StackColors>()!
.getPrimaryEnabledButtonColor(
context)
: Theme.of(context)
.extension<StackColors>()!
.getPrimaryDisabledButtonColor(
context),
onPressed: shouldEnableSave
? () async {
if (FocusScope.of(context)
@ -303,7 +311,7 @@ class _EditContactNameEmojiViewState
: null,
child: Text(
"Save",
style: STextStyles.button,
style: STextStyles.button(context),
),
);
},

View file

@ -8,12 +8,12 @@ import 'package:stackwallet/providers/ui/address_book_providers/address_entry_da
import 'package:stackwallet/utilities/address_utils.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/barcode_scanner_interface.dart';
import 'package:stackwallet/utilities/cfcolors.dart';
import 'package:stackwallet/utilities/clipboard_interface.dart';
import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
import 'package:stackwallet/utilities/logger.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/widgets/icon_widgets/clipboard_icon.dart';
import 'package:stackwallet/widgets/icon_widgets/qrcode_icon.dart';
import 'package:stackwallet/widgets/icon_widgets/x_icon.dart';
@ -72,15 +72,16 @@ class _NewContactAddressEntryFormState
children: [
TextField(
readOnly: true,
style: STextStyles.field,
style: STextStyles.field(context),
decoration: InputDecoration(
hintText: "Select cryptocurrency",
hintStyle: STextStyles.fieldLabel,
hintStyle: STextStyles.fieldLabel(context),
prefixIcon: Center(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 12),
child: RawMaterialButton(
splashColor: CFColors.splashLight,
splashColor:
Theme.of(context).extension<StackColors>()!.highlight,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(
Constants.size.circularBorderRadius,
@ -106,7 +107,7 @@ class _NewContactAddressEntryFormState
null
? Text(
"Select cryptocurrency",
style: STextStyles.fieldLabel,
style: STextStyles.fieldLabel(context),
)
: Row(
children: [
@ -126,7 +127,7 @@ class _NewContactAddressEntryFormState
.watch(addressEntryDataProvider(widget.id)
.select((value) => value.coin))!
.prettyName,
style: STextStyles.itemSubtitle12,
style: STextStyles.itemSubtitle12(context),
),
],
),
@ -134,7 +135,9 @@ class _NewContactAddressEntryFormState
Assets.svg.chevronDown,
width: 8,
height: 4,
color: CFColors.gray3,
color: Theme.of(context)
.extension<StackColors>()!
.textSubtitle2,
),
],
),
@ -153,10 +156,11 @@ class _NewContactAddressEntryFormState
child: TextField(
focusNode: addressLabelFocusNode,
controller: addressLabelController,
style: STextStyles.field,
style: STextStyles.field(context),
decoration: standardInputDecoration(
"Enter address label",
addressLabelFocusNode,
context,
).copyWith(
suffixIcon: addressLabelController.text.isNotEmpty
? Padding(
@ -195,10 +199,11 @@ class _NewContactAddressEntryFormState
child: TextField(
focusNode: addressFocusNode,
controller: addressController,
style: STextStyles.field,
style: STextStyles.field(context),
decoration: standardInputDecoration(
"Paste address",
addressFocusNode,
context,
).copyWith(
suffixIcon: UnconstrainedBox(
child: Row(
@ -351,8 +356,9 @@ class _NewContactAddressEntryFormState
Text(
"Invalid address",
textAlign: TextAlign.left,
style: STextStyles.label.copyWith(
color: CFColors.notificationRedForeground,
style: STextStyles.label(context).copyWith(
color:
Theme.of(context).extension<StackColors>()!.textError,
),
),
],

View file

@ -20,7 +20,7 @@ class _BuyViewState extends State<BuyView> {
Center(
child: Text(
"Coming soon",
style: STextStyles.pageTitleH1,
style: STextStyles.pageTitleH1(context),
),
),
],

View file

@ -1,3 +1,5 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:stackwallet/models/exchange/change_now/exchange_transaction.dart';
@ -8,10 +10,10 @@ import 'package:stackwallet/pages/wallet_view/wallet_view.dart';
import 'package:stackwallet/providers/exchange/trade_sent_from_stack_lookup_provider.dart';
import 'package:stackwallet/providers/providers.dart';
import 'package:stackwallet/route_generator.dart';
import 'package:stackwallet/utilities/cfcolors.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/custom_buttons/app_bar_icon_button.dart';
import 'package:stackwallet/widgets/rounded_container.dart';
import 'package:stackwallet/widgets/rounded_white_container.dart';
@ -47,14 +49,14 @@ class _ConfirmChangeNowSendViewState
late final ExchangeTransaction trade;
Future<void> _attemptSend(BuildContext context) async {
showDialog<void>(
unawaited(showDialog<void>(
context: context,
useSafeArea: false,
barrierDismissible: false,
builder: (context) {
return const SendingTransactionDialog();
},
);
));
final String note = transactionInfo["note"] as String? ?? "";
final manager =
@ -62,10 +64,10 @@ class _ConfirmChangeNowSendViewState
try {
final txid = await manager.confirmSend(txData: transactionInfo);
manager.refresh();
unawaited(manager.refresh());
// save note
ref
await ref
.read(notesServiceChangeNotifierProvider(walletId))
.editOrAddNote(txid: txid, note: note);
@ -86,7 +88,7 @@ class _ConfirmChangeNowSendViewState
// pop sending dialog
Navigator.of(context).pop();
showDialog<dynamic>(
await showDialog<dynamic>(
context: context,
useSafeArea: false,
barrierDismissible: true,
@ -95,15 +97,15 @@ class _ConfirmChangeNowSendViewState
title: "Broadcast transaction failed",
message: e.toString(),
rightButton: TextButton(
style: Theme.of(context).textButtonTheme.style?.copyWith(
backgroundColor: MaterialStateProperty.all<Color>(
CFColors.buttonGray,
),
),
style: Theme.of(context)
.extension<StackColors>()!
.getSecondaryEnabledButtonColor(context),
child: Text(
"Ok",
style: STextStyles.button.copyWith(
color: CFColors.stackAccent,
style: STextStyles.button(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.buttonTextSecondary,
),
),
onPressed: () {
@ -131,7 +133,7 @@ class _ConfirmChangeNowSendViewState
.select((value) => value.getManagerProvider(walletId)));
return Scaffold(
appBar: AppBar(
backgroundColor: CFColors.almostWhite,
backgroundColor: Theme.of(context).extension<StackColors>()!.background,
leading: AppBarBackButton(
onPressed: () async {
// if (FocusScope.of(context).hasFocus) {
@ -143,7 +145,7 @@ class _ConfirmChangeNowSendViewState
),
title: Text(
"Confirm transaction",
style: STextStyles.navBarTitle,
style: STextStyles.navBarTitle(context),
),
),
body: LayoutBuilder(
@ -167,7 +169,7 @@ class _ConfirmChangeNowSendViewState
children: [
Text(
"Send ${ref.watch(managerProvider.select((value) => value.coin)).ticker}",
style: STextStyles.pageTitleH1,
style: STextStyles.pageTitleH1(context),
),
const SizedBox(
height: 12,
@ -178,7 +180,7 @@ class _ConfirmChangeNowSendViewState
children: [
Text(
"Send from",
style: STextStyles.smallMed12,
style: STextStyles.smallMed12(context),
),
const SizedBox(
height: 4,
@ -188,7 +190,7 @@ class _ConfirmChangeNowSendViewState
.watch(walletsChangeNotifierProvider)
.getManager(walletId)
.walletName,
style: STextStyles.itemSubtitle12,
style: STextStyles.itemSubtitle12(context),
),
],
),
@ -205,14 +207,14 @@ class _ConfirmChangeNowSendViewState
children: [
Text(
"ChangeNOW address",
style: STextStyles.smallMed12,
style: STextStyles.smallMed12(context),
),
const SizedBox(
height: 4,
),
Text(
"${transactionInfo["address"] ?? "ERROR"}",
style: STextStyles.itemSubtitle12,
style: STextStyles.itemSubtitle12(context),
),
],
),
@ -226,7 +228,7 @@ class _ConfirmChangeNowSendViewState
children: [
Text(
"Amount",
style: STextStyles.smallMed12,
style: STextStyles.smallMed12(context),
),
Text(
"${Format.satoshiAmountToPrettyString(
@ -239,7 +241,7 @@ class _ConfirmChangeNowSendViewState
managerProvider
.select((value) => value.coin),
).ticker}",
style: STextStyles.itemSubtitle12,
style: STextStyles.itemSubtitle12(context),
textAlign: TextAlign.right,
),
],
@ -254,7 +256,7 @@ class _ConfirmChangeNowSendViewState
children: [
Text(
"Transaction fee",
style: STextStyles.smallMed12,
style: STextStyles.smallMed12(context),
),
Text(
"${Format.satoshiAmountToPrettyString(
@ -267,7 +269,7 @@ class _ConfirmChangeNowSendViewState
managerProvider
.select((value) => value.coin),
).ticker}",
style: STextStyles.itemSubtitle12,
style: STextStyles.itemSubtitle12(context),
textAlign: TextAlign.right,
),
],
@ -282,14 +284,14 @@ class _ConfirmChangeNowSendViewState
children: [
Text(
"Note",
style: STextStyles.smallMed12,
style: STextStyles.smallMed12(context),
),
const SizedBox(
height: 4,
),
Text(
transactionInfo["note"] as String? ?? "",
style: STextStyles.itemSubtitle12,
style: STextStyles.itemSubtitle12(context),
),
],
),
@ -303,11 +305,11 @@ class _ConfirmChangeNowSendViewState
children: [
Text(
"Trade ID",
style: STextStyles.smallMed12,
style: STextStyles.smallMed12(context),
),
Text(
trade.id,
style: STextStyles.itemSubtitle12,
style: STextStyles.itemSubtitle12(context),
textAlign: TextAlign.right,
),
],
@ -317,13 +319,15 @@ class _ConfirmChangeNowSendViewState
height: 12,
),
RoundedContainer(
color: CFColors.stackGreen15,
color: Theme.of(context)
.extension<StackColors>()!
.snackBarBackSuccess,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"Total amount",
style: STextStyles.titleBold12,
style: STextStyles.titleBold12(context),
),
Text(
"${Format.satoshiAmountToPrettyString(
@ -337,7 +341,7 @@ class _ConfirmChangeNowSendViewState
managerProvider
.select((value) => value.coin),
).ticker}",
style: STextStyles.itemSubtitle12,
style: STextStyles.itemSubtitle12(context),
textAlign: TextAlign.right,
),
],
@ -348,13 +352,9 @@ class _ConfirmChangeNowSendViewState
),
const Spacer(),
TextButton(
style:
Theme.of(context).textButtonTheme.style?.copyWith(
backgroundColor:
MaterialStateProperty.all<Color>(
CFColors.stackAccent,
),
),
style: Theme.of(context)
.extension<StackColors>()!
.getPrimaryEnabledButtonColor(context),
onPressed: () async {
final unlocked = await Navigator.push(
context,
@ -378,12 +378,12 @@ class _ConfirmChangeNowSendViewState
);
if (unlocked is bool && unlocked && mounted) {
_attemptSend(context);
await _attemptSend(context);
}
},
child: Text(
"Send",
style: STextStyles.button,
style: STextStyles.button(context),
),
),
],

View file

@ -1,9 +1,9 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:stackwallet/providers/exchange/trade_note_service_provider.dart';
import 'package:stackwallet/utilities/cfcolors.dart';
import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
import 'package:stackwallet/widgets/icon_widgets/x_icon.dart';
import 'package:stackwallet/widgets/stack_text_field.dart';
@ -46,9 +46,9 @@ class _EditNoteViewState extends ConsumerState<EditTradeNoteView> {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: CFColors.almostWhite,
backgroundColor: Theme.of(context).extension<StackColors>()!.background,
appBar: AppBar(
backgroundColor: CFColors.almostWhite,
backgroundColor: Theme.of(context).extension<StackColors>()!.background,
leading: AppBarBackButton(
onPressed: () async {
if (FocusScope.of(context).hasFocus) {
@ -62,7 +62,7 @@ class _EditNoteViewState extends ConsumerState<EditTradeNoteView> {
),
title: Text(
"Edit trade note",
style: STextStyles.navBarTitle,
style: STextStyles.navBarTitle(context),
),
),
body: Padding(
@ -86,12 +86,13 @@ class _EditNoteViewState extends ConsumerState<EditTradeNoteView> {
),
child: TextField(
controller: _noteController,
style: STextStyles.field,
style: STextStyles.field(context),
focusNode: noteFieldFocusNode,
onChanged: (_) => setState(() {}),
decoration: standardInputDecoration(
"Note",
noteFieldFocusNode,
context,
).copyWith(
suffixIcon: _noteController.text.isNotEmpty
? Padding(
@ -126,16 +127,12 @@ class _EditNoteViewState extends ConsumerState<EditTradeNoteView> {
Navigator.of(context).pop();
}
},
style:
Theme.of(context).textButtonTheme.style?.copyWith(
backgroundColor:
MaterialStateProperty.all<Color>(
CFColors.stackAccent,
),
),
style: Theme.of(context)
.extension<StackColors>()!
.getPrimaryEnabledButtonColor(context),
child: Text(
"Save",
style: STextStyles.button,
style: STextStyles.button(context),
),
)
],

View file

@ -4,10 +4,10 @@ import 'package:flutter_svg/svg.dart';
import 'package:stackwallet/models/exchange/change_now/currency.dart';
import 'package:stackwallet/models/exchange/change_now/fixed_rate_market.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/cfcolors.dart';
import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
import 'package:stackwallet/widgets/icon_widgets/x_icon.dart';
import 'package:stackwallet/widgets/loading_indicator.dart';
@ -119,7 +119,7 @@ class _FixedRateMarketPairCoinSelectionViewState
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: CFColors.almostWhite,
backgroundColor: Theme.of(context).extension<StackColors>()!.background,
appBar: AppBar(
leading: AppBarBackButton(
onPressed: () async {
@ -134,7 +134,7 @@ class _FixedRateMarketPairCoinSelectionViewState
),
title: Text(
"Choose a coin to exchange",
style: STextStyles.pageTitleH2,
style: STextStyles.pageTitleH2(context),
),
),
body: Padding(
@ -155,10 +155,11 @@ class _FixedRateMarketPairCoinSelectionViewState
controller: _searchController,
focusNode: _searchFocusNode,
onChanged: filter,
style: STextStyles.field,
style: STextStyles.field(context),
decoration: standardInputDecoration(
"Search",
_searchFocusNode,
context,
).copyWith(
prefixIcon: Padding(
padding: const EdgeInsets.symmetric(
@ -198,7 +199,7 @@ class _FixedRateMarketPairCoinSelectionViewState
),
Text(
"Popular coins",
style: STextStyles.smallMed12,
style: STextStyles.smallMed12(context),
),
const SizedBox(
height: 12,
@ -232,12 +233,12 @@ class _FixedRateMarketPairCoinSelectionViewState
child: Row(
children: [
SizedBox(
width: 20,
height: 20,
width: 24,
height: 24,
child: SvgPicture.network(
tuple.item1,
width: 20,
height: 20,
width: 24,
height: 24,
placeholderBuilder: (_) =>
const LoadingIndicator(),
),
@ -245,9 +246,28 @@ class _FixedRateMarketPairCoinSelectionViewState
const SizedBox(
width: 10,
),
Text(
"${tuple.item2} / ${ticker.toUpperCase()}",
style: STextStyles.titleBold12,
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
tuple.item2,
style: STextStyles.largeMedium14(context),
),
const SizedBox(
height: 2,
),
Text(
ticker.toUpperCase(),
style: STextStyles.smallMed12(context)
.copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textSubtitle1,
),
),
],
),
),
],
),
@ -263,7 +283,7 @@ class _FixedRateMarketPairCoinSelectionViewState
),
Text(
"All coins",
style: STextStyles.smallMed12,
style: STextStyles.smallMed12(context),
),
const SizedBox(
height: 12,
@ -289,12 +309,12 @@ class _FixedRateMarketPairCoinSelectionViewState
child: Row(
children: [
SizedBox(
width: 20,
height: 20,
width: 24,
height: 24,
child: SvgPicture.network(
tuple.item1,
width: 20,
height: 20,
width: 24,
height: 24,
placeholderBuilder: (_) =>
const LoadingIndicator(),
),
@ -302,9 +322,28 @@ class _FixedRateMarketPairCoinSelectionViewState
const SizedBox(
width: 10,
),
Text(
"${tuple.item2} / ${ticker.toUpperCase()}",
style: STextStyles.titleBold12,
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
tuple.item2,
style: STextStyles.largeMedium14(context),
),
const SizedBox(
height: 2,
),
Text(
ticker.toUpperCase(),
style: STextStyles.smallMed12(context)
.copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textSubtitle1,
),
),
],
),
),
],
),

View file

@ -2,10 +2,10 @@ import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:stackwallet/models/exchange/change_now/currency.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/cfcolors.dart';
import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
import 'package:stackwallet/widgets/icon_widgets/x_icon.dart';
import 'package:stackwallet/widgets/loading_indicator.dart';
@ -75,7 +75,7 @@ class _FloatingRateCurrencySelectionViewState
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: CFColors.almostWhite,
backgroundColor: Theme.of(context).extension<StackColors>()!.background,
appBar: AppBar(
leading: AppBarBackButton(
onPressed: () async {
@ -90,7 +90,7 @@ class _FloatingRateCurrencySelectionViewState
),
title: Text(
"Choose a coin to exchange",
style: STextStyles.pageTitleH2,
style: STextStyles.pageTitleH2(context),
),
),
body: Padding(
@ -111,10 +111,11 @@ class _FloatingRateCurrencySelectionViewState
controller: _searchController,
focusNode: _searchFocusNode,
onChanged: filter,
style: STextStyles.field,
style: STextStyles.field(context),
decoration: standardInputDecoration(
"Search",
_searchFocusNode,
context,
).copyWith(
prefixIcon: Padding(
padding: const EdgeInsets.symmetric(
@ -139,6 +140,7 @@ class _FloatingRateCurrencySelectionViewState
setState(() {
_searchController.text = "";
});
filter("");
},
),
],
@ -154,7 +156,7 @@ class _FloatingRateCurrencySelectionViewState
),
Text(
"Popular coins",
style: STextStyles.smallMed12,
style: STextStyles.smallMed12(context),
),
const SizedBox(
height: 12,
@ -183,12 +185,12 @@ class _FloatingRateCurrencySelectionViewState
child: Row(
children: [
SizedBox(
width: 20,
height: 20,
width: 24,
height: 24,
child: SvgPicture.network(
items[index].image,
width: 20,
height: 20,
width: 24,
height: 24,
placeholderBuilder: (_) =>
const LoadingIndicator(),
),
@ -196,9 +198,28 @@ class _FloatingRateCurrencySelectionViewState
const SizedBox(
width: 10,
),
Text(
"${items[index].name} / ${items[index].ticker.toUpperCase()}",
style: STextStyles.titleBold12,
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
items[index].name,
style: STextStyles.largeMedium14(context),
),
const SizedBox(
height: 2,
),
Text(
items[index].ticker.toUpperCase(),
style: STextStyles.smallMed12(context)
.copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textSubtitle1,
),
),
],
),
),
],
),
@ -214,7 +235,7 @@ class _FloatingRateCurrencySelectionViewState
),
Text(
"All coins",
style: STextStyles.smallMed12,
style: STextStyles.smallMed12(context),
),
const SizedBox(
height: 12,
@ -236,12 +257,12 @@ class _FloatingRateCurrencySelectionViewState
child: Row(
children: [
SizedBox(
width: 20,
height: 20,
width: 24,
height: 24,
child: SvgPicture.network(
_currencies[index].image,
width: 20,
height: 20,
width: 24,
height: 24,
placeholderBuilder: (_) =>
const LoadingIndicator(),
),
@ -249,9 +270,28 @@ class _FloatingRateCurrencySelectionViewState
const SizedBox(
width: 10,
),
Text(
"${_currencies[index].name} / ${_currencies[index].ticker.toUpperCase()}",
style: STextStyles.titleBold12,
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
_currencies[index].name,
style: STextStyles.largeMedium14(context),
),
const SizedBox(
height: 2,
),
Text(
_currencies[index].ticker.toUpperCase(),
style: STextStyles.smallMed12(context)
.copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textSubtitle1,
),
),
],
),
),
],
),

View file

@ -1,8 +1,8 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:stackwallet/providers/exchange/changenow_initial_load_status.dart';
import 'package:stackwallet/utilities/cfcolors.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/widgets/custom_loading_overlay.dart';
import 'package:stackwallet/widgets/stack_dialog.dart';
@ -65,7 +65,10 @@ class _ExchangeLoadingOverlayViewState
if (_statusEst == ChangeNowLoadStatus.loading ||
(_statusFixed == ChangeNowLoadStatus.loading && userReloaded))
Container(
color: CFColors.stackAccent.withOpacity(0.7),
color: Theme.of(context)
.extension<StackColors>()!
.overlay
.withOpacity(0.7),
child: const CustomLoadingOverlay(
message: "Loading ChangeNOW data", eventBus: null),
),
@ -74,7 +77,10 @@ class _ExchangeLoadingOverlayViewState
_statusEst != ChangeNowLoadStatus.loading &&
_statusFixed != ChangeNowLoadStatus.loading)
Container(
color: CFColors.stackAccent.withOpacity(0.7),
color: Theme.of(context)
.extension<StackColors>()!
.overlay
.withOpacity(0.7),
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
@ -83,10 +89,16 @@ class _ExchangeLoadingOverlayViewState
message:
"ChangeNOW requires a working internet connection. Tap OK to try fetching again.",
rightButton: TextButton(
style: Theme.of(context)
.extension<StackColors>()!
.getSecondaryEnabledButtonColor(context),
child: Text(
"OK",
style: STextStyles.button
.copyWith(color: CFColors.stackAccent),
style: STextStyles.button(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.buttonTextSecondary,
),
),
onPressed: () {
userReloaded = true;

View file

@ -3,9 +3,9 @@ import 'package:stackwallet/models/exchange/incomplete_exchange.dart';
import 'package:stackwallet/pages/exchange_view/exchange_step_views/step_2_view.dart';
import 'package:stackwallet/pages/exchange_view/sub_widgets/exchange_rate_sheet.dart';
import 'package:stackwallet/pages/exchange_view/sub_widgets/step_row.dart';
import 'package:stackwallet/utilities/cfcolors.dart';
import 'package:stackwallet/utilities/clipboard_interface.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
import 'package:stackwallet/widgets/rounded_white_container.dart';
@ -40,7 +40,7 @@ class _Step1ViewState extends State<Step1View> {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: CFColors.almostWhite,
backgroundColor: Theme.of(context).extension<StackColors>()!.background,
appBar: AppBar(
leading: AppBarBackButton(
onPressed: () async {
@ -55,7 +55,7 @@ class _Step1ViewState extends State<Step1View> {
),
title: Text(
"Exchange",
style: STextStyles.navBarTitle,
style: STextStyles.navBarTitle(context),
),
),
body: LayoutBuilder(
@ -84,14 +84,14 @@ class _Step1ViewState extends State<Step1View> {
),
Text(
"Confirm amount",
style: STextStyles.pageTitleH1,
style: STextStyles.pageTitleH1(context),
),
const SizedBox(
height: 8,
),
Text(
"Network fees and other exchange charges are included in the rate.",
style: STextStyles.itemSubtitle,
style: STextStyles.itemSubtitle(context),
),
const SizedBox(
height: 24,
@ -102,11 +102,19 @@ class _Step1ViewState extends State<Step1View> {
children: [
Text(
"You send",
style: STextStyles.itemSubtitle,
style: STextStyles.itemSubtitle(context)
.copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.infoItemText),
),
Text(
"${model.sendAmount.toStringAsFixed(8)} ${model.sendTicker}",
style: STextStyles.itemSubtitle12,
"${model.sendAmount.toStringAsFixed(8)} ${model.sendTicker.toUpperCase()}",
style: STextStyles.itemSubtitle12(context)
.copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.infoItemText),
),
],
),
@ -120,11 +128,19 @@ class _Step1ViewState extends State<Step1View> {
children: [
Text(
"You receive",
style: STextStyles.itemSubtitle,
style: STextStyles.itemSubtitle(context)
.copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.infoItemText),
),
Text(
"~${model.receiveAmount.toStringAsFixed(8)} ${model.receiveTicker}",
style: STextStyles.itemSubtitle12,
"~${model.receiveAmount.toStringAsFixed(8)} ${model.receiveTicker.toUpperCase()}",
style: STextStyles.itemSubtitle12(context)
.copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.infoItemText),
),
],
),
@ -140,11 +156,20 @@ class _Step1ViewState extends State<Step1View> {
model.rateType == ExchangeRateType.estimated
? "Estimated rate"
: "Fixed rate",
style: STextStyles.itemSubtitle,
style:
STextStyles.itemSubtitle(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.infoItemLabel,
),
),
Text(
model.rateInfo,
style: STextStyles.itemSubtitle12,
style: STextStyles.itemSubtitle12(context)
.copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.infoItemText),
),
],
),
@ -158,16 +183,12 @@ class _Step1ViewState extends State<Step1View> {
Navigator.of(context).pushNamed(Step2View.routeName,
arguments: model);
},
style:
Theme.of(context).textButtonTheme.style?.copyWith(
backgroundColor:
MaterialStateProperty.all<Color>(
CFColors.stackAccent,
),
),
style: Theme.of(context)
.extension<StackColors>()!
.getPrimaryEnabledButtonColor(context),
child: Text(
"Next",
style: STextStyles.button,
style: STextStyles.button(context),
),
),
],

View file

@ -10,12 +10,12 @@ import 'package:stackwallet/providers/exchange/exchange_send_from_wallet_id_prov
import 'package:stackwallet/providers/providers.dart';
import 'package:stackwallet/utilities/address_utils.dart';
import 'package:stackwallet/utilities/barcode_scanner_interface.dart';
import 'package:stackwallet/utilities/cfcolors.dart';
import 'package:stackwallet/utilities/clipboard_interface.dart';
import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
import 'package:stackwallet/utilities/logger.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
import 'package:stackwallet/widgets/icon_widgets/addressbook_icon.dart';
import 'package:stackwallet/widgets/icon_widgets/clipboard_icon.dart';
@ -95,7 +95,7 @@ class _Step2ViewState extends ConsumerState<Step2View> {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: CFColors.almostWhite,
backgroundColor: Theme.of(context).extension<StackColors>()!.background,
appBar: AppBar(
leading: AppBarBackButton(
onPressed: () async {
@ -110,7 +110,7 @@ class _Step2ViewState extends ConsumerState<Step2View> {
),
title: Text(
"Exchange",
style: STextStyles.navBarTitle,
style: STextStyles.navBarTitle(context),
),
),
body: LayoutBuilder(
@ -139,14 +139,14 @@ class _Step2ViewState extends ConsumerState<Step2View> {
),
Text(
"Exchange details",
style: STextStyles.pageTitleH1,
style: STextStyles.pageTitleH1(context),
),
const SizedBox(
height: 8,
),
Text(
"Enter your recipient and refund addresses",
style: STextStyles.itemSubtitle,
style: STextStyles.itemSubtitle(context),
),
const SizedBox(
height: 24,
@ -156,9 +156,7 @@ class _Step2ViewState extends ConsumerState<Step2View> {
children: [
Text(
"Recipient Wallet",
style: STextStyles.itemSubtitle.copyWith(
color: CFColors.neutral50,
),
style: STextStyles.smallMed12(context),
),
// GestureDetector(
// onTap: () {
@ -166,7 +164,7 @@ class _Step2ViewState extends ConsumerState<Step2View> {
// },
// child: Text(
// "Choose from Stack",
// style: STextStyles.link2,
// style: STextStyles.link2(context),
// ),
// ),
],
@ -196,10 +194,11 @@ class _Step2ViewState extends ConsumerState<Step2View> {
selectAll: false,
),
focusNode: _toFocusNode,
style: STextStyles.field,
style: STextStyles.field(context),
decoration: standardInputDecoration(
"Enter the ${model.receiveTicker} payout address",
"Enter the ${model.receiveTicker.toUpperCase()} payout address",
_toFocusNode,
context,
).copyWith(
contentPadding: const EdgeInsets.only(
left: 16,
@ -335,8 +334,8 @@ class _Step2ViewState extends ConsumerState<Step2View> {
),
RoundedWhiteContainer(
child: Text(
"This is the wallet where your ${model.receiveTicker} will be sent to.",
style: STextStyles.label,
"This is the wallet where your ${model.receiveTicker.toUpperCase()} will be sent to.",
style: STextStyles.label(context),
),
),
const SizedBox(
@ -347,7 +346,7 @@ class _Step2ViewState extends ConsumerState<Step2View> {
children: [
Text(
"Refund Wallet (required)",
style: STextStyles.smallMed12,
style: STextStyles.smallMed12(context),
),
// GestureDetector(
// onTap: () {
@ -355,7 +354,7 @@ class _Step2ViewState extends ConsumerState<Step2View> {
// },
// child: Text(
// "Choose from Stack",
// style: STextStyles.link2,
// style: STextStyles.link2(context),
// ),
// ),
],
@ -384,10 +383,11 @@ class _Step2ViewState extends ConsumerState<Step2View> {
selectAll: false,
),
focusNode: _refundFocusNode,
style: STextStyles.field,
style: STextStyles.field(context),
decoration: standardInputDecoration(
"Enter ${model.sendTicker} refund address",
"Enter ${model.sendTicker.toUpperCase()} refund address",
_refundFocusNode,
context,
).copyWith(
contentPadding: const EdgeInsets.only(
left: 16,
@ -526,7 +526,7 @@ class _Step2ViewState extends ConsumerState<Step2View> {
RoundedWhiteContainer(
child: Text(
"In case something goes wrong during the exchange, we might need a refund address so we can return your coins back to you.",
style: STextStyles.label,
style: STextStyles.label(context),
),
),
const Spacer(),
@ -537,10 +537,15 @@ class _Step2ViewState extends ConsumerState<Step2View> {
onPressed: () {
Navigator.of(context).pop();
},
style: Theme.of(context)
.extension<StackColors>()!
.getSecondaryEnabledButtonColor(context),
child: Text(
"Back",
style: STextStyles.button.copyWith(
color: CFColors.stackAccent,
style: STextStyles.button(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.buttonTextSecondary,
),
),
),
@ -559,17 +564,11 @@ class _Step2ViewState extends ConsumerState<Step2View> {
arguments: model);
},
style: Theme.of(context)
.textButtonTheme
.style
?.copyWith(
backgroundColor:
MaterialStateProperty.all<Color>(
CFColors.stackAccent,
),
),
.extension<StackColors>()!
.getPrimaryEnabledButtonColor(context),
child: Text(
"Next",
style: STextStyles.button,
style: STextStyles.button(context),
),
),
),

View file

@ -12,9 +12,9 @@ import 'package:stackwallet/providers/exchange/change_now_provider.dart';
import 'package:stackwallet/providers/global/trades_service_provider.dart';
import 'package:stackwallet/services/notifications_api.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/cfcolors.dart';
import 'package:stackwallet/utilities/clipboard_interface.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
import 'package:stackwallet/widgets/rounded_white_container.dart';
import 'package:stackwallet/widgets/stack_dialog.dart';
@ -50,7 +50,7 @@ class _Step3ViewState extends ConsumerState<Step3View> {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: CFColors.almostWhite,
backgroundColor: Theme.of(context).extension<StackColors>()!.background,
appBar: AppBar(
leading: AppBarBackButton(
onPressed: () async {
@ -65,7 +65,7 @@ class _Step3ViewState extends ConsumerState<Step3View> {
),
title: Text(
"Exchange",
style: STextStyles.navBarTitle,
style: STextStyles.navBarTitle(context),
),
),
body: LayoutBuilder(
@ -94,7 +94,7 @@ class _Step3ViewState extends ConsumerState<Step3View> {
),
Text(
"Confirm exchange details",
style: STextStyles.pageTitleH1,
style: STextStyles.pageTitleH1(context),
),
const SizedBox(
height: 24,
@ -104,12 +104,12 @@ class _Step3ViewState extends ConsumerState<Step3View> {
children: [
Text(
"You send",
style: STextStyles.itemSubtitle,
style: STextStyles.itemSubtitle(context),
),
const Spacer(),
Text(
"${model.sendAmount.toString()} ${model.sendTicker}",
style: STextStyles.itemSubtitle12,
"${model.sendAmount.toString()} ${model.sendTicker.toUpperCase()}",
style: STextStyles.itemSubtitle12(context),
)
],
),
@ -122,12 +122,12 @@ class _Step3ViewState extends ConsumerState<Step3View> {
children: [
Text(
"You receive",
style: STextStyles.itemSubtitle,
style: STextStyles.itemSubtitle(context),
),
const Spacer(),
Text(
"${model.receiveAmount.toString()} ${model.receiveTicker}",
style: STextStyles.itemSubtitle12,
"${model.receiveAmount.toString()} ${model.receiveTicker.toUpperCase()}",
style: STextStyles.itemSubtitle12(context),
)
],
),
@ -140,12 +140,12 @@ class _Step3ViewState extends ConsumerState<Step3View> {
children: [
Text(
"Estimated rate",
style: STextStyles.itemSubtitle,
style: STextStyles.itemSubtitle(context),
),
const Spacer(),
Text(
model.rateInfo,
style: STextStyles.itemSubtitle12,
style: STextStyles.itemSubtitle12(context),
)
],
),
@ -158,15 +158,15 @@ class _Step3ViewState extends ConsumerState<Step3View> {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Recipient ${model.receiveTicker} address",
style: STextStyles.itemSubtitle,
"Recipient ${model.receiveTicker.toUpperCase()} address",
style: STextStyles.itemSubtitle(context),
),
const SizedBox(
height: 4,
),
Text(
model.recipientAddress!,
style: STextStyles.itemSubtitle12,
style: STextStyles.itemSubtitle12(context),
)
],
),
@ -179,15 +179,15 @@ class _Step3ViewState extends ConsumerState<Step3View> {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Refund ${model.sendTicker} address",
style: STextStyles.itemSubtitle,
"Refund ${model.sendTicker.toUpperCase()} address",
style: STextStyles.itemSubtitle(context),
),
const SizedBox(
height: 4,
),
Text(
model.refundAddress!,
style: STextStyles.itemSubtitle12,
style: STextStyles.itemSubtitle12(context),
)
],
),
@ -203,10 +203,15 @@ class _Step3ViewState extends ConsumerState<Step3View> {
onPressed: () {
Navigator.of(context).pop();
},
style: Theme.of(context)
.extension<StackColors>()!
.getSecondaryEnabledButtonColor(context),
child: Text(
"Back",
style: STextStyles.button.copyWith(
color: CFColors.stackAccent,
style: STextStyles.button(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.buttonTextSecondary,
),
),
),
@ -304,17 +309,11 @@ class _Step3ViewState extends ConsumerState<Step3View> {
}
},
style: Theme.of(context)
.textButtonTheme
.style
?.copyWith(
backgroundColor:
MaterialStateProperty.all<Color>(
CFColors.stackAccent,
),
),
.extension<StackColors>()!
.getPrimaryEnabledButtonColor(context),
child: Text(
"Next",
style: STextStyles.button,
style: STextStyles.button(context),
),
),
),

View file

@ -18,13 +18,13 @@ import 'package:stackwallet/providers/exchange/exchange_send_from_wallet_id_prov
import 'package:stackwallet/providers/providers.dart';
import 'package:stackwallet/route_generator.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/cfcolors.dart';
import 'package:stackwallet/utilities/clipboard_interface.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
import 'package:stackwallet/utilities/enums/fee_rate_type_enum.dart';
import 'package:stackwallet/utilities/enums/flush_bar_type.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/custom_buttons/app_bar_icon_button.dart';
import 'package:stackwallet/widgets/rounded_container.dart';
import 'package:stackwallet/widgets/rounded_white_container.dart';
@ -114,7 +114,7 @@ class _Step4ViewState extends ConsumerState<Step4View> {
final bool isWalletCoin =
_isWalletCoinAndHasWallet(model.trade!.fromCurrency, ref);
return Scaffold(
backgroundColor: CFColors.almostWhite,
backgroundColor: Theme.of(context).extension<StackColors>()!.background,
appBar: AppBar(
leading: AppBarBackButton(
onPressed: () async {
@ -129,7 +129,7 @@ class _Step4ViewState extends ConsumerState<Step4View> {
),
title: Text(
"Exchange",
style: STextStyles.navBarTitle,
style: STextStyles.navBarTitle(context),
),
),
body: LayoutBuilder(
@ -157,35 +157,41 @@ class _Step4ViewState extends ConsumerState<Step4View> {
height: 14,
),
Text(
"Send ${model.sendTicker} to the address below",
style: STextStyles.pageTitleH1,
"Send ${model.sendTicker.toUpperCase()} to the address below",
style: STextStyles.pageTitleH1(context),
),
const SizedBox(
height: 8,
),
Text(
"Send ${model.sendTicker} to the address below. Once it is received, ChangeNOW will send the ${model.receiveTicker} to the recipient address you provided. You can find this trade details and check its status in the list of trades.",
style: STextStyles.itemSubtitle,
"Send ${model.sendTicker.toUpperCase()} to the address below. Once it is received, ChangeNOW will send the ${model.receiveTicker.toUpperCase()} to the recipient address you provided. You can find this trade details and check its status in the list of trades.",
style: STextStyles.itemSubtitle(context),
),
const SizedBox(
height: 12,
),
RoundedContainer(
color: CFColors.warningBackground,
color: Theme.of(context)
.extension<StackColors>()!
.warningBackground,
child: RichText(
text: TextSpan(
text:
"You must send at least ${model.sendAmount.toString()} ${model.sendTicker}. ",
style: STextStyles.label.copyWith(
color: CFColors.stackAccent,
style: STextStyles.label(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.warningForeground,
fontWeight: FontWeight.w700,
),
children: [
TextSpan(
text:
"If you send less than ${model.sendAmount.toString()} ${model.sendTicker}, your transaction may not be converted and it may not be refunded.",
style: STextStyles.label.copyWith(
color: CFColors.stackAccent,
style: STextStyles.label(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.warningForeground,
fontWeight: FontWeight.w500,
),
),
@ -206,9 +212,7 @@ class _Step4ViewState extends ConsumerState<Step4View> {
children: [
Text(
"Amount",
style: STextStyles.itemSubtitle.copyWith(
color: CFColors.neutral50,
),
style: STextStyles.itemSubtitle(context),
),
GestureDetector(
onTap: () async {
@ -225,7 +229,9 @@ class _Step4ViewState extends ConsumerState<Step4View> {
children: [
SvgPicture.asset(
Assets.svg.copy,
color: CFColors.link2,
color: Theme.of(context)
.extension<StackColors>()!
.infoItemIcons,
width: 10,
),
const SizedBox(
@ -233,7 +239,7 @@ class _Step4ViewState extends ConsumerState<Step4View> {
),
Text(
"Copy",
style: STextStyles.link2,
style: STextStyles.link2(context),
),
],
),
@ -244,8 +250,8 @@ class _Step4ViewState extends ConsumerState<Step4View> {
height: 4,
),
Text(
"${model.sendAmount.toString()} ${model.sendTicker}",
style: STextStyles.itemSubtitle12,
"${model.sendAmount.toString()} ${model.sendTicker.toUpperCase()}",
style: STextStyles.itemSubtitle12(context),
),
],
),
@ -262,10 +268,8 @@ class _Step4ViewState extends ConsumerState<Step4View> {
MainAxisAlignment.spaceBetween,
children: [
Text(
"Send ${model.sendTicker} to this address",
style: STextStyles.itemSubtitle.copyWith(
color: CFColors.neutral50,
),
"Send ${model.sendTicker.toUpperCase()} to this address",
style: STextStyles.itemSubtitle(context),
),
GestureDetector(
onTap: () async {
@ -282,7 +286,9 @@ class _Step4ViewState extends ConsumerState<Step4View> {
children: [
SvgPicture.asset(
Assets.svg.copy,
color: CFColors.link2,
color: Theme.of(context)
.extension<StackColors>()!
.infoItemIcons,
width: 10,
),
const SizedBox(
@ -290,7 +296,7 @@ class _Step4ViewState extends ConsumerState<Step4View> {
),
Text(
"Copy",
style: STextStyles.link2,
style: STextStyles.link2(context),
),
],
),
@ -302,7 +308,7 @@ class _Step4ViewState extends ConsumerState<Step4View> {
),
Text(
model.trade!.payinAddress,
style: STextStyles.itemSubtitle12,
style: STextStyles.itemSubtitle12(context),
),
],
),
@ -315,14 +321,14 @@ class _Step4ViewState extends ConsumerState<Step4View> {
children: [
Text(
"Trade ID",
style: STextStyles.itemSubtitle,
style: STextStyles.itemSubtitle(context),
),
const Spacer(),
Row(
children: [
Text(
model.trade!.id,
style: STextStyles.itemSubtitle12,
style: STextStyles.itemSubtitle12(context),
),
const SizedBox(
width: 10,
@ -340,7 +346,9 @@ class _Step4ViewState extends ConsumerState<Step4View> {
},
child: SvgPicture.asset(
Assets.svg.copy,
color: CFColors.link2,
color: Theme.of(context)
.extension<StackColors>()!
.infoItemIcons,
width: 12,
),
)
@ -358,14 +366,15 @@ class _Step4ViewState extends ConsumerState<Step4View> {
children: [
Text(
"Status",
style: STextStyles.itemSubtitle.copyWith(
color: CFColors.neutral50,
),
style: STextStyles.itemSubtitle(context),
),
Text(
_statusString,
style: STextStyles.itemSubtitle.copyWith(
color: CFColors.status.forStatus(_status),
style:
STextStyles.itemSubtitle(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.colorForStatus(_status),
),
),
],
@ -390,7 +399,8 @@ class _Step4ViewState extends ConsumerState<Step4View> {
Center(
child: Text(
"Send ${model.sendTicker} to this address",
style: STextStyles.pageTitleH2,
style:
STextStyles.pageTitleH2(context),
),
),
const SizedBox(
@ -405,7 +415,9 @@ class _Step4ViewState extends ConsumerState<Step4View> {
.size
.width /
2,
foregroundColor: CFColors.stackAccent,
foregroundColor: Theme.of(context)
.extension<StackColors>()!
.accentColorDark,
),
),
const SizedBox(
@ -418,11 +430,18 @@ class _Step4ViewState extends ConsumerState<Step4View> {
child: TextButton(
onPressed: () =>
Navigator.of(context).pop(),
style: Theme.of(context)
.extension<StackColors>()!
.getSecondaryEnabledButtonColor(
context),
child: Text(
"Cancel",
style:
STextStyles.button.copyWith(
color: CFColors.stackAccent,
STextStyles.button(context)
.copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.buttonTextSecondary,
),
),
),
@ -435,16 +454,12 @@ class _Step4ViewState extends ConsumerState<Step4View> {
},
);
},
style:
Theme.of(context).textButtonTheme.style?.copyWith(
backgroundColor:
MaterialStateProperty.all<Color>(
CFColors.stackAccent,
),
),
style: Theme.of(context)
.extension<StackColors>()!
.getPrimaryEnabledButtonColor(context),
child: Text(
"Show QR Code",
style: STextStyles.button,
style: STextStyles.button(context),
),
),
if (isWalletCoin)
@ -563,21 +578,18 @@ class _Step4ViewState extends ConsumerState<Step4View> {
message: e.toString(),
rightButton: TextButton(
style: Theme.of(context)
.textButtonTheme
.style
?.copyWith(
backgroundColor:
MaterialStateProperty
.all<Color>(
CFColors.buttonGray,
),
),
.extension<StackColors>()!
.getSecondaryEnabledButtonColor(
context),
child: Text(
"Ok",
style: STextStyles.button
style: STextStyles.button(
context)
.copyWith(
color:
CFColors.stackAccent,
color: Theme.of(context)
.extension<
StackColors>()!
.buttonTextSecondary,
),
),
onPressed: () {
@ -614,10 +626,15 @@ class _Step4ViewState extends ConsumerState<Step4View> {
),
);
},
style: Theme.of(context)
.extension<StackColors>()!
.getSecondaryEnabledButtonColor(context),
child: Text(
buttonTitle,
style: STextStyles.button.copyWith(
color: CFColors.stackAccent,
style: STextStyles.button(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.buttonTextSecondary,
),
),
);

View file

@ -29,10 +29,10 @@ import 'package:stackwallet/providers/exchange/trade_sent_from_stack_lookup_prov
import 'package:stackwallet/providers/global/trades_service_provider.dart';
import 'package:stackwallet/providers/providers.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/cfcolors.dart';
import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/enums/flush_bar_type.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/widgets/custom_loading_overlay.dart';
import 'package:stackwallet/widgets/loading_indicator.dart';
import 'package:stackwallet/widgets/stack_dialog.dart';
@ -66,7 +66,10 @@ class _ExchangeViewState extends ConsumerState<ExchangeView> {
builder: (_) => WillPopScope(
onWillPop: () async => false,
child: Container(
color: CFColors.stackAccent.withOpacity(0.8),
color: Theme.of(context)
.extension<StackColors>()!
.overlay
.withOpacity(0.6),
child: const CustomLoadingOverlay(
message: "Updating exchange rate",
eventBus: null,
@ -366,8 +369,10 @@ class _ExchangeViewState extends ConsumerState<ExchangeView> {
),
Text(
"You will send",
style: STextStyles.itemSubtitle.copyWith(
color: CFColors.neutral50,
style: STextStyles.itemSubtitle(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textDark3,
),
),
const SizedBox(
@ -436,7 +441,7 @@ class _ExchangeViewState extends ConsumerState<ExchangeView> {
right: 12,
),
hintText: "0",
hintStyle: STextStyles.fieldLabel.copyWith(
hintStyle: STextStyles.fieldLabel(context).copyWith(
fontSize: 14,
),
prefixIcon: FittedBox(
@ -561,7 +566,10 @@ class _ExchangeViewState extends ConsumerState<ExchangeView> {
width: 18,
height: 18,
decoration: BoxDecoration(
color: CFColors.gray3,
color: Theme.of(context)
.extension<
StackColors>()!
.textFieldDefaultBG,
borderRadius:
BorderRadius.circular(
18,
@ -583,7 +591,7 @@ class _ExchangeViewState extends ConsumerState<ExchangeView> {
width: 18,
height: 18,
decoration: BoxDecoration(
// color: CFColors.stackAccent,
// color: Theme.of(context).extension<StackColors>()!.accentColorDark
borderRadius:
BorderRadius.circular(18),
),
@ -591,7 +599,9 @@ class _ExchangeViewState extends ConsumerState<ExchangeView> {
Assets.svg.circleQuestion,
width: 18,
height: 18,
color: CFColors.gray3,
color: Theme.of(context)
.extension<StackColors>()!
.textFieldDefaultBG,
),
);
}
@ -615,8 +625,11 @@ class _ExchangeViewState extends ConsumerState<ExchangeView> {
.market?.from
.toUpperCase())) ??
"-",
style: STextStyles.smallMed14.copyWith(
color: CFColors.stackAccent,
style: STextStyles.smallMed14(context)
.copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textDark,
),
),
const SizedBox(
@ -626,7 +639,9 @@ class _ExchangeViewState extends ConsumerState<ExchangeView> {
Assets.svg.chevronDown,
width: 5,
height: 2.5,
color: CFColors.stackAccent,
color: Theme.of(context)
.extension<StackColors>()!
.textDark,
),
],
),
@ -646,25 +661,41 @@ class _ExchangeViewState extends ConsumerState<ExchangeView> {
alignment: Alignment.bottomLeft,
child: Text(
"You will receive",
style: STextStyles.itemSubtitle.copyWith(
color: CFColors.neutral50,
style:
STextStyles.itemSubtitle(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textDark3,
),
),
),
),
Center(
child: GestureDetector(
onTap: () async {
await _swap();
},
child: Padding(
padding: const EdgeInsets.all(4),
child: SvgPicture.asset(
Assets.svg.swap,
width: 20,
height: 20,
child: Column(
children: [
const SizedBox(
height: 6,
),
),
GestureDetector(
onTap: () async {
await _swap();
},
child: Padding(
padding: const EdgeInsets.all(4),
child: SvgPicture.asset(
Assets.svg.swap,
width: 20,
height: 20,
color: Theme.of(context)
.extension<StackColors>()!
.accentColorDark,
),
),
),
const SizedBox(
height: 6,
),
],
),
),
Positioned.fill(
@ -679,7 +710,7 @@ class _ExchangeViewState extends ConsumerState<ExchangeView> {
: ref.watch(fixedRateExchangeFormProvider
.select((value) =>
value.sendAmountWarning)),
style: STextStyles.errorSmall,
style: STextStyles.errorSmall(context),
),
),
),
@ -755,7 +786,7 @@ class _ExchangeViewState extends ConsumerState<ExchangeView> {
right: 12,
),
hintText: "0",
hintStyle: STextStyles.fieldLabel.copyWith(
hintStyle: STextStyles.fieldLabel(context).copyWith(
fontSize: 14,
),
prefixIcon: FittedBox(
@ -874,7 +905,10 @@ class _ExchangeViewState extends ConsumerState<ExchangeView> {
width: 18,
height: 18,
decoration: BoxDecoration(
color: CFColors.gray3,
color: Theme.of(context)
.extension<
StackColors>()!
.textFieldDefaultBG,
borderRadius:
BorderRadius.circular(
18),
@ -895,7 +929,7 @@ class _ExchangeViewState extends ConsumerState<ExchangeView> {
width: 18,
height: 18,
decoration: BoxDecoration(
// color: CFColors.stackAccent,
// color: Theme.of(context).extension<StackColors>()!.accentColorDark
borderRadius:
BorderRadius.circular(18),
),
@ -903,7 +937,9 @@ class _ExchangeViewState extends ConsumerState<ExchangeView> {
Assets.svg.circleQuestion,
width: 18,
height: 18,
color: CFColors.gray3,
color: Theme.of(context)
.extension<StackColors>()!
.textFieldDefaultBG,
),
);
}
@ -927,8 +963,11 @@ class _ExchangeViewState extends ConsumerState<ExchangeView> {
.market?.to
.toUpperCase())) ??
"-",
style: STextStyles.smallMed14.copyWith(
color: CFColors.stackAccent,
style: STextStyles.smallMed14(context)
.copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textDark,
),
),
const SizedBox(
@ -938,7 +977,9 @@ class _ExchangeViewState extends ConsumerState<ExchangeView> {
Assets.svg.chevronDown,
width: 5,
height: 2.5,
color: CFColors.stackAccent,
color: Theme.of(context)
.extension<StackColors>()!
.textDark,
),
],
),
@ -966,7 +1007,7 @@ class _ExchangeViewState extends ConsumerState<ExchangeView> {
// Text(
// ref.watch(exchangeFormSateProvider.select(
// (value) => value.minimumReceiveWarning)),
// style: STextStyles.errorSmall,
// style: STextStyles.errorSmall(context),
// ),
// ],
// ),
@ -1117,28 +1158,20 @@ class _ExchangeViewState extends ConsumerState<ExchangeView> {
height: 12,
),
TextButton(
style: Theme.of(context)
.textButtonTheme
.style
?.copyWith(
backgroundColor: MaterialStateProperty.all<Color>(
((ref
.read(
prefsChangeNotifierProvider)
.exchangeRateType ==
ExchangeRateType.estimated)
? ref.watch(
estimatedRateExchangeFormProvider
.select((value) =>
value.canExchange))
: ref.watch(
fixedRateExchangeFormProvider
.select((value) =>
value.canExchange)))
? CFColors.stackAccent
: CFColors.buttonGray,
),
),
style: ((ref
.read(prefsChangeNotifierProvider)
.exchangeRateType ==
ExchangeRateType.estimated)
? ref.watch(estimatedRateExchangeFormProvider
.select((value) => value.canExchange))
: ref.watch(fixedRateExchangeFormProvider
.select((value) => value.canExchange)))
? Theme.of(context)
.extension<StackColors>()!
.getPrimaryEnabledButtonColor(context)
: Theme.of(context)
.extension<StackColors>()!
.getPrimaryDisabledButtonColor(context),
onPressed: ((ref
.read(prefsChangeNotifierProvider)
.exchangeRateType ==
@ -1304,18 +1337,13 @@ class _ExchangeViewState extends ConsumerState<ExchangeView> {
"${response.value!.warningMessage!}\n\nDo you want to attempt trade anyways?",
leftButton: TextButton(
style: Theme.of(context)
.textButtonTheme
.style
?.copyWith(
backgroundColor:
MaterialStateProperty.all<
Color>(
CFColors.buttonGray,
),
),
.extension<StackColors>()!
.getSecondaryEnabledButtonColor(
context),
child: Text(
"Cancel",
style: STextStyles.itemSubtitle12,
style: STextStyles.itemSubtitle12(
context),
),
onPressed: () {
// notify return to cancel
@ -1324,18 +1352,12 @@ class _ExchangeViewState extends ConsumerState<ExchangeView> {
),
rightButton: TextButton(
style: Theme.of(context)
.textButtonTheme
.style
?.copyWith(
backgroundColor:
MaterialStateProperty.all<
Color>(
CFColors.stackAccent,
),
),
.extension<StackColors>()!
.getPrimaryEnabledButtonColor(
context),
child: Text(
"Attempt",
style: STextStyles.button,
style: STextStyles.button(context),
),
onPressed: () {
// continue and try to attempt trade
@ -1351,7 +1373,7 @@ class _ExchangeViewState extends ConsumerState<ExchangeView> {
}
String rate =
"1 $fromTicker ~${ref.read(fixedRateExchangeFormProvider).rate!.toStringAsFixed(8)} $toTicker";
"1 ${fromTicker.toUpperCase()} ~${ref.read(fixedRateExchangeFormProvider).rate!.toStringAsFixed(8)} ${toTicker.toUpperCase()}";
final model = IncompleteExchangeModel(
sendTicker: fromTicker,
@ -1379,7 +1401,7 @@ class _ExchangeViewState extends ConsumerState<ExchangeView> {
: null,
child: Text(
"Exchange",
style: STextStyles.button,
style: STextStyles.button(context),
),
),
const SizedBox(
@ -1387,8 +1409,8 @@ class _ExchangeViewState extends ConsumerState<ExchangeView> {
),
// Text(
// "Trades",
// style: STextStyles.itemSubtitle.copyWith(
// color: CFColors.neutral50,
// style: STextStyles.itemSubtitle(context).copyWith(
// color: Theme.of(context).extension<StackColors>()!.textDark3,
// ),
// ),
// SizedBox(
@ -1427,8 +1449,10 @@ class _ExchangeViewState extends ConsumerState<ExchangeView> {
),
Text(
"Trades",
style: STextStyles.itemSubtitle.copyWith(
color: CFColors.neutral50,
style: STextStyles.itemSubtitle(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textDark3,
),
),
const SizedBox(
@ -1471,6 +1495,7 @@ class _ExchangeViewState extends ConsumerState<ExchangeView> {
debugPrint("name: ${manager.walletName}");
// TODO store tx data completely locally in isar so we don't lock up ui here when querying txData
final txData = await manager.transactionData;
final tx = txData.getAllTransactions()[txid];
@ -1500,7 +1525,9 @@ class _ExchangeViewState extends ConsumerState<ExchangeView> {
padding: const EdgeInsets.symmetric(horizontal: 4),
child: Container(
decoration: BoxDecoration(
color: CFColors.white,
color: Theme.of(context)
.extension<StackColors>()!
.popupBG,
borderRadius: BorderRadius.circular(
Constants.size.circularBorderRadius,
),
@ -1510,7 +1537,7 @@ class _ExchangeViewState extends ConsumerState<ExchangeView> {
child: Text(
"Trades will appear here",
textAlign: TextAlign.center,
style: STextStyles.itemSubtitle,
style: STextStyles.itemSubtitle(context),
),
),
),
@ -1542,7 +1569,7 @@ class RateInfo extends ConsumerWidget {
return Container(
decoration: BoxDecoration(
color: CFColors.white,
color: Theme.of(context).extension<StackColors>()!.popupBG,
borderRadius: BorderRadius.circular(
Constants.size.circularBorderRadius,
),
@ -1620,7 +1647,7 @@ class RateInfo extends ConsumerWidget {
children: [
Text(
isEstimated ? "Estimated rate" : "Fixed rate",
style: STextStyles.itemSubtitle,
style: STextStyles.itemSubtitle(context),
),
const SizedBox(
width: 6,
@ -1630,7 +1657,9 @@ class RateInfo extends ConsumerWidget {
Assets.svg.chevronDown,
width: 5,
height: 2.5,
color: CFColors.neutral60,
color: Theme.of(context)
.extension<StackColors>()!
.infoItemLabel,
),
],
),
@ -1647,7 +1676,7 @@ class RateInfo extends ConsumerWidget {
.select((value) => value.rateDisplayString))
: ref.watch(fixedRateExchangeFormProvider
.select((value) => value.rateDisplayString)),
style: STextStyles.itemSubtitle12,
style: STextStyles.itemSubtitle12(context),
),
),
),

View file

@ -1,3 +1,5 @@
import 'dart:async';
import 'package:decimal/decimal.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
@ -9,12 +11,12 @@ import 'package:stackwallet/pages/send_view/sub_widgets/building_transaction_dia
import 'package:stackwallet/providers/providers.dart';
import 'package:stackwallet/route_generator.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/cfcolors.dart';
import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
import 'package:stackwallet/utilities/enums/fee_rate_type_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/animated_text.dart';
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
import 'package:stackwallet/widgets/rounded_white_container.dart';
@ -58,7 +60,7 @@ class _SendFromViewState extends ConsumerState<SendFromView> {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: CFColors.almostWhite,
backgroundColor: Theme.of(context).extension<StackColors>()!.background,
appBar: AppBar(
leading: AppBarBackButton(
onPressed: () {
@ -67,7 +69,7 @@ class _SendFromViewState extends ConsumerState<SendFromView> {
),
title: Text(
"Send ",
style: STextStyles.navBarTitle,
style: STextStyles.navBarTitle(context),
),
),
body: Padding(
@ -77,14 +79,14 @@ class _SendFromViewState extends ConsumerState<SendFromView> {
children: [
Text(
"Choose your ${coin.ticker} wallet",
style: STextStyles.pageTitleH1,
style: STextStyles.pageTitleH1(context),
),
const SizedBox(
height: 8,
),
Text(
"You need to send ${amount.toStringAsFixed(coin == Coin.monero ? 12 : 8)} ${coin.ticker}",
style: STextStyles.itemSubtitle,
style: STextStyles.itemSubtitle(context),
),
const SizedBox(
height: 16,
@ -159,7 +161,7 @@ class _SendFromCardState extends ConsumerState<SendFromCard> {
return RoundedWhiteContainer(
padding: const EdgeInsets.all(0),
child: MaterialButton(
splashColor: CFColors.splashLight,
splashColor: Theme.of(context).extension<StackColors>()!.highlight,
key: Key("walletsSheetItemButtonKey_$walletId"),
padding: const EdgeInsets.all(5),
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
@ -174,7 +176,7 @@ class _SendFromCardState extends ConsumerState<SendFromCard> {
try {
bool wasCancelled = false;
showDialog<dynamic>(
unawaited(showDialog<dynamic>(
context: context,
useSafeArea: false,
barrierDismissible: false,
@ -187,7 +189,7 @@ class _SendFromCardState extends ConsumerState<SendFromCard> {
},
);
},
);
));
final txData = await manager.prepareSend(
address: address,
@ -210,7 +212,7 @@ class _SendFromCardState extends ConsumerState<SendFromCard> {
txData["address"] = address;
if (mounted) {
Navigator.of(context).push(
await Navigator.of(context).push(
RouteGenerator.getRoute(
shouldUseMaterialRoute: RouteGenerator.useMaterialPageRoute,
builder: (_) => ConfirmChangeNowSendView(
@ -231,7 +233,7 @@ class _SendFromCardState extends ConsumerState<SendFromCard> {
// pop building dialog
Navigator.of(context).pop();
showDialog<dynamic>(
await showDialog<dynamic>(
context: context,
useSafeArea: false,
barrierDismissible: true,
@ -240,15 +242,15 @@ class _SendFromCardState extends ConsumerState<SendFromCard> {
title: "Transaction failed",
message: e.toString(),
rightButton: TextButton(
style: Theme.of(context).textButtonTheme.style?.copyWith(
backgroundColor: MaterialStateProperty.all<Color>(
CFColors.buttonGray,
),
),
style: Theme.of(context)
.extension<StackColors>()!
.getSecondaryEnabledButtonColor(context),
child: Text(
"Ok",
style: STextStyles.button.copyWith(
color: CFColors.stackAccent,
style: STextStyles.button(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.buttonTextSecondary,
),
),
onPressed: () {
@ -265,7 +267,10 @@ class _SendFromCardState extends ConsumerState<SendFromCard> {
children: [
Container(
decoration: BoxDecoration(
color: CFColors.coin.forCoin(manager.coin).withOpacity(0.5),
color: Theme.of(context)
.extension<StackColors>()!
.colorForCoin(manager.coin)
.withOpacity(0.5),
borderRadius: BorderRadius.circular(
Constants.size.circularBorderRadius,
),
@ -288,7 +293,7 @@ class _SendFromCardState extends ConsumerState<SendFromCard> {
children: [
Text(
manager.walletName,
style: STextStyles.titleBold12,
style: STextStyles.titleBold12(context),
),
const SizedBox(
height: 2,
@ -304,7 +309,7 @@ class _SendFromCardState extends ConsumerState<SendFromCard> {
locale: locale,
decimalPlaces: coin == Coin.monero ? 12 : 8,
)} ${coin.ticker}",
style: STextStyles.itemSubtitle,
style: STextStyles.itemSubtitle(context),
);
} else {
return AnimatedText(
@ -314,7 +319,7 @@ class _SendFromCardState extends ConsumerState<SendFromCard> {
"Loading balance..",
"Loading balance..."
],
style: STextStyles.itemSubtitle,
style: STextStyles.itemSubtitle(context),
);
}
},

View file

@ -1,9 +1,9 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:stackwallet/providers/providers.dart';
import 'package:stackwallet/utilities/cfcolors.dart';
import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
enum ExchangeRateType { estimated, fixed }
@ -15,9 +15,9 @@ class ExchangeRateSheet extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
return Container(
decoration: const BoxDecoration(
color: CFColors.white,
borderRadius: BorderRadius.vertical(
decoration: BoxDecoration(
color: Theme.of(context).extension<StackColors>()!.popupBG,
borderRadius: const BorderRadius.vertical(
top: Radius.circular(20),
),
),
@ -35,7 +35,8 @@ class ExchangeRateSheet extends ConsumerWidget {
Center(
child: Container(
decoration: BoxDecoration(
color: CFColors.fieldGray,
color:
Theme.of(context).extension<StackColors>()!.textSubtitle4,
borderRadius: BorderRadius.circular(
Constants.size.circularBorderRadius,
),
@ -49,7 +50,7 @@ class ExchangeRateSheet extends ConsumerWidget {
),
Text(
"Exchange rate",
style: STextStyles.pageTitleH2,
style: STextStyles.pageTitleH2(context),
textAlign: TextAlign.left,
),
const SizedBox(
@ -76,7 +77,9 @@ class ExchangeRateSheet extends ConsumerWidget {
width: 20,
height: 20,
child: Radio(
activeColor: CFColors.link2,
activeColor: Theme.of(context)
.extension<StackColors>()!
.radioButtonIconEnabled,
value: ExchangeRateType.estimated,
groupValue: ref.watch(prefsChangeNotifierProvider
.select((value) => value.exchangeRateType)),
@ -102,9 +105,7 @@ class ExchangeRateSheet extends ConsumerWidget {
children: [
Text(
"Estimated rate",
style: STextStyles.titleBold12.copyWith(
color: const Color(0xFF44464E),
),
style: STextStyles.titleBold12(context),
textAlign: TextAlign.left,
),
const SizedBox(
@ -112,7 +113,11 @@ class ExchangeRateSheet extends ConsumerWidget {
),
Text(
"ChangeNOW will pick the best rate for you during the moment of the exchange.",
style: STextStyles.itemSubtitle,
style: STextStyles.itemSubtitle(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textSubtitle1,
),
textAlign: TextAlign.left,
),
],
@ -146,7 +151,9 @@ class ExchangeRateSheet extends ConsumerWidget {
width: 20,
height: 20,
child: Radio(
activeColor: CFColors.link2,
activeColor: Theme.of(context)
.extension<StackColors>()!
.radioButtonIconEnabled,
value: ExchangeRateType.fixed,
groupValue: ref.watch(prefsChangeNotifierProvider
.select((value) => value.exchangeRateType)),
@ -169,9 +176,7 @@ class ExchangeRateSheet extends ConsumerWidget {
children: [
Text(
"Fixed rate",
style: STextStyles.titleBold12.copyWith(
color: const Color(0xFF44464E),
),
style: STextStyles.titleBold12(context),
textAlign: TextAlign.left,
),
const SizedBox(
@ -179,7 +184,11 @@ class ExchangeRateSheet extends ConsumerWidget {
),
Text(
"You will get the exact exchange amount displayed - ChangeNOW takes all the rate risks.",
style: STextStyles.itemSubtitle,
style: STextStyles.itemSubtitle(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textSubtitle1,
),
textAlign: TextAlign.left,
)
],

View file

@ -1,8 +1,8 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/cfcolors.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
enum StepIndicatorStatus { current, completed, incomplete }
@ -19,18 +19,22 @@ class StepIndicator extends StatelessWidget {
final double size;
Color get background {
Color background(BuildContext context) {
switch (status) {
case StepIndicatorStatus.current:
return CFColors.selection;
return Theme.of(context)
.extension<StackColors>()!
.stepIndicatorBGNumber;
case StepIndicatorStatus.completed:
return CFColors.selection;
return Theme.of(context).extension<StackColors>()!.stepIndicatorBGCheck;
case StepIndicatorStatus.incomplete:
return CFColors.stackAccent.withOpacity(0.2);
return Theme.of(context)
.extension<StackColors>()!
.stepIndicatorBGInactive;
}
}
Widget get centered {
Widget centered(BuildContext context) {
switch (status) {
case StepIndicatorStatus.current:
return Text(
@ -38,13 +42,16 @@ class StepIndicator extends StatelessWidget {
style: GoogleFonts.roboto(
fontWeight: FontWeight.w600,
fontSize: 8,
color: CFColors.link2,
color: Theme.of(context)
.extension<StackColors>()!
.stepIndicatorIconNumber,
),
);
case StepIndicatorStatus.completed:
return SvgPicture.asset(
Assets.svg.check,
color: CFColors.link2,
color:
Theme.of(context).extension<StackColors>()!.stepIndicatorIconText,
width: 10,
);
case StepIndicatorStatus.incomplete:
@ -53,7 +60,9 @@ class StepIndicator extends StatelessWidget {
style: GoogleFonts.roboto(
fontWeight: FontWeight.w600,
fontSize: 8,
color: CFColors.white,
color: Theme.of(context)
.extension<StackColors>()!
.stepIndicatorIconInactive,
),
);
}
@ -66,10 +75,10 @@ class StepIndicator extends StatelessWidget {
height: size,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(size / 2),
color: background,
color: background(context),
),
child: Center(
child: centered,
child: centered(context),
),
);
}

View file

@ -1,6 +1,6 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:stackwallet/pages/exchange_view/sub_widgets/step_indicator.dart';
import 'package:stackwallet/utilities/cfcolors.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
class StepRow extends StatelessWidget {
const StepRow({
@ -18,15 +18,17 @@ class StepRow extends StatelessWidget {
final double indicatorSize;
final double minSpacing;
Color getColor(int index) {
Color getColor(int index, BuildContext context) {
if (current >= count - 1) {
return CFColors.stackAccent;
return Theme.of(context).extension<StackColors>()!.accentColorDark;
}
if (current <= index) {
return CFColors.stackAccent.withOpacity(0.2);
return Theme.of(context)
.extension<StackColors>()!
.stepIndicatorBGLinesInactive;
} else {
return CFColors.link2;
return Theme.of(context).extension<StackColors>()!.stepIndicatorBGLines;
}
}
@ -40,7 +42,7 @@ class StepRow extends StatelessWidget {
}
}
List<Widget> _buildList(double spacerWidth) {
List<Widget> _buildList(double spacerWidth, BuildContext context) {
List<Widget> list = [];
for (int i = 0; i < count - 1; i++) {
list.add(StepIndicator(
@ -51,7 +53,7 @@ class StepRow extends StatelessWidget {
width: spacerWidth,
dotSize: 1.5,
spacing: 4,
color: getColor(i),
color: getColor(i, context),
));
}
list.add(StepIndicator(
@ -68,7 +70,7 @@ class StepRow extends StatelessWidget {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
..._buildList(spacerWidth),
..._buildList(spacerWidth, context),
],
);
}

View file

@ -17,12 +17,12 @@ import 'package:stackwallet/providers/exchange/trade_note_service_provider.dart'
import 'package:stackwallet/providers/global/trades_service_provider.dart';
import 'package:stackwallet/providers/providers.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/cfcolors.dart';
import 'package:stackwallet/utilities/clipboard_interface.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
import 'package:stackwallet/utilities/enums/flush_bar_type.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/custom_buttons/app_bar_icon_button.dart';
import 'package:stackwallet/widgets/rounded_container.dart';
import 'package:stackwallet/widgets/rounded_white_container.dart';
@ -108,11 +108,11 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
case ChangeNowTransactionStatus.Sending:
case ChangeNowTransactionStatus.Refunded:
case ChangeNowTransactionStatus.Verifying:
return Assets.svg.txExchangePending;
return Assets.svg.txExchangePending(context);
case ChangeNowTransactionStatus.Finished:
return Assets.svg.txExchange;
return Assets.svg.txExchange(context);
case ChangeNowTransactionStatus.Failed:
return Assets.svg.txExchangeFailed;
return Assets.svg.txExchangeFailed(context);
}
}
@ -140,9 +140,9 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
Decimal.parse("-1");
return Scaffold(
backgroundColor: CFColors.almostWhite,
backgroundColor: Theme.of(context).extension<StackColors>()!.background,
appBar: AppBar(
backgroundColor: CFColors.almostWhite,
backgroundColor: Theme.of(context).extension<StackColors>()!.background,
leading: AppBarBackButton(
onPressed: () async {
Navigator.of(context).pop();
@ -150,7 +150,7 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
),
title: Text(
"Trade details",
style: STextStyles.navBarTitle,
style: STextStyles.navBarTitle(context),
),
),
body: Padding(
@ -170,7 +170,7 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
children: [
SelectableText(
"${trade.fromCurrency.toUpperCase()}${trade.toCurrency.toUpperCase()}",
style: STextStyles.titleBold12,
style: STextStyles.titleBold12(context),
),
const SizedBox(
height: 4,
@ -180,7 +180,7 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
localeServiceChangeNotifierProvider
.select((value) => value.locale),
), decimalPlaces: trade.fromCurrency.toLowerCase() == "xmr" ? 12 : 8)} ${trade.fromCurrency.toUpperCase()}",
style: STextStyles.itemSubtitle,
style: STextStyles.itemSubtitle(context),
),
],
),
@ -212,18 +212,21 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
children: [
Text(
"Status",
style: STextStyles.itemSubtitle,
style: STextStyles.itemSubtitle(context),
),
const SizedBox(
height: 4,
),
SelectableText(
trade.statusObject?.status.name ?? trade.statusString,
style: STextStyles.itemSubtitle.copyWith(
style: STextStyles.itemSubtitle(context).copyWith(
color: trade.statusObject != null
? CFColors.status
.forStatus(trade.statusObject!.status)
: CFColors.stackAccent,
? Theme.of(context)
.extension<StackColors>()!
.colorForStatus(trade.statusObject!.status)
: Theme.of(context)
.extension<StackColors>()!
.accentColorDark,
),
),
// ),
@ -237,15 +240,19 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
),
if (!sentFromStack && !hasTx)
RoundedContainer(
color: CFColors.warningBackground,
color: Theme.of(context)
.extension<StackColors>()!
.warningBackground,
child: RichText(
text: TextSpan(
text:
"You must send at least ${sendAmount.toStringAsFixed(
trade.fromCurrency.toLowerCase() == "xmr" ? 12 : 8,
)} ${trade.fromCurrency.toUpperCase()}. ",
style: STextStyles.label.copyWith(
color: CFColors.stackAccent,
style: STextStyles.label(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.warningForeground,
fontWeight: FontWeight.w700,
),
children: [
@ -256,8 +263,10 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
? 12
: 8,
)} ${trade.fromCurrency.toUpperCase()}, your transaction may not be converted and it may not be refunded.",
style: STextStyles.label.copyWith(
color: CFColors.stackAccent,
style: STextStyles.label(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.warningForeground,
fontWeight: FontWeight.w500,
),
),
@ -275,14 +284,14 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
children: [
Text(
"Sent from",
style: STextStyles.itemSubtitle,
style: STextStyles.itemSubtitle(context),
),
const SizedBox(
height: 4,
),
SelectableText(
widget.walletName!,
style: STextStyles.itemSubtitle12,
style: STextStyles.itemSubtitle12(context),
),
const SizedBox(
height: 10,
@ -300,7 +309,7 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
},
child: Text(
"View transaction",
style: STextStyles.link2,
style: STextStyles.link2(context),
),
),
],
@ -317,14 +326,14 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
children: [
Text(
"ChangeNOW address",
style: STextStyles.itemSubtitle,
style: STextStyles.itemSubtitle(context),
),
const SizedBox(
height: 4,
),
SelectableText(
trade.payinAddress,
style: STextStyles.itemSubtitle12,
style: STextStyles.itemSubtitle12(context),
),
],
),
@ -340,14 +349,14 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
children: [
Text(
"Send ${trade.fromCurrency.toUpperCase()} to this address",
style: STextStyles.itemSubtitle,
style: STextStyles.itemSubtitle(context),
),
const SizedBox(
height: 4,
),
SelectableText(
trade.payinAddress,
style: STextStyles.itemSubtitle12,
style: STextStyles.itemSubtitle12(context),
),
const SizedBox(
height: 10,
@ -368,8 +377,9 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
children: [
Center(
child: Text(
"Recovery phrase QR code",
style: STextStyles.pageTitleH2,
"Send ${trade.fromCurrency.toUpperCase()} to this address",
style:
STextStyles.pageTitleH2(context),
),
),
const SizedBox(
@ -382,12 +392,16 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
width: width + 20,
height: width + 20,
child: QrImage(
data: trade.payinAddress,
size: width,
backgroundColor: CFColors.white,
foregroundColor:
CFColors.stackAccent,
),
data: trade.payinAddress,
size: width,
backgroundColor: Theme.of(
context)
.extension<StackColors>()!
.popupBG,
foregroundColor: Theme.of(
context)
.extension<StackColors>()!
.accentColorDark),
),
),
),
@ -402,19 +416,18 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
// await _capturePng(true);
Navigator.of(context).pop();
},
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all<
Color>(
CFColors.buttonGray,
),
),
style: Theme.of(context)
.extension<StackColors>()!
.getSecondaryEnabledButtonColor(
context),
child: Text(
"Cancel",
style:
STextStyles.button.copyWith(
color: CFColors.stackAccent,
),
style: STextStyles.button(context)
.copyWith(
color: Theme.of(context)
.extension<
StackColors>()!
.accentColorDark),
),
),
),
@ -428,17 +441,19 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
child: Row(
children: [
SvgPicture.asset(
Assets.svg.pencil,
width: 10,
height: 10,
color: CFColors.link2,
Assets.svg.qrcode,
width: 12,
height: 12,
color: Theme.of(context)
.extension<StackColors>()!
.infoItemIcons,
),
const SizedBox(
width: 4,
),
Text(
"Edit",
style: STextStyles.link2,
"Show QR code",
style: STextStyles.link2(context),
),
],
),
@ -458,7 +473,7 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
children: [
Text(
"Trade note",
style: STextStyles.itemSubtitle,
style: STextStyles.itemSubtitle(context),
),
GestureDetector(
onTap: () {
@ -478,14 +493,16 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
Assets.svg.pencil,
width: 10,
height: 10,
color: CFColors.link2,
color: Theme.of(context)
.extension<StackColors>()!
.infoItemIcons,
),
const SizedBox(
width: 4,
),
Text(
"Edit",
style: STextStyles.link2,
style: STextStyles.link2(context),
),
],
),
@ -498,7 +515,7 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
SelectableText(
ref.watch(tradeNoteServiceProvider.select(
(value) => value.getNote(tradeId: tradeId))),
style: STextStyles.itemSubtitle12,
style: STextStyles.itemSubtitle12(context),
),
],
),
@ -517,7 +534,7 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
children: [
Text(
"Transaction note",
style: STextStyles.itemSubtitle,
style: STextStyles.itemSubtitle(context),
),
GestureDetector(
onTap: () {
@ -536,14 +553,16 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
Assets.svg.pencil,
width: 10,
height: 10,
color: CFColors.link2,
color: Theme.of(context)
.extension<StackColors>()!
.infoItemIcons,
),
const SizedBox(
width: 4,
),
Text(
"Edit",
style: STextStyles.link2,
style: STextStyles.link2(context),
),
],
),
@ -567,7 +586,7 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
}
return SelectableText(
_note,
style: STextStyles.itemSubtitle12,
style: STextStyles.itemSubtitle12(context),
);
},
),
@ -583,7 +602,7 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
children: [
Text(
"Date",
style: STextStyles.itemSubtitle,
style: STextStyles.itemSubtitle(context),
),
// Flexible(
// child: FittedBox(
@ -592,7 +611,7 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
SelectableText(
Format.extractDateFrom(
trade.date.millisecondsSinceEpoch ~/ 1000),
style: STextStyles.itemSubtitle12,
style: STextStyles.itemSubtitle12(context),
),
// ),
// ),
@ -608,7 +627,7 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
children: [
Text(
"Exchange",
style: STextStyles.itemSubtitle,
style: STextStyles.itemSubtitle(context),
),
// Flexible(
// child: FittedBox(
@ -616,7 +635,7 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
// child:
SelectableText(
"ChangeNOW",
style: STextStyles.itemSubtitle12,
style: STextStyles.itemSubtitle12(context),
),
// ),
// ),
@ -631,14 +650,14 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
children: [
Text(
"Trade ID",
style: STextStyles.itemSubtitle,
style: STextStyles.itemSubtitle(context),
),
const Spacer(),
Row(
children: [
Text(
trade.id,
style: STextStyles.itemSubtitle12,
style: STextStyles.itemSubtitle12(context),
),
const SizedBox(
width: 10,
@ -655,7 +674,9 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
},
child: SvgPicture.asset(
Assets.svg.copy,
color: CFColors.link2,
color: Theme.of(context)
.extension<StackColors>()!
.infoItemIcons,
width: 12,
),
)
@ -673,7 +694,7 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
children: [
Text(
"Tracking",
style: STextStyles.itemSubtitle,
style: STextStyles.itemSubtitle(context),
),
const SizedBox(
height: 4,
@ -689,7 +710,7 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
},
child: Text(
"https://changenow.io/exchange/txs/${trade.id}",
style: STextStyles.link2,
style: STextStyles.link2(context),
),
),
],

Some files were not shown because too many files have changed in this diff Show more