Username Education

Co-authored-by: Jamie Kyle <jamie@signal.org>
This commit is contained in:
Fedor Indutny 2024-01-29 12:09:54 -08:00 committed by GitHub
parent c6a7637513
commit 7dc11c1928
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
100 changed files with 1443 additions and 1269 deletions

View File

@ -885,7 +885,7 @@
},
"icu:cdsMirroringErrorToast": {
"messageformat": "Desktop ran into a Contact Discovery Service inconsistency.",
"description": "An error popup when we discovered an inconsistency between mirrored Contact Discovery Service requests."
"description": "(Deleted 2024/01/22) An error popup when we discovered an inconsistency between mirrored Contact Discovery Service requests."
},
"icu:decryptionErrorToast": {
"messageformat": "Desktop ran into a decryption error from {name}, device {deviceId}",
@ -6884,29 +6884,73 @@
"description": "Text of the confirmation dialog shown on username link error"
},
"icu:UsernameOnboardingModalBody__title": {
"messageformat": "Set up your Signal username",
"messageformat": "New ways to connect",
"description": "Title of username onboarding modal"
},
"icu:UsernameOnboardingModalBody__row__number__title": {
"messageformat": "Phone number privacy",
"description": "Title of the first row of username onboarding modal"
},
"icu:UsernameOnboardingModalBody__row__number__body": {
"messageformat": "Your phone number is no longer shared with chats. If your number is saved to a friends contacts, they will still see it.",
"description": "Body of the first row of username onboarding modal"
},
"icu:UsernameOnboardingModalBody__row__username__title": {
"messageformat": "Usernames",
"description": "Title of the second row of username onboarding modal"
},
"icu:UsernameOnboardingModalBody__row__username__body": {
"messageformat": "People can now message you using your optional username. Phone numbers are no longer required and usernames arent visible on your profile.",
"description": "Body of the second row of username onboarding modal"
},
"icu:UsernameOnboardingModalBody__row__qr__title": {
"messageformat": "QR codes and links",
"description": "Title of the third row of username onboarding modal"
},
"icu:UsernameOnboardingModalBody__row__qr__body": {
"messageformat": "Usernames have a unique QR code and link you can share with friends to quickly start a chat with you.",
"description": "Body of the third row of username onboarding modal"
},
"icu:UsernameOnboardingModalBody__row__number": {
"messageformat": "Usernames are paired with a set of digits and arent shared on your profile",
"description": "Content of the first row of username onboarding modal"
"description": "(Deleted 01/16/2023) Content of the first row of username onboarding modal"
},
"icu:UsernameOnboardingModalBody__row__link": {
"messageformat": "Each username has a unique QR code and link you can share with friends to start a chat with you",
"description": "Content of the second row of username onboarding modal"
"description": "(Deleted 01/16/2023) Content of the second row of username onboarding modal"
},
"icu:UsernameOnboardingModalBody__row__lock": {
"messageformat": "Turn off phone number discovery under Settings > Privacy > Phone Number > Who can find my number, to use your username as the primary way others can contact you.",
"description": "Content of the third row of username onboarding modal"
"description": "(Deleted 01/16/2023) Content of the third row of username onboarding modal"
},
"icu:UsernameOnboardingModalBody__learn-more": {
"messageformat": "Learn More",
"description": "Text that open a popup with information about username onboarding"
"description": "(Deleted 01/16/2023) Text that open a popup with information about username onboarding"
},
"icu:UsernameOnboardingModalBody__continue": {
"messageformat": "Continue",
"messageformat": "Set up your Username",
"description": "Text of the primary button on username onboarding modal"
},
"icu:UsernameOnboardingModalBody__skip": {
"messageformat": "Not Now",
"description": "Text of the secondary button on username onboarding modal"
},
"icu:UsernameMegaphone__title": {
"messageformat": "New ways to connect",
"description": "Title of username megaphone"
},
"icu:UsernameMegaphone__body": {
"messageformat": "Introducing phone number privacy, optional usernames and links.",
"description": "Body of username megaphone"
},
"icu:UsernameMegaphone__learn-more": {
"messageformat": "Learn more",
"description": "Text of the primary button on username megaphone"
},
"icu:UsernameMegaphone__dismiss": {
"messageformat": "Dismiss",
"description": "Text of the secondary button on username megaphone"
},
"icu:UnsupportedOSWarningDialog__body": {
"messageformat": "Signal desktop will no longer support your computers version of {OS} soon. To keep using Signal, update your computers operating system by {expirationDate}. <learnMoreLink>Learn more</learnMoreLink>",
"description": "Body of a dialog displayed on unsupported operating systems"

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="none"><path fill="#FFE3A5" d="M8 8.667a8 8 0 1 1 16 0v4.252c-.44-.22-.93-.32-1.525-.37a22.132 22.132 0 0 0-1.675-.048V8.8a4.8 4.8 0 1 0-9.6 0v3.7a22.12 22.12 0 0 0-1.675.048c-.595.05-1.084.15-1.525.37V8.666ZM8.658 14.266c.2-.102.476-.18.99-.222.526-.043 1.204-.044 2.192-.044h8.32c.988 0 1.666 0 2.192.044.514.042.79.12.99.222.456.235.828.609 1.06 1.069.102.2.179.479.22.996.044.53.045 1.213.045 2.209v5.587c0 .995-.001 1.678-.044 2.208-.042.518-.12.796-.22.997-.233.46-.605.834-1.061 1.068-.2.103-.476.18-.99.223-.526.043-1.204.044-2.192.044h-8.32c-.988 0-1.666-.001-2.192-.044-.514-.043-.79-.12-.99-.223a2.436 2.436 0 0 1-1.06-1.068c-.102-.201-.179-.48-.22-.997-.044-.53-.045-1.213-.045-2.208V18.54c0-.995.001-1.679.044-2.209.042-.517.119-.795.22-.996.233-.46.605-.834 1.061-1.069Z"/><path fill="#B3841C" fill-rule="evenodd" d="M16 .667a8 8 0 0 0-8 8v4.251c.435-.217.916-.317 1.5-.367V8.667a6.5 6.5 0 1 1 13 0v3.884c.584.05 1.065.15 1.5.367V8.668a8 8 0 0 0-8-8ZM20.8 12.5V8.8a4.8 4.8 0 1 0-9.6 0v3.7l.618-.001h.882V8.8a3.3 3.3 0 0 1 6.6 0v3.7h1.5Z" clip-rule="evenodd"/><path fill="#B2841C" fill-rule="evenodd" d="M11.818 12.5c-.952 0-1.696 0-2.293.05-.607.05-1.104.152-1.552.382-.74.38-1.339.984-1.714 1.726-.226.447-.328.943-.377 1.552-.049.6-.049 1.349-.049 2.31v5.628c0 .96 0 1.708.049 2.308.05.61.151 1.106.377 1.553a3.935 3.935 0 0 0 1.714 1.726c.448.23.945.333 1.552.383.597.049 1.341.049 2.293.049h8.364c.952 0 1.696 0 2.293-.05.607-.05 1.104-.152 1.552-.382.74-.38 1.339-.985 1.714-1.726.226-.447.328-.944.377-1.553.049-.6.049-1.348.049-2.308v-5.629c0-.96 0-1.708-.049-2.309-.05-.609-.151-1.105-.377-1.552a3.936 3.936 0 0 0-1.714-1.726c-.448-.23-.945-.333-1.552-.383-.597-.049-1.341-.049-2.293-.049h-8.364Zm-2.17 1.544c-.514.042-.79.12-.99.222a2.436 2.436 0 0 0-1.06 1.069c-.102.2-.179.479-.22.996-.044.53-.045 1.213-.045 2.209v5.587c0 .995.001 1.678.044 2.208.042.518.119.796.22.997.233.46.605.834 1.061 1.068.2.103.476.18.99.223.526.043 1.204.044 2.192.044h8.32c.988 0 1.666-.001 2.192-.044.514-.043.79-.12.99-.223a2.436 2.436 0 0 0 1.06-1.068c.102-.201.179-.48.22-.997.044-.53.045-1.213.045-2.208V18.54c0-.995-.001-1.679-.044-2.209-.042-.517-.12-.795-.22-.996a2.436 2.436 0 0 0-1.061-1.069c-.2-.102-.476-.18-.99-.222-.526-.043-1.204-.044-2.192-.044h-8.32c-.988 0-1.666 0-2.192.044Z" clip-rule="evenodd"/><path fill="#B2841C" d="M15 21.066a2 2 0 1 1 2 0v2.1a1 1 0 1 1-2 0v-2.1Z"/></svg>

Before

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="none"><path fill="#CCD1FF" fill-rule="evenodd" d="M23.806 5.583a1.167 1.167 0 0 0-2.28-.499l-1.11 5.083h-6.279l1.003-4.584a1.167 1.167 0 1 0-2.28-.499l-1.111 5.083H7.332a1.167 1.167 0 1 0 0 2.333h3.905l-1.531 7H5.333a1.167 1.167 0 1 0 0 2.333h3.863l-1.002 4.584a1.167 1.167 0 0 0 2.28.499l1.11-5.083h6.279l-1.003 4.584a1.167 1.167 0 1 0 2.28.499l1.111-5.083h4.416a1.167 1.167 0 1 0 0-2.333h-3.905l1.531-7h4.374a1.167 1.167 0 0 0 0-2.333h-3.863l1.002-4.584ZM19.905 12.5h-6.278l-1.532 7h6.278l1.532-7Z" clip-rule="evenodd"/><path fill="#6771CC" fill-rule="evenodd" d="M8.763 29.272a2.667 2.667 0 0 1-2.035-3.175l.605-2.764h-2a2.667 2.667 0 1 1 0-5.333H8.5l.875-4h-2.04a2.667 2.667 0 0 1 0-5.333h3.207l.854-3.904a2.667 2.667 0 1 1 5.21 1.14l-.604 2.764h3.207l.854-3.904a2.667 2.667 0 1 1 5.21 1.14l-.605 2.764h2a2.667 2.667 0 0 1 0 5.333H23.5l-.875 4h2.042a2.667 2.667 0 0 1 0 5.333h-3.208l-.854 3.904a2.667 2.667 0 1 1-5.21-1.14l.604-2.764h-3.207l-.854 3.904a2.667 2.667 0 0 1-3.175 2.035Zm-.57-2.855a1.167 1.167 0 0 0 2.28.499l1.112-5.083h6.278l-1.003 4.584a1.167 1.167 0 1 0 2.28.499l1.111-5.083h4.416a1.167 1.167 0 1 0 0-2.333h-3.905l1.531-7h4.374a1.167 1.167 0 0 0 0-2.333h-3.863l1.002-4.584a1.167 1.167 0 0 0-2.28-.499l-1.11 5.083h-6.279l1.003-4.584a1.167 1.167 0 1 0-2.28-.499l-1.111 5.083H7.332a1.167 1.167 0 1 0 0 2.333h3.905l-1.531 7H5.333a1.167 1.167 0 1 0 0 2.333h3.863l-1.002 4.584ZM14.834 14l-.874 4h3.207l.875-4h-3.207Zm-1.206-1.5-1.532 7h6.278l1.532-7h-6.278Z" clip-rule="evenodd"/></svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -0,0 +1,7 @@
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12.2964 7.03176C10.9497 5.25976 8.34897 5.08326 6.77518 6.65704L5.98672 7.4455C3.465 9.96723 2.20799 13.5948 3.36417 16.9685C5.0336 21.8397 7.81162 26.4151 11.6982 30.3018C15.5849 34.1884 20.1603 36.9664 25.0315 38.6358C28.4052 39.792 32.0328 38.535 34.5545 36.0133L35.343 35.2248C36.9167 33.651 36.7402 31.0503 34.9682 29.7036L29.8036 25.7785C28.3413 24.6671 26.2829 24.8068 24.9842 26.1056L22.7358 28.354C22.0186 29.0711 19.4024 27.6177 16.8924 25.1076C14.3823 22.5976 12.9289 19.9814 13.646 19.2642L15.8944 17.0158C17.1932 15.7171 17.3329 13.6587 16.2215 12.1964L12.2964 7.03176Z" fill="#F3D48F" style="fill:#F3D48F;fill:color(display-p3 0.9527 0.8304 0.5627);fill-opacity:1;"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M16.2418 16.6199C17.3044 15.3344 17.3593 13.467 16.3321 12.1154L12.455 7.01399C11.1894 5.34883 8.80282 5.11004 7.2351 6.42929C7.42477 11.5901 11.26 15.82 16.2418 16.6199ZM24.6819 26.1597L24.9875 25.8542C26.2703 24.5714 28.3035 24.4334 29.7479 25.5311L34.8493 29.4082C36.2074 30.4403 36.6167 32.2183 36.0057 33.6894C35.6555 33.7239 35.3004 33.7416 34.9411 33.7416C30.111 33.7416 26.0264 30.5494 24.6819 26.1597Z" fill="#F8E3B5" style="fill:#F8E3B5;fill:color(display-p3 0.9730 0.8908 0.7105);fill-opacity:1;"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.5558 7.59461C10.5502 6.2714 8.60813 6.1396 7.43293 7.3148L6.64448 8.10326C4.30976 10.438 3.22983 13.7072 4.24413 16.6669C5.86861 21.407 8.57179 25.8598 12.356 29.644C16.1402 33.4282 20.593 36.1314 25.3331 37.7559C28.2928 38.7702 31.562 37.6902 33.8967 35.3555L34.6852 34.5671C35.8604 33.3919 35.7286 31.4498 34.4054 30.4442L29.2408 26.5191C28.1488 25.6892 26.6117 25.7935 25.6419 26.7633L23.3935 29.0117C22.8804 29.5248 22.179 29.509 21.6963 29.4155C21.1752 29.3146 20.6051 29.071 20.0347 28.7541C18.8824 28.114 17.5329 27.0637 16.2346 25.7654C14.9363 24.4671 13.886 23.1176 13.2458 21.9653C12.929 21.3949 12.6854 20.8248 12.5845 20.3037C12.491 19.821 12.4752 19.1196 12.9883 18.6065L15.2367 16.3581C16.2065 15.3883 16.3108 13.8512 15.4809 12.7592L11.5558 7.59461ZM6.11742 5.99929C8.0898 4.02691 11.3492 4.24812 13.037 6.4689L16.9621 11.6335C18.3549 13.4662 18.1798 16.0459 16.5522 17.6736L14.394 19.8318C14.3962 19.8601 14.4011 19.8988 14.411 19.95C14.4593 20.1995 14.6016 20.5748 14.8721 21.0618C15.4069 22.0244 16.3384 23.2381 17.5501 24.4499C18.7619 25.6616 19.9756 26.5931 20.9382 27.1279C21.4252 27.3984 21.8005 27.5407 22.05 27.589C22.1012 27.5989 22.1399 27.6038 22.1682 27.606L24.3264 25.4478C25.9541 23.8202 28.5338 23.6451 30.3665 25.0379L35.5311 28.963C37.7519 30.6508 37.9731 33.9102 36.0007 35.8826L35.2122 36.671C32.5035 39.3798 28.5176 40.8138 24.73 39.5158C19.7275 37.8014 15.0295 34.9486 11.0405 30.9595C7.05144 26.9705 4.19858 22.2725 2.48421 17.27C1.18616 13.4824 2.62023 9.49648 5.32897 6.78775L6.11742 5.99929ZM22.2312 27.6057C22.2312 27.6057 22.228 27.6067 22.2202 27.6072C22.2271 27.6056 22.2312 27.6057 22.2312 27.6057ZM14.3943 19.7688C14.3943 19.7688 14.3944 19.7729 14.3928 19.7798C14.3933 19.772 14.3943 19.7688 14.3943 19.7688Z" fill="#A48338" style="fill:#A48338;fill:color(display-p3 0.6444 0.5137 0.2203);fill-opacity:1;"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M24.6362 4.60922C24.6362 2.06362 26.5797 0 28.9771 0C31.3746 0 33.3181 2.06362 33.3181 4.60922V6.71024C33.7381 6.95519 34.0796 7.32881 34.2977 7.7832C34.4462 8.09272 34.5049 8.42133 34.5322 8.77576C34.5584 9.11644 34.5584 9.53416 34.5584 10.038V13.1021C34.5584 13.606 34.5584 14.0237 34.5322 14.3644C34.5049 14.7188 34.4462 15.0474 34.2977 15.3569C34.0683 15.8348 33.7024 16.2234 33.2523 16.4669C32.9608 16.6246 32.6513 16.6869 32.3175 16.7159C31.9967 16.7437 31.6033 16.7437 31.1288 16.7437H26.8255C26.351 16.7437 25.9576 16.7437 25.6367 16.7159C25.3029 16.6869 24.9934 16.6246 24.7019 16.4669C24.2519 16.2234 23.8859 15.8348 23.6566 15.3569C23.5081 15.0474 23.4494 14.7188 23.4221 14.3644C23.3959 14.0237 23.3959 13.606 23.3959 13.1021V10.038C23.3959 9.53417 23.3959 9.11644 23.4221 8.77576C23.4494 8.42133 23.5081 8.09272 23.6566 7.7832C23.8747 7.32881 24.2162 6.95519 24.6362 6.71024V4.60922ZM32.0778 4.60922V6.40885C31.8062 6.39645 31.4912 6.39646 31.1288 6.39646H26.8255C26.4631 6.39646 26.148 6.39645 25.8765 6.40885V4.60922C25.8765 2.79093 27.2647 1.31692 28.9771 1.31692C30.6896 1.31692 32.0778 2.79093 32.0778 4.60922Z" fill="#D3D3D3" style="fill:#D3D3D3;fill:color(display-p3 0.8276 0.8276 0.8276);fill-opacity:1;"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M23.6566 7.7832C23.8472 7.3861 24.132 7.0507 24.4811 6.80894C24.5315 6.77406 24.5832 6.74113 24.6362 6.71024V4.60922C24.6362 2.06362 26.5797 0 28.9771 0C31.3746 0 33.3181 2.06362 33.3181 4.60922V6.71024C33.371 6.74113 33.4228 6.77406 33.4731 6.80894C33.8222 7.0507 34.1071 7.3861 34.2977 7.7832C34.4462 8.09272 34.5049 8.42133 34.5322 8.77576C34.5584 9.11644 34.5584 9.53416 34.5584 10.038V13.1021C34.5584 13.606 34.5584 14.0237 34.5322 14.3644C34.5049 14.7188 34.4462 15.0474 34.2977 15.3569C34.0683 15.8348 33.7024 16.2234 33.2523 16.4669C32.9608 16.6246 32.6513 16.6869 32.3175 16.7159C31.9967 16.7437 31.6033 16.7437 31.1288 16.7437H26.8255C26.351 16.7437 25.9576 16.7437 25.6367 16.7159C25.3029 16.6869 24.9934 16.6246 24.7019 16.4669C24.2519 16.2234 23.8859 15.8348 23.6566 15.3569C23.5081 15.0474 23.4494 14.7188 23.4221 14.3644C23.3959 14.0237 23.3959 13.606 23.3959 13.1021V10.038C23.3959 9.53417 23.3959 9.11644 23.4221 8.77576C23.4494 8.42133 23.5081 8.09272 23.6566 7.7832ZM32.0142 7.8027L32.4563 7.82288L32.6151 7.9155C32.7858 8.01506 32.9381 8.17515 33.0397 8.38686C33.0818 8.47465 33.1199 8.60867 33.141 8.88281C33.1622 9.1581 33.1631 9.51485 33.1631 10.038V13.1022C33.1631 13.6253 33.1622 13.9821 33.141 14.2573C33.1199 14.5315 33.0818 14.6655 33.0397 14.7533C32.9328 14.976 32.7699 15.1414 32.5884 15.2396C32.5333 15.2694 32.4372 15.3049 32.197 15.3258C31.9497 15.3472 31.6251 15.3484 31.1289 15.3484H26.8255C26.3292 15.3484 26.0045 15.3472 25.7573 15.3258C25.5171 15.3049 25.4209 15.2694 25.3659 15.2396C25.1843 15.1414 25.0215 14.976 24.9146 14.7533C24.8725 14.6655 24.8344 14.5315 24.8133 14.2573C24.7921 13.982 24.7912 13.6253 24.7912 13.1021V10.038C24.7912 9.51484 24.7921 9.1581 24.8133 8.88281C24.8344 8.60866 24.8725 8.47465 24.9146 8.38686C25.0162 8.17514 25.1685 8.01506 25.3392 7.9155L25.498 7.82288L25.9401 7.8027C26.1732 7.79206 26.4533 7.79176 26.8255 7.79177H31.1288C31.5011 7.79176 31.7811 7.79206 32.0142 7.8027ZM26.1865 4.53887C26.1865 2.75654 27.4798 1.39531 28.9771 1.39531C30.4745 1.39531 31.7678 2.75654 31.7678 4.53887V6.0344C31.6024 6.03275 31.4277 6.03275 31.2451 6.03276H26.7093C26.5266 6.03275 26.3519 6.03275 26.1865 6.0344V4.53887Z" fill="#77736B" style="fill:#77736B;fill:color(display-p3 0.4668 0.4528 0.4212);fill-opacity:1;"/>
</svg>

After

Width:  |  Height:  |  Size: 6.7 KiB

View File

@ -0,0 +1,17 @@
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_11_324)">
<path d="M12.7584 7.51766C11.468 5.81975 8.97599 5.65063 7.468 7.15862L6.7125 7.91411C4.29621 10.3304 3.09176 13.8063 4.1996 17.0389C5.79923 21.7065 8.4611 26.0907 12.1852 29.8148C15.9093 33.5389 20.2935 36.2008 24.9611 37.8004C28.1937 38.9082 31.6696 37.7038 34.0859 35.2875L34.8414 34.532C36.3494 33.024 36.1802 30.532 34.4823 29.2416L29.5336 25.4806C28.1325 24.4157 26.1601 24.5496 24.9157 25.794L22.7613 27.9484C22.0741 28.6356 19.5673 27.2429 17.1622 24.8378C14.7571 22.4327 13.3644 19.9259 14.0516 19.2387L16.206 17.0843C17.4504 15.8399 17.5843 13.8675 16.5194 12.4664L12.7584 7.51766Z" fill="#F3D48F" style="fill:#F3D48F;fill:color(display-p3 0.9527 0.8304 0.5627);fill-opacity:1;"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M16.5388 16.7049C17.557 15.4732 17.6096 13.6839 16.6253 12.3887L12.9103 7.50064C11.6977 5.9051 9.41087 5.6763 7.90869 6.94039C8.09043 11.8855 11.7654 15.9385 16.5388 16.7049ZM24.6261 25.8459L24.9188 25.5532C26.148 24.324 28.0962 24.1918 29.4802 25.2436L34.3684 28.9585C35.6697 29.9476 36.0619 31.6512 35.4764 33.0608C35.1409 33.0939 34.8006 33.1108 34.4563 33.1108C29.8281 33.1108 25.9143 30.0521 24.6261 25.8459Z" fill="#DBB96E" style="fill:#DBB96E;fill:color(display-p3 0.8588 0.7255 0.4314);fill-opacity:1;"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.45199 6.6536L6.20749 5.89811C8.47933 3.62627 12.2336 3.88106 14.1776 6.43903L17.9387 11.3877C19.5429 13.4986 19.3413 16.47 17.4665 18.3448L15.7667 20.0446C15.8205 20.1727 15.8976 20.3338 16.0056 20.5283C16.4675 21.3598 17.3031 22.4576 18.4227 23.5773C19.5424 24.6969 20.6402 25.5325 21.4717 25.9944C21.6662 26.1025 21.8273 26.1795 21.9554 26.2333L23.6552 24.5335C25.53 22.6587 28.5014 22.4571 30.6123 24.0613L35.561 27.8224C38.1189 29.7664 38.3737 33.5207 36.1019 35.7925L35.3464 36.548C32.5717 39.3227 28.4091 40.8665 24.3831 39.4867C19.4642 37.801 14.8451 34.9957 10.9247 31.0753C7.00431 27.1549 4.19902 22.5358 2.51325 17.6169C1.13353 13.5909 2.67732 9.42828 5.45199 6.6536ZM22.313 26.3462C22.313 26.3462 22.3061 26.3461 22.2901 26.3434C22.3047 26.3444 22.313 26.3462 22.313 26.3462ZM15.6538 19.687C15.6538 19.687 15.6556 19.6953 15.6566 19.7099C15.6539 19.6939 15.6538 19.687 15.6538 19.687ZM7.468 7.15862C8.97599 5.65063 11.468 5.81975 12.7584 7.51766L16.5194 12.4664C17.5843 13.8675 17.4504 15.8399 16.206 17.0843L14.0516 19.2387C13.3644 19.9259 14.7571 22.4327 17.1622 24.8378C19.5673 27.2429 22.0741 28.6356 22.7613 27.9484L24.9157 25.794C26.1601 24.5496 28.1325 24.4157 29.5336 25.4806L34.4823 29.2416C36.1802 30.532 36.3494 33.024 34.8414 34.532L34.0859 35.2875C31.6696 37.7038 28.1937 38.9082 24.9611 37.8004C20.2935 36.2008 15.9093 33.5389 12.1852 29.8148C8.4611 26.0907 5.79923 21.7065 4.1996 17.0389C3.09176 13.8063 4.29621 10.3304 6.7125 7.91411L7.468 7.15862Z" fill="black" style="fill:black;fill-opacity:1;"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M28.7417 0.7799C26.2804 0.7799 24.2852 2.77517 24.2852 5.23647V7.0191H26.9591V5.23647C26.9591 4.25195 27.7572 3.45384 28.7417 3.45384C29.7263 3.45384 30.5244 4.25195 30.5244 5.23647V7.0191H33.1983V5.23647C33.1983 2.77517 31.203 0.7799 28.7417 0.7799Z" fill="#D9D9D9" style="fill:#D9D9D9;fill:color(display-p3 0.8510 0.8510 0.8510);fill-opacity:1;"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M28.7417 1.5598C26.7112 1.5598 25.0651 3.2059 25.0651 5.23647V7.91041H23.5053V5.23647C23.5053 2.34445 25.8497 0 28.7417 0C31.6338 0 33.9782 2.34445 33.9782 5.23647V7.91041H32.4184V5.23647C32.4184 3.2059 30.7723 1.5598 28.7417 1.5598Z" fill="black" style="fill:black;fill-opacity:1;"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M28.7417 4.23374C28.188 4.23374 27.739 4.68268 27.739 5.23647V7.0191H26.1792V5.23647C26.1792 3.82122 27.3265 2.67394 28.7417 2.67394C30.157 2.67394 31.3043 3.82122 31.3043 5.23647V7.0191H29.7445V5.23647C29.7445 4.68268 29.2955 4.23374 28.7417 4.23374Z" fill="black" style="fill:black;fill-opacity:1;"/>
<path d="M23.8395 9.69304C23.8395 8.70852 24.6376 7.91041 25.6221 7.91041H31.8613C32.8459 7.91041 33.644 8.70852 33.644 9.69304V15.0409C33.644 16.0254 32.8459 16.8235 31.8613 16.8235H25.6221C24.6376 16.8235 23.8395 16.0254 23.8395 15.0409V9.69304Z" fill="#D3D3D3" style="fill:#D3D3D3;fill:color(display-p3 0.8276 0.8276 0.8276);fill-opacity:1;"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M25.6221 6.39518H31.8613C33.6827 6.39518 35.1592 7.87168 35.1592 9.69304V15.0409C35.1592 16.8623 33.6827 18.3388 31.8613 18.3388H25.6221C23.8008 18.3388 22.3243 16.8623 22.3243 15.0409V9.69304C22.3243 7.87168 23.8008 6.39518 25.6221 6.39518ZM25.6221 7.91041C24.6376 7.91041 23.8395 8.70852 23.8395 9.69304V15.0409C23.8395 16.0254 24.6376 16.8235 25.6221 16.8235H31.8613C32.8459 16.8235 33.644 16.0254 33.644 15.0409V9.69304C33.644 8.70852 32.8459 7.91041 31.8613 7.91041H25.6221Z" fill="black" style="fill:black;fill-opacity:1;"/>
</g>
<defs>
<clipPath id="clip0_11_324">
<rect width="40" height="40" fill="white" style="fill:white;fill-opacity:1;"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 5.0 KiB

View File

@ -1,23 +0,0 @@
<svg width="32" height="34" viewBox="0 0 32 34" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M25.5918 26.1585C24.9159 25.4686 24.9159 24.359 25.5918 23.6691L27.8097 21.405C28.7087 20.4872 28.7087 18.9901 27.8097 18.0723C26.9229 17.167 25.4945 17.167 24.6077 18.0723L22.3898 20.3365C21.7017 21.0389 20.5766 21.0389 19.8885 20.3365C19.2127 19.6465 19.2127 18.537 19.8885 17.8471L22.1065 15.5829C24.3694 13.2728 28.0479 13.2728 30.3109 15.5829M24.7831 22.1648L25.5585 22.9243L21.7563 26.8056C21.0683 27.5081 19.9432 27.5081 19.2551 26.8056C18.5793 26.1157 18.5793 25.0062 19.2551 24.3163L23.0573 20.4349C23.7453 19.7325 24.8704 19.7325 25.5585 20.4349C26.2343 21.1248 26.2343 22.2343 25.5585 22.9243L24.7831 22.1648ZM24.7831 22.1648L20.981 26.0461C20.7185 26.3141 20.2929 26.3141 20.0305 26.0461C19.768 25.7782 19.768 25.3437 20.0305 25.0758L23.8326 21.1944C24.0951 20.9265 24.5207 20.9265 24.7831 21.1944C25.0456 21.4624 25.0456 21.8968 24.7831 22.1648ZM30.3109 15.5829C32.5617 17.8806 32.5617 21.5967 30.3109 23.8944L28.093 26.1585C27.4049 26.8609 26.2799 26.8609 25.5918 26.1585M19.2217 21.0818C19.8975 21.7718 19.8975 22.8813 19.2217 23.5712L17.0037 25.8354C16.1047 26.7531 16.1047 28.2502 17.0037 29.168C17.8906 30.0733 19.3189 30.0733 20.2057 29.168L22.4237 26.9039C23.1118 26.2015 24.2368 26.2015 24.9249 26.9039C25.6008 27.5938 25.6007 28.7033 24.9249 29.3933L22.707 31.6574C20.444 33.9675 16.7655 33.9675 14.5025 31.6574C12.2518 29.3598 12.2518 25.6436 14.5025 23.346L16.7204 21.0818C17.4085 20.3794 18.5336 20.3794 19.2217 21.0818ZM26.3671 24.4286C26.1046 24.6966 26.1046 25.131 26.3671 25.399C26.6296 25.6669 27.0552 25.6669 27.3177 25.399L29.5356 23.1349C31.373 21.2592 31.373 18.2181 29.5356 16.3425C27.6982 14.4668 24.7192 14.4668 22.8818 16.3425L20.6639 18.6066C20.4014 18.8745 20.4014 19.309 20.6639 19.5769C20.9264 19.8449 21.3519 19.8449 21.6144 19.5769L23.8323 17.3128C25.1448 15.973 27.2726 15.973 28.585 17.3128C29.8975 18.6526 29.8975 20.8247 28.585 22.1645L26.3671 24.4286ZM18.4463 22.8117C18.7088 22.5438 18.7088 22.1093 18.4463 21.8414C18.1838 21.5734 17.7583 21.5734 17.4958 21.8414L15.2779 24.1055C13.4405 25.9812 13.4405 29.0222 15.2779 30.8979C17.1153 32.7735 20.0942 32.7735 21.9316 30.8979L24.1496 28.6338C24.412 28.3658 24.412 27.9314 24.1496 27.6634C23.8871 27.3955 23.4615 27.3955 23.199 27.6634L20.9811 29.9275C19.6687 31.2673 17.5408 31.2673 16.2284 29.9275C14.916 28.5878 14.916 26.4156 16.2284 25.0758L18.4463 22.8117Z" fill="#647392"/>
<path d="M2.56503 5.82115C2.56503 4.6814 2.56503 4.11153 2.78684 3.6762C2.98195 3.29328 3.29328 2.98195 3.6762 2.78684C4.11153 2.56503 4.6814 2.56503 5.82115 2.56503H6.30448C7.44422 2.56503 8.0141 2.56503 8.44942 2.78684C8.83234 2.98195 9.14367 3.29328 9.33878 3.6762C9.56059 4.11153 9.56059 4.6814 9.56059 5.82115V6.30448C9.56059 7.44422 9.56059 8.0141 9.33878 8.44942C9.14367 8.83234 8.83234 9.14367 8.44942 9.33878C8.0141 9.56059 7.44422 9.56059 6.30448 9.56059H5.82115C4.6814 9.56059 4.11153 9.56059 3.6762 9.33878C3.29328 9.14367 2.98195 8.83234 2.78684 8.44942C2.56503 8.0141 2.56503 7.44422 2.56503 6.30448V5.82115Z" fill="#C2E0F0"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.79619 1.97147H6.32943C6.87811 1.97146 7.32581 1.97145 7.68944 2.00116C8.0655 2.03189 8.4036 2.09732 8.71889 2.25797C9.2135 2.50999 9.61563 2.91212 9.86764 3.40673C10.0283 3.72201 10.0937 4.06012 10.1245 4.43618C10.1542 4.79981 10.1542 5.2475 10.1541 5.79617V6.32944C10.1542 6.87811 10.1542 7.32581 10.1245 7.68944C10.0937 8.0655 10.0283 8.4036 9.86764 8.71889C9.61563 9.2135 9.2135 9.61563 8.71889 9.86764C8.4036 10.0283 8.0655 10.0937 7.68944 10.1245C7.32581 10.1542 6.87811 10.1542 6.32944 10.1541H5.79617C5.2475 10.1542 4.79981 10.1542 4.43618 10.1245C4.06012 10.0937 3.72201 10.0283 3.40673 9.86764C2.91212 9.61563 2.50999 9.2135 2.25797 8.71889C2.09732 8.4036 2.03189 8.0655 2.00116 7.68944C1.97145 7.32581 1.97146 6.87811 1.97147 6.32943V5.79619C1.97146 5.24751 1.97145 4.79981 2.00116 4.43618C2.03189 4.06012 2.09732 3.72201 2.25797 3.40673C2.50999 2.91212 2.91212 2.50999 3.40673 2.25797C3.72201 2.09732 4.06012 2.03189 4.43618 2.00116C4.79981 1.97145 5.24751 1.97146 5.79619 1.97147ZM4.53285 3.18435C4.2302 3.20907 4.06571 3.25454 3.94567 3.31571C3.67443 3.45391 3.45391 3.67443 3.31571 3.94567C3.25454 4.06571 3.20907 4.2302 3.18435 4.53285C3.15905 4.84242 3.15859 5.24147 3.15859 5.82114V6.30447C3.15859 6.88414 3.15905 7.28319 3.18435 7.59277C3.20907 7.89541 3.25454 8.0599 3.31571 8.17995C3.45391 8.45118 3.67443 8.67171 3.94567 8.80991C4.06571 8.87107 4.2302 8.91654 4.53285 8.94127C4.84242 8.96656 5.24147 8.96702 5.82114 8.96702H6.30447C6.88414 8.96702 7.28319 8.96656 7.59277 8.94127C7.89541 8.91654 8.0599 8.87107 8.17995 8.80991C8.45118 8.67171 8.67171 8.45118 8.80991 8.17995C8.87107 8.0599 8.91654 7.89541 8.94127 7.59277C8.96656 7.28319 8.96702 6.88414 8.96702 6.30447V5.82114C8.96702 5.24147 8.96656 4.84242 8.94127 4.53285C8.91654 4.2302 8.87107 4.06571 8.80991 3.94567C8.67171 3.67443 8.45118 3.45391 8.17995 3.31571C8.0599 3.25454 7.89541 3.20907 7.59277 3.18435C7.28319 3.15905 6.88414 3.15859 6.30447 3.15859H5.82114C5.24147 3.15859 4.84242 3.15905 4.53285 3.18435Z" fill="#628192"/>
<path d="M2.56503 16.0813C2.56503 14.9416 2.56503 14.3717 2.78684 13.9364C2.98195 13.5534 3.29328 13.2421 3.6762 13.047C4.11153 12.8252 4.6814 12.8252 5.82115 12.8252H6.30448C7.44422 12.8252 8.0141 12.8252 8.44942 13.047C8.83234 13.2421 9.14367 13.5534 9.33878 13.9364C9.56059 14.3717 9.56059 14.9416 9.56059 16.0813V16.5646C9.56059 17.7044 9.56059 18.2743 9.33878 18.7096C9.14367 19.0925 8.83234 19.4038 8.44942 19.5989C8.0141 19.8208 7.44422 19.8208 6.30448 19.8208H5.82115C4.6814 19.8208 4.11153 19.8208 3.6762 19.5989C3.29328 19.4038 2.98195 19.0925 2.78684 18.7096C2.56503 18.2743 2.56503 17.7044 2.56503 16.5646V16.0813Z" fill="#C2E0F0"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.79619 12.2316H6.32943C6.87811 12.2316 7.32581 12.2316 7.68944 12.2613C8.0655 12.2921 8.4036 12.3575 8.71889 12.5181C9.2135 12.7701 9.61563 13.1723 9.86764 13.6669C10.0283 13.9822 10.0937 14.3203 10.1245 14.6963C10.1542 15.06 10.1542 15.5077 10.1541 16.0563V16.5896C10.1542 17.1383 10.1542 17.586 10.1245 17.9496C10.0937 18.3257 10.0283 18.6638 9.86764 18.9791C9.61563 19.4737 9.2135 19.8758 8.71889 20.1278C8.4036 20.2885 8.0655 20.3539 7.68944 20.3846C7.32581 20.4143 6.87811 20.4143 6.32944 20.4143H5.79617C5.2475 20.4143 4.79981 20.4143 4.43618 20.3846C4.06012 20.3539 3.72201 20.2885 3.40673 20.1278C2.91212 19.8758 2.50999 19.4737 2.25797 18.9791C2.09732 18.6638 2.03189 18.3257 2.00116 17.9496C1.97145 17.586 1.97146 17.1383 1.97147 16.5896V16.0564C1.97146 15.5077 1.97145 15.06 2.00116 14.6963C2.03189 14.3203 2.09732 13.9822 2.25797 13.6669C2.50999 13.1723 2.91212 12.7701 3.40673 12.5181C3.72201 12.3575 4.06012 12.2921 4.43618 12.2613C4.79981 12.2316 5.24751 12.2316 5.79619 12.2316ZM4.53285 13.4445C4.2302 13.4692 4.06571 13.5147 3.94567 13.5759C3.67443 13.7141 3.45391 13.9346 3.31571 14.2058C3.25454 14.3259 3.20907 14.4904 3.18435 14.793C3.15905 15.1026 3.15859 15.5016 3.15859 16.0813V16.5646C3.15859 17.1443 3.15905 17.5434 3.18435 17.8529C3.20907 18.1556 3.25454 18.3201 3.31571 18.4401C3.45391 18.7113 3.67443 18.9319 3.94567 19.0701C4.06571 19.1312 4.2302 19.1767 4.53285 19.2014C4.84242 19.2267 5.24147 19.2272 5.82114 19.2272H6.30447C6.88414 19.2272 7.28319 19.2267 7.59277 19.2014C7.89541 19.1767 8.0599 19.1312 8.17995 19.0701C8.45118 18.9319 8.67171 18.7113 8.80991 18.4401C8.87107 18.3201 8.91654 18.1556 8.94127 17.8529C8.96656 17.5434 8.96702 17.1443 8.96702 16.5646V16.0813C8.96702 15.5016 8.96656 15.1026 8.94127 14.793C8.91654 14.4904 8.87107 14.3259 8.80991 14.2058C8.67171 13.9346 8.45118 13.7141 8.17995 13.5759C8.0599 13.5147 7.89541 13.4692 7.59277 13.4445C7.28319 13.4192 6.88414 13.4188 6.30447 13.4188H5.82114C5.24147 13.4188 4.84242 13.4192 4.53285 13.4445Z" fill="#628192"/>
<path d="M12.8252 5.82115C12.8252 4.6814 12.8252 4.11153 13.047 3.6762C13.2421 3.29328 13.5534 2.98195 13.9364 2.78684C14.3717 2.56503 14.9416 2.56503 16.0813 2.56503H16.5646C17.7044 2.56503 18.2743 2.56503 18.7096 2.78684C19.0925 2.98195 19.4038 3.29328 19.5989 3.6762C19.8208 4.11153 19.8208 4.6814 19.8208 5.82115V6.30448C19.8208 7.44422 19.8208 8.0141 19.5989 8.44942C19.4038 8.83234 19.0925 9.14367 18.7096 9.33878C18.2743 9.56059 17.7044 9.56059 16.5646 9.56059H16.0813C14.9416 9.56059 14.3717 9.56059 13.9364 9.33878C13.5534 9.14367 13.2421 8.83234 13.047 8.44942C12.8252 8.0141 12.8252 7.44422 12.8252 6.30448V5.82115Z" fill="#C2E0F0"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M16.0564 1.97147H16.5896C17.1383 1.97146 17.586 1.97145 17.9496 2.00116C18.3257 2.03189 18.6638 2.09732 18.9791 2.25797C19.4737 2.50999 19.8758 2.91212 20.1278 3.40673C20.2885 3.72201 20.3539 4.06012 20.3846 4.43618C20.4143 4.79981 20.4143 5.2475 20.4143 5.79617V6.32944C20.4143 6.87811 20.4143 7.32581 20.3846 7.68944C20.3539 8.0655 20.2885 8.4036 20.1278 8.71889C19.8758 9.2135 19.4737 9.61563 18.9791 9.86764C18.6638 10.0283 18.3257 10.0937 17.9496 10.1245C17.586 10.1542 17.1383 10.1542 16.5896 10.1541H16.0563C15.5077 10.1542 15.06 10.1542 14.6963 10.1245C14.3203 10.0937 13.9822 10.0283 13.6669 9.86764C13.1723 9.61563 12.7701 9.2135 12.5181 8.71889C12.3575 8.4036 12.2921 8.0655 12.2613 7.68944C12.2316 7.32581 12.2316 6.87811 12.2316 6.32943V5.79619C12.2316 5.24751 12.2316 4.79981 12.2613 4.43618C12.2921 4.06012 12.3575 3.72201 12.5181 3.40673C12.7701 2.91212 13.1723 2.50999 13.6669 2.25797C13.9822 2.09732 14.3203 2.03189 14.6963 2.00116C15.06 1.97145 15.5077 1.97146 16.0564 1.97147ZM14.793 3.18435C14.4904 3.20907 14.3259 3.25454 14.2058 3.31571C13.9346 3.45391 13.7141 3.67443 13.5759 3.94567C13.5147 4.06571 13.4692 4.2302 13.4445 4.53285C13.4192 4.84242 13.4188 5.24147 13.4188 5.82114V6.30447C13.4188 6.88414 13.4192 7.28319 13.4445 7.59277C13.4692 7.89541 13.5147 8.0599 13.5759 8.17995C13.7141 8.45118 13.9346 8.67171 14.2058 8.80991C14.3259 8.87107 14.4904 8.91654 14.793 8.94127C15.1026 8.96656 15.5016 8.96702 16.0813 8.96702H16.5646C17.1443 8.96702 17.5434 8.96656 17.8529 8.94127C18.1556 8.91654 18.3201 8.87107 18.4401 8.80991C18.7113 8.67171 18.9319 8.45118 19.0701 8.17995C19.1312 8.0599 19.1767 7.89541 19.2014 7.59277C19.2267 7.28319 19.2272 6.88414 19.2272 6.30447V5.82114C19.2272 5.24147 19.2267 4.84242 19.2014 4.53285C19.1767 4.2302 19.1312 4.06571 19.0701 3.94567C18.9319 3.67443 18.7113 3.45391 18.4401 3.31571C18.3201 3.25454 18.1556 3.20907 17.8529 3.18435C17.5434 3.15905 17.1443 3.15859 16.5646 3.15859H16.0813C15.5016 3.15859 15.1026 3.15905 14.793 3.18435Z" fill="#628192"/>
<path d="M13.0584 13.3976C13.0584 13.2102 13.2102 13.0584 13.3976 13.0584H14.1183C14.3056 13.0584 14.4575 13.2102 14.4575 13.3976V14.1183C14.4575 14.3056 14.3056 14.4575 14.1183 14.4575H13.3976C13.2102 14.4575 13.0584 14.3056 13.0584 14.1183V13.3976Z" fill="#628192"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.7192 13.3976C12.7192 13.0229 13.0229 12.7192 13.3976 12.7192H14.1183C14.493 12.7192 14.7967 13.0229 14.7967 13.3976V14.1183C14.7967 14.493 14.493 14.7967 14.1183 14.7967H13.3976C13.0229 14.7967 12.7192 14.493 12.7192 14.1183V13.3976ZM14.1183 13.3976H13.3976V14.1183H14.1183V13.3976Z" fill="#628192"/>
<path d="M15.6234 15.9626C15.6234 15.7753 15.7753 15.6234 15.9626 15.6234H16.6833C16.8707 15.6234 17.0225 15.7753 17.0225 15.9626V16.6833C17.0225 16.8707 16.8707 17.0225 16.6833 17.0225H15.9626C15.7753 17.0225 15.6234 16.8707 15.6234 16.6833V15.9626Z" fill="#628192"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M15.2842 15.9626C15.2842 15.588 15.588 15.2842 15.9626 15.2842H16.6834C17.058 15.2842 17.3617 15.588 17.3617 15.9626V16.6834C17.3617 17.058 17.058 17.3617 16.6834 17.3617H15.9626C15.588 17.3617 15.2842 17.058 15.2842 16.6834V15.9626ZM16.6834 15.9626H15.9626V16.6834H16.6834V15.9626Z" fill="#628192"/>
<path d="M5.36325 15.9626C5.36325 15.7753 5.51511 15.6234 5.70243 15.6234H6.42318C6.61051 15.6234 6.76236 15.7753 6.76236 15.9626V16.6833C6.76236 16.8707 6.61051 17.0225 6.42318 17.0225H5.70243C5.51511 17.0225 5.36325 16.8707 5.36325 16.6833V15.9626Z" fill="#628192"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M4.68491 15.9626C4.68491 15.4006 5.14047 14.9451 5.70244 14.9451H6.4232C6.98517 14.9451 7.44073 15.4006 7.44073 15.9626V16.6834C7.44073 17.2453 6.98517 17.7009 6.4232 17.7009H5.70244C5.14047 17.7009 4.68491 17.2453 4.68491 16.6834V15.9626ZM6.04162 16.3018V16.3442H6.08402V16.3018H6.04162Z" fill="#628192"/>
<path d="M5.36325 5.70243C5.36325 5.51511 5.51511 5.36325 5.70243 5.36325H6.42318C6.61051 5.36325 6.76236 5.51511 6.76236 5.70243V6.42318C6.76236 6.61051 6.61051 6.76236 6.42318 6.76236H5.70243C5.51511 6.76236 5.36325 6.61051 5.36325 6.42318V5.70243Z" fill="#628192"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M4.68491 5.70244C4.68491 5.14047 5.14047 4.68491 5.70244 4.68491H6.4232C6.98517 4.68491 7.44073 5.14047 7.44073 5.70244V6.4232C7.44073 6.98517 6.98517 7.44073 6.4232 7.44073H5.70244C5.14047 7.44073 4.68491 6.98517 4.68491 6.4232V5.70244ZM6.04162 6.04162V6.08402H6.08402V6.04162H6.04162Z" fill="#628192"/>
<path d="M15.6234 5.70243C15.6234 5.51511 15.7753 5.36325 15.9626 5.36325H16.6833C16.8707 5.36325 17.0225 5.51511 17.0225 5.70243V6.42318C17.0225 6.61051 16.8707 6.76236 16.6833 6.76236H15.9626C15.7753 6.76236 15.6234 6.61051 15.6234 6.42318V5.70243Z" fill="#628192"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M14.9451 5.70244C14.9451 5.14047 15.4006 4.68491 15.9626 4.68491H16.6834C17.2453 4.68491 17.7009 5.14047 17.7009 5.70244V6.4232C17.7009 6.98517 17.2453 7.44073 16.6834 7.44073H15.9626C15.4006 7.44073 14.9451 6.98517 14.9451 6.4232V5.70244ZM16.3018 6.04162V6.08402H16.3442V6.04162H16.3018Z" fill="#628192"/>
<path d="M18.1884 13.3976C18.1884 13.2102 18.3403 13.0584 18.5276 13.0584H19.2484C19.4357 13.0584 19.5876 13.2102 19.5876 13.3976V14.1183C19.5876 14.3056 19.4357 14.4575 19.2484 14.4575H18.5276C18.3403 14.4575 18.1884 14.3056 18.1884 14.1183V13.3976Z" fill="#628192"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M17.8493 13.3976C17.8493 13.0229 18.153 12.7192 18.5276 12.7192H19.2484C19.623 12.7192 19.9267 13.0229 19.9267 13.3976V14.1183C19.9267 14.493 19.623 14.7967 19.2484 14.7967H18.5276C18.153 14.7967 17.8493 14.493 17.8493 14.1183V13.3976ZM19.2484 13.3976H18.5276V14.1183H19.2484V13.3976Z" fill="#628192"/>
<path d="M13.0584 18.5276C13.0584 18.3403 13.2102 18.1884 13.3976 18.1884H14.1183C14.3056 18.1884 14.4575 18.3403 14.4575 18.5276V19.2484C14.4575 19.4357 14.3056 19.5876 14.1183 19.5876H13.3976C13.2102 19.5876 13.0584 19.4357 13.0584 19.2484V18.5276Z" fill="#628192"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.7192 18.5276C12.7192 18.153 13.0229 17.8493 13.3976 17.8493H14.1183C14.493 17.8493 14.7967 18.153 14.7967 18.5276V19.2484C14.7967 19.623 14.493 19.9267 14.1183 19.9267H13.3976C13.0229 19.9267 12.7192 19.623 12.7192 19.2484V18.5276ZM14.1183 18.5276H13.3976V19.2484H14.1183V18.5276Z" fill="#628192"/>
</svg>

Before

Width:  |  Height:  |  Size: 15 KiB

View File

@ -0,0 +1,32 @@
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(-0.9 13) rotate(-15)">
<rect width="28.9" height="28.9" fill="#8ab8d1" style="fill:#8AB8D1;fill:color(display-p3 0.5403 0.7217 0.8212);fill-opacity:1;stroke:#5C8FAB;stroke:color(display-p3 0.3614 0.5616 0.6714);" stroke-width="1.65" stroke="#5c8fab" rx="7.7"/>
</g>
<path d="M6.0521 19.1251C5.67171 17.7043 6.51507 16.2439 7.9358 15.8632L20.7981 12.4168C22.2188 12.0361 23.6789 12.8793 24.0593 14.3001L27.5031 27.1631C27.8835 28.5839 27.0401 30.0443 25.6194 30.4249L12.7571 33.8714C11.3364 34.2521 9.87629 33.4089 9.4959 31.9881L6.0521 19.1251Z" fill="white" style="fill:white;fill-opacity:1;"/>
<path d="M11.6481 20.5708C11.58 20.3165 11.7309 20.0551 11.9852 19.987L12.5991 19.8225C12.8534 19.7544 13.1147 19.9053 13.1828 20.1596L13.3471 20.7735C13.4152 21.0278 13.2643 21.2892 13.01 21.3573L12.3961 21.5218C12.1418 21.5899 11.8805 21.439 11.8124 21.1847L11.6481 20.5708Z" fill="#8AB8D1" style="fill:#8AB8D1;fill:color(display-p3 0.5403 0.7217 0.8212);fill-opacity:1;"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M10.8886 18.0602L12.5862 17.6053C12.8269 17.5408 13.039 17.484 13.2185 17.4513C13.4094 17.4165 13.6108 17.3991 13.8231 17.4442C14.1349 17.5105 14.4176 17.6738 14.6308 17.9107C14.7761 18.072 14.8617 18.2552 14.9269 18.4379C14.9883 18.6097 15.0451 18.8218 15.1095 19.0625L15.5641 20.7602C15.6285 21.0009 15.6853 21.2131 15.718 21.3926C15.7527 21.5834 15.7701 21.7849 15.7249 21.9972C15.6586 22.309 15.4953 22.5918 15.2584 22.8051C15.097 22.9504 14.9139 23.036 14.7312 23.1013C14.5594 23.1627 14.3473 23.2196 14.1066 23.2841L12.409 23.7389C12.1683 23.8034 11.9561 23.8603 11.7767 23.893C11.5858 23.9278 11.3844 23.9452 11.1721 23.9C10.8603 23.8338 10.5776 23.6705 10.3643 23.4336C10.2191 23.2722 10.1335 23.0891 10.0683 22.9064C10.0069 22.7346 9.95008 22.5224 9.88564 22.2817L9.43114 20.5841C9.36667 20.3434 9.30986 20.1312 9.27719 19.9517C9.24244 19.7608 9.22509 19.5594 9.27026 19.3471C9.33659 19.0353 9.49991 18.7524 9.73682 18.5392C9.89817 18.3939 10.0813 18.3082 10.264 18.2429C10.4358 18.1815 10.6479 18.1247 10.8886 18.0602ZM10.6381 19.2903C10.5204 19.3324 10.4896 19.3578 10.4808 19.3657C10.4185 19.4219 10.3755 19.4963 10.358 19.5783C10.3556 19.5899 10.3489 19.6293 10.3713 19.7523C10.3949 19.8817 10.4394 20.0495 10.5108 20.3163L10.9546 21.9738C11.026 22.2406 11.0713 22.4082 11.1156 22.532C11.1576 22.6497 11.1831 22.6806 11.191 22.6893C11.2471 22.7517 11.3215 22.7947 11.4035 22.8121C11.415 22.8145 11.4545 22.8212 11.5775 22.7988C11.7068 22.7752 11.8747 22.7307 12.1414 22.6592L13.7989 22.2151C14.0656 22.1436 14.2332 22.0983 14.357 22.054C14.4747 22.0119 14.5056 21.9864 14.5144 21.9785C14.5767 21.9224 14.6197 21.848 14.6371 21.7659C14.6396 21.7544 14.6462 21.715 14.6239 21.592C14.6003 21.4626 14.5558 21.2947 14.4844 21.028L14.0406 19.3704C13.9692 19.1037 13.9239 18.9361 13.8796 18.8122C13.8376 18.6945 13.8121 18.6637 13.8042 18.6549C13.7481 18.5926 13.6737 18.5496 13.5917 18.5322C13.5801 18.5297 13.5407 18.5231 13.4177 18.5455C13.2884 18.5691 13.1205 18.6136 12.8538 18.6851L11.1963 19.1292C10.9296 19.2007 10.762 19.246 10.6381 19.2903Z" fill="#8AB8D1" style="fill:#8AB8D1;fill:color(display-p3 0.5403 0.7217 0.8212);fill-opacity:1;"/>
<path d="M13.7932 26.7401C13.5389 26.8082 13.388 27.0696 13.4561 27.3239L13.6204 27.9378C13.6885 28.1921 13.9498 28.343 14.2041 28.2748L14.818 28.1104C15.0723 28.0422 15.2232 27.7808 15.1551 27.5266L14.9908 26.9126C14.9227 26.6583 14.6614 26.5074 14.4071 26.5756L13.7932 26.7401Z" fill="#8AB8D1" style="fill:#8AB8D1;fill:color(display-p3 0.5403 0.7217 0.8212);fill-opacity:1;"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.6966 24.8133L14.3942 24.3584C14.6349 24.2939 14.847 24.2371 15.0265 24.2043C15.2174 24.1696 15.4188 24.1522 15.6311 24.1973C15.9429 24.2636 16.2256 24.4269 16.4388 24.6638C16.5841 24.8251 16.6697 25.0082 16.7349 25.1909C16.7963 25.3627 16.8531 25.5749 16.9175 25.8156L17.372 27.5133C17.4365 27.754 17.4933 27.9662 17.526 28.1456C17.5607 28.3365 17.5781 28.5379 17.5329 28.7503C17.4666 29.0621 17.3033 29.3449 17.0664 29.5582C16.905 29.7035 16.7219 29.7891 16.5392 29.8544C16.3674 29.9158 16.1553 29.9727 15.9145 30.0371L14.217 30.492C13.9763 30.5565 13.7641 30.6134 13.5847 30.6461C13.3938 30.6809 13.1924 30.6982 12.9801 30.6531C12.6683 30.5868 12.3856 30.4235 12.1723 30.1866C12.0271 30.0253 11.9415 29.8422 11.8762 29.6595C11.8149 29.4877 11.7581 29.2755 11.6936 29.0348L11.2391 27.3372C11.1747 27.0964 11.1179 26.8843 11.0852 26.7048C11.0504 26.5139 11.0331 26.3125 11.0783 26.1001C11.1446 25.7883 11.3079 25.5055 11.5448 25.2922C11.7062 25.147 11.8893 25.0613 12.072 24.996C12.2438 24.9346 12.4559 24.8778 12.6966 24.8133ZM12.4461 26.0434C12.3284 26.0854 12.2976 26.1109 12.2888 26.1188C12.2265 26.1749 12.1835 26.2494 12.166 26.3314C12.1636 26.3429 12.1569 26.3824 12.1793 26.5054C12.2029 26.6347 12.2474 26.8026 12.3188 27.0693L12.7626 28.7269C12.834 28.9936 12.8793 29.1613 12.9235 29.2851C12.9656 29.4028 12.9911 29.4337 12.9989 29.4424C13.0551 29.5048 13.1295 29.5477 13.2115 29.5652C13.223 29.5676 13.2625 29.5743 13.3855 29.5518C13.5148 29.5283 13.6827 29.4837 13.9494 29.4123L15.6069 28.9682C15.8736 28.8967 16.0412 28.8513 16.165 28.8071C16.2827 28.765 16.3136 28.7395 16.3224 28.7316C16.3847 28.6755 16.4277 28.6011 16.4451 28.519C16.4476 28.5075 16.4542 28.468 16.4318 28.3451C16.4083 28.2157 16.3638 28.0478 16.2924 27.7811L15.8486 26.1235C15.7772 25.8568 15.7319 25.6892 15.6876 25.5653C15.6456 25.4476 15.6201 25.4168 15.6122 25.408C15.5561 25.3457 15.4817 25.3027 15.3997 25.2852C15.3881 25.2828 15.3487 25.2762 15.2257 25.2986C15.0963 25.3221 14.9285 25.3667 14.6618 25.4381L13.0043 25.8823C12.7376 25.9537 12.57 25.9991 12.4461 26.0434Z" fill="#8AB8D1" style="fill:#8AB8D1;fill:color(display-p3 0.5403 0.7217 0.8212);fill-opacity:1;"/>
<path d="M18.7379 18.1776C18.4836 18.2457 18.3327 18.5071 18.4008 18.7614L18.5651 19.3753C18.6332 19.6296 18.8945 19.7805 19.1488 19.7124L19.7627 19.5479C20.017 19.4798 20.1679 19.2184 20.0998 18.9641L19.9355 18.3502C19.8674 18.0959 19.6061 17.945 19.3518 18.0131L18.7379 18.1776Z" fill="#8AB8D1" style="fill:#8AB8D1;fill:color(display-p3 0.5403 0.7217 0.8212);fill-opacity:1;"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M17.6413 16.2508C17.4006 16.3153 17.1885 16.3721 17.0167 16.4336C16.834 16.4989 16.6509 16.5845 16.4895 16.7298C16.2526 16.9431 16.0893 17.2259 16.023 17.5377C15.9778 17.75 15.9951 17.9515 16.0299 18.1423C16.0626 18.3218 16.1194 18.534 16.1838 18.7747L16.6383 20.4723C16.7028 20.7131 16.7596 20.9252 16.821 21.097C16.8862 21.2797 16.9718 21.4629 17.117 21.6242C17.3303 21.8611 17.613 22.0244 17.9248 22.0907C18.1371 22.1358 18.3385 22.1184 18.5294 22.0836C18.7088 22.0509 18.921 21.9941 19.1617 21.9296L20.8593 21.4747C21.1 21.4102 21.3121 21.3534 21.4839 21.2919C21.6666 21.2266 21.8497 21.141 22.0111 20.9957C22.248 20.7824 22.4113 20.4996 22.4776 20.1878C22.5228 19.9755 22.5054 19.7741 22.4707 19.5832C22.438 19.4037 22.3812 19.1915 22.3168 18.9508L21.8622 17.2532C21.7978 17.0124 21.741 16.8003 21.6796 16.6285C21.6144 16.4458 21.5288 16.2627 21.3836 16.1013C21.1703 15.8644 20.8876 15.7011 20.5758 15.6349C20.3635 15.5897 20.1621 15.6071 19.9712 15.6419C19.7917 15.6746 19.5796 15.7315 19.3389 15.796L17.6413 16.2508ZM17.2335 17.5563C17.2423 17.5485 17.2731 17.523 17.3908 17.4809C17.5147 17.4366 17.6823 17.3913 17.949 17.3198L19.6065 16.8757C19.8732 16.8042 20.0411 16.7597 20.1704 16.7361C20.2934 16.7137 20.3328 16.7203 20.3444 16.7228C20.4264 16.7402 20.5008 16.7832 20.5569 16.8455C20.5648 16.8543 20.5903 16.8852 20.6323 17.0029C20.6766 17.1267 20.7219 17.2943 20.7933 17.5611L21.2371 19.2186C21.3085 19.4854 21.353 19.6532 21.3766 19.7826C21.3989 19.9056 21.3923 19.945 21.3898 19.9566C21.3724 20.0386 21.3294 20.113 21.2671 20.1692C21.2583 20.1771 21.2274 20.2025 21.1098 20.2446C20.9859 20.2889 20.8183 20.3342 20.5516 20.4057L18.8941 20.8498C18.6274 20.9213 18.4595 20.9658 18.3302 20.9894C18.2072 21.0118 18.1677 21.0052 18.1562 21.0027C18.0742 20.9853 17.9998 20.9423 17.9437 20.88C17.9358 20.8712 17.9103 20.8404 17.8683 20.7226C17.824 20.5988 17.7787 20.4312 17.7073 20.1644L17.2635 18.5069C17.1921 18.2401 17.1476 18.0723 17.124 17.9429C17.1016 17.8199 17.1083 17.7805 17.1107 17.769C17.1282 17.6869 17.1712 17.6125 17.2335 17.5563Z" fill="#8AB8D1" style="fill:#8AB8D1;fill:color(display-p3 0.5403 0.7217 0.8212);fill-opacity:1;"/>
<path d="M18.4057 23.6948C18.1514 23.7629 18.0005 24.0243 18.0686 24.2786L18.2329 24.8925C18.301 25.1468 18.5623 25.2977 18.8166 25.2295L19.4305 25.0651C19.6848 24.9969 19.8357 24.7355 19.7676 24.4813L19.6033 23.8673C19.5352 23.613 19.2739 23.4621 19.0196 23.5303L18.4057 23.6948Z" fill="#8AB8D1" style="fill:#8AB8D1;fill:color(display-p3 0.5403 0.7217 0.8212);fill-opacity:1;"/>
<path d="M20.2088 25.5145C20.1407 25.2602 20.2916 24.9988 20.5459 24.9307L21.1598 24.7662C21.4141 24.6981 21.6754 24.849 21.7435 25.1033L21.9078 25.7172C21.9759 25.9715 21.825 26.2328 21.5707 26.301L20.9568 26.4655C20.7025 26.5336 20.4412 26.3827 20.3731 26.1284L20.2088 25.5145Z" fill="#8AB8D1" style="fill:#8AB8D1;fill:color(display-p3 0.5403 0.7217 0.8212);fill-opacity:1;"/>
<path d="M22.3489 26.7504C22.2808 26.4961 22.4318 26.2347 22.6861 26.1666L23.2999 26.0021C23.5542 25.934 23.8156 26.0849 23.8836 26.3392L24.048 26.9531C24.1161 27.2074 23.9651 27.4688 23.7109 27.5369L23.097 27.7014C22.8427 27.7695 22.5814 27.6186 22.5133 27.3643L22.3489 26.7504Z" fill="#8AB8D1" style="fill:#8AB8D1;fill:color(display-p3 0.5403 0.7217 0.8212);fill-opacity:1;"/>
<path d="M21.7821 22.7901C21.5278 22.8582 21.3768 23.1196 21.4449 23.3739L21.6093 23.9878C21.6774 24.2421 21.9387 24.393 22.193 24.3249L22.8069 24.1604C23.0611 24.0922 23.2121 23.8309 23.144 23.5766L22.9796 22.9626C22.9116 22.7084 22.6502 22.5574 22.396 22.6256L21.7821 22.7901Z" fill="#8AB8D1" style="fill:#8AB8D1;fill:color(display-p3 0.5403 0.7217 0.8212);fill-opacity:1;"/>
<path d="M18.9726 27.6551C18.9045 27.4008 19.0554 27.1394 19.3097 27.0713L19.9236 26.9068C20.1779 26.8387 20.4392 26.9896 20.5073 27.2439L20.6716 27.8578C20.7397 28.1121 20.5888 28.3735 20.3345 28.4416L19.7206 28.6061C19.4663 28.6742 19.205 28.5233 19.1369 28.269L18.9726 27.6551Z" fill="#8AB8D1" style="fill:#8AB8D1;fill:color(display-p3 0.5403 0.7217 0.8212);fill-opacity:1;"/>
<rect x="10.3" y="0.845" width="28.9" height="28.9" fill="#88A5E4" style="fill:#88A5E4;fill:color(display-p3 0.5328 0.6468 0.8924);fill-opacity:1;stroke:#6384CB;stroke:color(display-p3 0.3887 0.5181 0.7969);" stroke-width="1.65" stroke="#6384cb" rx="7.7"/>
<path d="M15.4267 8.59483C15.427 7.12399 16.6196 5.93163 18.0905 5.93163H31.4065C32.8774 5.93163 34.0695 7.12399 34.0692 8.59483L34.0664 21.9109C34.0661 23.3817 32.8735 24.5741 31.4027 24.5741H18.0867C16.6158 24.5741 15.4237 23.3817 15.424 21.9109L15.4267 8.59483Z" fill="white" style="fill:white;fill-opacity:1;"/>
<path d="M20.4578 11.4397C20.4579 11.1764 20.6713 10.963 20.9346 10.963H21.5701C21.8334 10.963 22.0467 11.1764 22.0467 11.4397L22.0466 12.0752C22.0465 12.3385 21.8331 12.5519 21.5698 12.5519H20.9343C20.671 12.5519 20.4577 12.3385 20.4577 12.0752L20.4578 11.4397Z" fill="#6384CB" style="fill:#6384CB;fill:color(display-p3 0.3887 0.5181 0.7969);fill-opacity:1;"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M20.3741 8.81808H22.1315C22.3807 8.81807 22.6004 8.81806 22.7822 8.83292C22.9755 8.84871 23.1746 8.88404 23.368 8.9826C23.652 9.12731 23.8828 9.35822 24.0275 9.64223C24.126 9.83565 24.1613 10.0347 24.177 10.2281C24.1919 10.4099 24.1918 10.6295 24.1917 10.8787L24.1914 12.6362C24.1913 12.8854 24.1913 13.105 24.1764 13.2868C24.1606 13.4802 24.1252 13.6792 24.0266 13.8727C23.8818 14.1567 23.6509 14.3876 23.3668 14.5323C23.1734 14.6308 22.9743 14.6662 22.781 14.682C22.5992 14.6968 22.3795 14.6968 22.1303 14.6968H20.3729C20.1237 14.6968 19.904 14.6968 19.7222 14.682C19.5289 14.6662 19.3298 14.6308 19.1364 14.5323C18.8524 14.3876 18.6216 14.1567 18.4769 13.8727C18.3784 13.6792 18.3431 13.4802 18.3274 13.2868C18.3125 13.105 18.3126 12.8854 18.3127 12.6361L18.313 10.8787C18.3131 10.6295 18.3131 10.4099 18.328 10.2281C18.3438 10.0347 18.3792 9.83565 18.4778 9.64223C18.6226 9.35822 18.8535 9.12731 19.1376 8.9826C19.331 8.88404 19.53 8.84871 19.7234 8.83292C19.9052 8.81806 20.1249 8.81807 20.3741 8.81808ZM19.8137 9.94141C19.6892 9.95159 19.6528 9.96821 19.6423 9.97357C19.5675 10.0116 19.5067 10.0724 19.4687 10.1472C19.4633 10.1577 19.4467 10.194 19.4365 10.3186C19.4257 10.4497 19.4253 10.6233 19.4252 10.8995L19.4249 12.6154C19.4248 12.8915 19.4252 13.0652 19.4359 13.1963C19.446 13.3208 19.4626 13.3572 19.468 13.3677C19.5061 13.4425 19.5668 13.5032 19.6415 13.5413C19.652 13.5467 19.6884 13.5633 19.813 13.5735C19.9441 13.5842 20.1177 13.5846 20.3938 13.5846H22.1098C22.3859 13.5846 22.5596 13.5842 22.6906 13.5735C22.8152 13.5633 22.8516 13.5467 22.8621 13.5413C22.9369 13.5032 22.9976 13.4425 23.0357 13.3677C23.0411 13.3572 23.0577 13.3208 23.0679 13.1963C23.0787 13.0652 23.0791 12.8915 23.0792 12.6154L23.0795 10.8995C23.0796 10.6233 23.0792 10.4497 23.0685 10.3186C23.0584 10.194 23.0418 10.1577 23.0364 10.1472C22.9983 10.0724 22.9376 10.0116 22.8629 9.97357C22.8524 9.96821 22.816 9.95159 22.6914 9.94141C22.5603 9.9307 22.3867 9.93027 22.1105 9.93027H20.3946C20.1185 9.93027 19.9448 9.9307 19.8137 9.94141Z" fill="#6384CB" style="fill:#6384CB;fill:color(display-p3 0.3887 0.5181 0.7969);fill-opacity:1;"/>
<path d="M20.9332 17.9539C20.6699 17.9539 20.4565 18.1673 20.4564 18.4306L20.4563 19.0661C20.4562 19.3294 20.6696 19.5428 20.9328 19.5428H21.5684C21.8316 19.5428 22.0451 19.3294 22.0451 19.0661L22.0452 18.4306C22.0453 18.1673 21.8319 17.9539 21.5687 17.9539H20.9332Z" fill="#6384CB" style="fill:#6384CB;fill:color(display-p3 0.3887 0.5181 0.7969);fill-opacity:1;"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M20.3727 15.809H22.1301C22.3793 15.809 22.5989 15.809 22.7808 15.8238C22.9741 15.8396 23.1731 15.875 23.3665 15.9735C23.6505 16.1182 23.8814 16.3491 24.026 16.6331C24.1246 16.8266 24.1598 17.0256 24.1756 17.219C24.1904 17.4008 24.1904 17.6204 24.1903 17.8696L24.1899 19.6271C24.1899 19.8763 24.1899 20.0959 24.175 20.2777C24.1591 20.4711 24.1238 20.6701 24.0252 20.8636C23.8804 21.1476 23.6494 21.3785 23.3654 21.5232C23.172 21.6217 22.9729 21.6571 22.7795 21.6729C22.5977 21.6877 22.3781 21.6877 22.1289 21.6877H20.3714C20.1222 21.6877 19.9026 21.6877 19.7208 21.6729C19.5274 21.6571 19.3284 21.6217 19.135 21.5232C18.851 21.3785 18.6201 21.1476 18.4755 20.8636C18.377 20.6701 18.3417 20.4711 18.3259 20.2777C18.3111 20.0959 18.3112 19.8763 18.3112 19.6271L18.3116 17.8696C18.3116 17.6204 18.3117 17.4008 18.3265 17.219C18.3424 17.0256 18.3778 16.8266 18.4763 16.6331C18.6211 16.3491 18.8521 16.1182 19.1361 15.9735C19.3296 15.875 19.5286 15.8396 19.722 15.8238C19.9038 15.809 20.1234 15.809 20.3727 15.809ZM19.8123 16.9323C19.6877 16.9425 19.6513 16.9591 19.6408 16.9645C19.5661 17.0026 19.5053 17.0633 19.4672 17.1381C19.4619 17.1486 19.4452 17.185 19.435 17.3095C19.4243 17.4406 19.4238 17.6143 19.4238 17.8904L19.4234 19.6063C19.4234 19.8825 19.4238 20.0561 19.4344 20.1872C19.4446 20.3117 19.4612 20.3481 19.4666 20.3586C19.5046 20.4334 19.5654 20.4941 19.6401 20.5322C19.6506 20.5376 19.687 20.5542 19.8116 20.5644C19.9426 20.5751 20.1163 20.5755 20.3924 20.5755H22.1084C22.3845 20.5755 22.5581 20.5751 22.6892 20.5644C22.8138 20.5542 22.8502 20.5376 22.8607 20.5322C22.9354 20.4941 22.9962 20.4334 23.0343 20.3586C23.0397 20.3481 23.0563 20.3117 23.0665 20.1872C23.0772 20.0561 23.0777 19.8825 23.0778 19.6063L23.0781 17.8904C23.0782 17.6143 23.0778 17.4406 23.0671 17.3095C23.0569 17.185 23.0403 17.1486 23.035 17.1381C22.9969 17.0633 22.9361 17.0026 22.8614 16.9645C22.8509 16.9591 22.8145 16.9425 22.69 16.9323C22.5589 16.9216 22.3852 16.9212 22.1091 16.9212H20.3932C20.117 16.9212 19.9434 16.9216 19.8123 16.9323Z" fill="#6384CB" style="fill:#6384CB;fill:color(display-p3 0.3887 0.5181 0.7969);fill-opacity:1;"/>
<path d="M27.9255 10.963C27.6623 10.963 27.4488 11.1764 27.4487 11.4397L27.4486 12.0752C27.4486 12.3385 27.6619 12.5519 27.9252 12.5519H28.5607C28.824 12.5519 29.0374 12.3385 29.0375 12.0752L29.0376 11.4397C29.0376 11.1764 28.8243 10.963 28.561 10.963H27.9255Z" fill="#6384CB" style="fill:#6384CB;fill:color(display-p3 0.3887 0.5181 0.7969);fill-opacity:1;"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M27.365 8.81808C27.1158 8.81807 26.8962 8.81806 26.7143 8.83292C26.521 8.84871 26.3219 8.88404 26.1285 8.9826C25.8444 9.12731 25.6135 9.35822 25.4687 9.64223C25.3701 9.83565 25.3347 10.0347 25.3189 10.2281C25.304 10.4099 25.304 10.6295 25.3039 10.8787L25.3036 12.6361C25.3035 12.8854 25.3034 13.105 25.3183 13.2868C25.334 13.4802 25.3693 13.6792 25.4678 13.8727C25.6125 14.1567 25.8433 14.3876 26.1273 14.5323C26.3207 14.6308 26.5198 14.6662 26.7131 14.682C26.8949 14.6968 27.1146 14.6968 27.3637 14.6968H29.1212C29.3704 14.6968 29.5901 14.6968 29.7719 14.682C29.9653 14.6662 30.1643 14.6308 30.3577 14.5323C30.6418 14.3876 30.8727 14.1567 31.0175 13.8727C31.1161 13.6792 31.1515 13.4802 31.1673 13.2868C31.1822 13.105 31.1822 12.8854 31.1823 12.6362L31.1826 10.8787C31.1827 10.6295 31.1828 10.4099 31.1679 10.2281C31.1522 10.0347 31.1169 9.83565 31.0184 9.64223C30.8737 9.35822 30.6429 9.12731 30.3589 8.9826C30.1655 8.88404 29.9664 8.84871 29.7731 8.83292C29.5913 8.81806 29.3716 8.81807 29.1224 8.81808H27.365ZM26.6332 9.97357C26.6437 9.96821 26.6801 9.95159 26.8047 9.94141C26.9357 9.9307 27.1094 9.93027 27.3855 9.93027H29.1015C29.3776 9.93027 29.5512 9.9307 29.6823 9.94141C29.8069 9.95159 29.8433 9.96821 29.8538 9.97357C29.9285 10.0116 29.9892 10.0724 30.0273 10.1472C30.0327 10.1577 30.0493 10.194 30.0594 10.3186C30.0701 10.4497 30.0705 10.6233 30.0705 10.8995L30.0701 12.6154C30.07 12.8915 30.0696 13.0652 30.0588 13.1963C30.0486 13.3208 30.032 13.3572 30.0267 13.3677C29.9886 13.4425 29.9278 13.5032 29.853 13.5413C29.8425 13.5467 29.8061 13.5633 29.6816 13.5735C29.5505 13.5842 29.3768 13.5846 29.1007 13.5846H27.3848C27.1086 13.5846 26.935 13.5842 26.8039 13.5735C26.6793 13.5633 26.643 13.5467 26.6325 13.5413C26.5577 13.5032 26.497 13.4425 26.4589 13.3677C26.4536 13.3572 26.4369 13.3208 26.4268 13.1963C26.4161 13.0652 26.4157 12.8915 26.4158 12.6154L26.4161 10.8995C26.4162 10.6233 26.4166 10.4497 26.4274 10.3186C26.4376 10.194 26.4542 10.1577 26.4596 10.1472C26.4977 10.0724 26.5584 10.0116 26.6332 9.97357Z" fill="#6384CB" style="fill:#6384CB;fill:color(display-p3 0.3887 0.5181 0.7969);fill-opacity:1;"/>
<path d="M26.1767 16.2062C25.9134 16.2062 25.7 16.4196 25.6999 16.6829L25.6998 17.3184C25.6998 17.5816 25.9131 17.795 26.1764 17.795H26.8119C27.0752 17.795 27.2886 17.5816 27.2887 17.3184L27.2888 16.6829C27.2888 16.4196 27.0755 16.2062 26.8122 16.2062H26.1767Z" fill="#6384CB" style="fill:#6384CB;fill:color(display-p3 0.3887 0.5181 0.7969);fill-opacity:1;"/>
<path d="M27.4473 18.4306C27.4474 18.1673 27.6608 17.9539 27.9241 17.9539H28.5596C28.8228 17.9539 29.0362 18.1673 29.0362 18.4306L29.036 19.0661C29.036 19.3294 28.8225 19.5428 28.5593 19.5428H27.9237C27.6605 19.5428 27.4471 19.3294 27.4472 19.0661L27.4473 18.4306Z" fill="#6384CB" style="fill:#6384CB;fill:color(display-p3 0.3887 0.5181 0.7969);fill-opacity:1;"/>
<path d="M29.1947 20.1783C29.1947 19.9151 29.4082 19.7017 29.6714 19.7017H30.307C30.5702 19.7017 30.7836 19.9151 30.7835 20.1783L30.7834 20.8138C30.7833 21.0771 30.5699 21.2905 30.3066 21.2905H29.6711C29.4079 21.2905 29.1945 21.0771 29.1946 20.8138L29.1947 20.1783Z" fill="#6384CB" style="fill:#6384CB;fill:color(display-p3 0.3887 0.5181 0.7969);fill-opacity:1;"/>
<path d="M29.6722 16.2062C29.4089 16.2062 29.1955 16.4196 29.1954 16.6829L29.1953 17.3184C29.1952 17.5816 29.4086 17.795 29.6718 17.795H30.3074C30.5706 17.795 30.7841 17.5816 30.7841 17.3184L30.7842 16.6829C30.7843 16.4196 30.5709 16.2062 30.3077 16.2062H29.6722Z" fill="#6384CB" style="fill:#6384CB;fill:color(display-p3 0.3887 0.5181 0.7969);fill-opacity:1;"/>
<path d="M25.6992 20.1783C25.6993 19.9151 25.9127 19.7017 26.176 19.7017H26.8115C27.0748 19.7017 27.2881 19.9151 27.2881 20.1783L27.2879 20.8138C27.2879 21.0771 27.0744 21.2905 26.8112 21.2905H26.1757C25.9124 21.2905 25.699 21.0771 25.6991 20.8138L25.6992 20.1783Z" fill="#6384CB" style="fill:#6384CB;fill:color(display-p3 0.3887 0.5181 0.7969);fill-opacity:1;"/>
</svg>

After

Width:  |  Height:  |  Size: 20 KiB

View File

@ -0,0 +1,30 @@
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1.92742 20.1051C0.959155 16.4885 3.10589 12.7711 6.72229 11.8021L19.8184 8.29303C23.4348 7.32402 27.1514 9.47031 28.1197 13.0869L31.6261 26.1838C32.5944 29.8004 30.4477 33.5178 26.8313 34.4868L13.7351 37.9959C10.1187 38.9649 6.4021 36.8186 5.43384 33.202L1.92742 20.1051Z" fill="#8AB8D1" style="fill:#8AB8D1;fill:color(display-p3 0.5403 0.7217 0.8212);fill-opacity:1;"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.28399 10.165L19.3801 6.65592C23.9006 5.44466 28.5464 8.12753 29.7567 12.6483L33.2631 25.7451C34.4735 30.2659 31.7901 34.9126 27.2696 36.1239L14.1734 39.633C9.65291 40.8442 5.00715 38.1614 3.79682 33.6406L0.290406 20.5438C-0.91993 16.023 1.76349 11.3763 6.28399 10.165ZM6.72229 11.8021C3.10589 12.7711 0.959155 16.4885 1.92742 20.1051L5.43384 33.202C6.4021 36.8186 10.1187 38.9649 13.7351 37.9959L26.8313 34.4868C30.4477 33.5178 32.5944 29.8004 31.6261 26.1838L28.1197 13.0869C27.1514 9.47031 23.4348 7.32402 19.8184 8.29303L6.72229 11.8021Z" fill="black" style="fill:black;fill-opacity:1;"/>
<path d="M6.05211 19.1252C5.67172 17.7044 6.51508 16.244 7.93581 15.8633L20.7981 12.4169C22.2188 12.0362 23.6789 12.8794 24.0593 14.3002L27.5031 27.1632C27.8835 28.584 27.0401 30.0444 25.6194 30.4251L12.7571 33.8715C11.3364 34.2522 9.8763 33.409 9.49591 31.9882L6.05211 19.1252Z" fill="white" style="fill:white;fill-opacity:1;"/>
<path d="M11.6481 20.5709C11.58 20.3166 11.7309 20.0552 11.9852 19.9871L12.5991 19.8226C12.8534 19.7544 13.1147 19.9053 13.1828 20.1596L13.3471 20.7736C13.4152 21.0278 13.2643 21.2892 13.01 21.3574L12.3961 21.5218C12.1418 21.59 11.8805 21.4391 11.8124 21.1848L11.6481 20.5709Z" fill="#8AB8D1" style="fill:#8AB8D1;fill:color(display-p3 0.5403 0.7217 0.8212);fill-opacity:1;"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M10.8887 18.0603L12.5862 17.6054C12.8269 17.5409 13.0391 17.4841 13.2185 17.4513C13.4094 17.4166 13.6108 17.3992 13.8231 17.4443C14.1349 17.5106 14.4176 17.6739 14.6309 17.9108C14.7761 18.0721 14.8617 18.2552 14.9269 18.4379C14.9883 18.6097 15.0451 18.8219 15.1095 19.0626L15.5641 20.7603C15.6285 21.001 15.6853 21.2132 15.718 21.3926C15.7528 21.5835 15.7701 21.7849 15.7249 21.9973C15.6586 22.3091 15.4953 22.5919 15.2584 22.8052C15.097 22.9505 14.9139 23.0361 14.7312 23.1014C14.5594 23.1628 14.3473 23.2196 14.1066 23.2841L12.409 23.739C12.1683 23.8035 11.9561 23.8604 11.7767 23.8931C11.5858 23.9279 11.3844 23.9452 11.1721 23.9001C10.8603 23.8338 10.5776 23.6705 10.3643 23.4336C10.2191 23.2723 10.1335 23.0892 10.0683 22.9065C10.0069 22.7347 9.95009 22.5225 9.88565 22.2818L9.43115 20.5842C9.36668 20.3434 9.30987 20.1313 9.2772 19.9518C9.24245 19.7609 9.2251 19.5595 9.27027 19.3471C9.3366 19.0353 9.49992 18.7525 9.73683 18.5392C9.89818 18.394 10.0813 18.3083 10.264 18.243C10.4358 18.1816 10.6479 18.1248 10.8887 18.0603ZM10.6381 19.2904C10.5204 19.3324 10.4896 19.3579 10.4808 19.3658C10.4185 19.4219 10.3755 19.4963 10.3581 19.5784C10.3556 19.5899 10.349 19.6294 10.3713 19.7524C10.3949 19.8817 10.4394 20.0496 10.5108 20.3163L10.9546 21.9739C11.026 22.2406 11.0713 22.4083 11.1156 22.5321C11.1576 22.6498 11.1831 22.6807 11.191 22.6894C11.2471 22.7518 11.3215 22.7947 11.4035 22.8122C11.4151 22.8146 11.4545 22.8213 11.5775 22.7988C11.7068 22.7753 11.8747 22.7307 12.1414 22.6593L13.7989 22.2152C14.0656 22.1437 14.2332 22.0983 14.3571 22.0541C14.4748 22.012 14.5056 21.9865 14.5144 21.9786C14.5767 21.9225 14.6197 21.8481 14.6371 21.766C14.6396 21.7545 14.6462 21.715 14.6239 21.5921C14.6003 21.4627 14.5558 21.2948 14.4844 21.0281L14.0406 19.3705C13.9692 19.1038 13.9239 18.9361 13.8796 18.8123C13.8376 18.6946 13.8121 18.6638 13.8042 18.655C13.7481 18.5927 13.6737 18.5497 13.5917 18.5322C13.5801 18.5298 13.5407 18.5232 13.4177 18.5456C13.2884 18.5691 13.1205 18.6137 12.8538 18.6851L11.1963 19.1293C10.9296 19.2007 10.762 19.2461 10.6381 19.2904Z" fill="#8AB8D1" style="fill:#8AB8D1;fill:color(display-p3 0.5403 0.7217 0.8212);fill-opacity:1;"/>
<path d="M13.7932 26.7401C13.5389 26.8083 13.388 27.0696 13.4561 27.3239L13.6204 27.9378C13.6885 28.1921 13.9498 28.3431 14.2041 28.2749L14.818 28.1104C15.0723 28.0423 15.2232 27.7809 15.1551 27.5266L14.9908 26.9127C14.9227 26.6584 14.6614 26.5075 14.4071 26.5756L13.7932 26.7401Z" fill="#8AB8D1" style="fill:#8AB8D1;fill:color(display-p3 0.5403 0.7217 0.8212);fill-opacity:1;"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.6967 24.8133L14.3942 24.3585C14.6349 24.294 14.847 24.2371 15.0265 24.2044C15.2174 24.1696 15.4188 24.1522 15.6311 24.1974C15.9429 24.2637 16.2256 24.4269 16.4389 24.6638C16.5841 24.8252 16.6697 25.0083 16.7349 25.191C16.7963 25.3628 16.8531 25.5749 16.9175 25.8157L17.3721 27.5133C17.4365 27.754 17.4933 27.9662 17.526 28.1457C17.5607 28.3366 17.5781 28.538 17.5329 28.7503C17.4666 29.0622 17.3033 29.345 17.0664 29.5583C16.905 29.7035 16.7219 29.7892 16.5392 29.8545C16.3674 29.9159 16.1553 29.9727 15.9146 30.0372L14.217 30.4921C13.9763 30.5566 13.7641 30.6134 13.5847 30.6461C13.3938 30.6809 13.1924 30.6983 12.9801 30.6532C12.6683 30.5869 12.3856 30.4236 12.1723 30.1867C12.0271 30.0254 11.9415 29.8422 11.8763 29.6596C11.8149 29.4878 11.7581 29.2756 11.6936 29.0349L11.2391 27.3372C11.1747 27.0965 11.1179 26.8843 11.0852 26.7048C11.0504 26.514 11.0331 26.3126 11.0783 26.1002C11.1446 25.7884 11.3079 25.5056 11.5448 25.2923C11.7062 25.147 11.8893 25.0614 12.072 24.9961C12.2438 24.9347 12.4559 24.8778 12.6967 24.8133ZM12.4461 26.0434C12.3284 26.0855 12.2976 26.111 12.2888 26.1189C12.2265 26.175 12.1835 26.2494 12.1661 26.3315C12.1636 26.343 12.157 26.3825 12.1793 26.5054C12.2029 26.6348 12.2474 26.8027 12.3188 27.0694L12.7626 28.727C12.834 28.9937 12.8793 29.1613 12.9236 29.2852C12.9656 29.4029 12.9911 29.4337 12.999 29.4425C13.0551 29.5048 13.1295 29.5478 13.2115 29.5652C13.2231 29.5677 13.2625 29.5743 13.3855 29.5519C13.5148 29.5283 13.6827 29.4838 13.9494 29.4123L15.6069 28.9682C15.8736 28.8968 16.0412 28.8514 16.1651 28.8071C16.2828 28.7651 16.3136 28.7396 16.3224 28.7317C16.3847 28.6756 16.4277 28.6011 16.4451 28.5191C16.4476 28.5076 16.4542 28.4681 16.4319 28.3451C16.4083 28.2157 16.3638 28.0479 16.2924 27.7812L15.8486 26.1236C15.7772 25.8569 15.7319 25.6892 15.6876 25.5654C15.6456 25.4477 15.6201 25.4168 15.6122 25.4081C15.5561 25.3457 15.4817 25.3028 15.3997 25.2853C15.3881 25.2829 15.3487 25.2762 15.2257 25.2986C15.0964 25.3222 14.9285 25.3667 14.6618 25.4382L13.0043 25.8823C12.7376 25.9538 12.57 25.9992 12.4461 26.0434Z" fill="#8AB8D1" style="fill:#8AB8D1;fill:color(display-p3 0.5403 0.7217 0.8212);fill-opacity:1;"/>
<path d="M18.7379 18.1777C18.4836 18.2458 18.3327 18.5072 18.4008 18.7615L18.5651 19.3754C18.6332 19.6297 18.8945 19.7806 19.1488 19.7125L19.7627 19.548C20.017 19.4798 20.1679 19.2185 20.0998 18.9642L19.9355 18.3503C19.8674 18.096 19.6061 17.9451 19.3518 18.0132L18.7379 18.1777Z" fill="#8AB8D1" style="fill:#8AB8D1;fill:color(display-p3 0.5403 0.7217 0.8212);fill-opacity:1;"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M17.6414 16.2509C17.4006 16.3154 17.1885 16.3722 17.0167 16.4336C16.834 16.4989 16.6509 16.5846 16.4895 16.7298C16.2526 16.9431 16.0893 17.226 16.023 17.5378C15.9778 17.7501 15.9952 17.9515 16.0299 18.1424C16.0626 18.3219 16.1194 18.534 16.1838 18.7748L16.6384 20.4724C16.7028 20.7131 16.7596 20.9253 16.821 21.0971C16.8862 21.2798 16.9718 21.4629 17.117 21.6243C17.3303 21.8612 17.613 22.0244 17.9248 22.0907C18.1371 22.1359 18.3385 22.1185 18.5294 22.0837C18.7088 22.051 18.921 21.9941 19.1617 21.9296L20.8593 21.4748C21.1 21.4103 21.3121 21.3534 21.4839 21.292C21.6666 21.2267 21.8497 21.1411 22.0111 20.9958C22.248 20.7825 22.4113 20.4997 22.4776 20.1879C22.5228 19.9755 22.5055 19.7741 22.4707 19.5833C22.438 19.4038 22.3812 19.1916 22.3168 18.9509L21.8623 17.2532C21.7978 17.0125 21.741 16.8003 21.6796 16.6285C21.6144 16.4459 21.5288 16.2627 21.3836 16.1014C21.1703 15.8645 20.8876 15.7012 20.5758 15.6349C20.3635 15.5898 20.1621 15.6072 19.9712 15.642C19.7918 15.6747 19.5796 15.7315 19.3389 15.796L17.6414 16.2509ZM17.2335 17.5564C17.2423 17.5485 17.2731 17.523 17.3908 17.481C17.5147 17.4367 17.6823 17.3913 17.949 17.3199L19.6065 16.8758C19.8732 16.8043 20.0411 16.7598 20.1704 16.7362C20.2934 16.7138 20.3328 16.7204 20.3444 16.7229C20.4264 16.7403 20.5008 16.7833 20.5569 16.8456C20.5648 16.8544 20.5903 16.8852 20.6323 17.0029C20.6766 17.1268 20.7219 17.2944 20.7933 17.5611L21.2371 19.2187C21.3085 19.4854 21.353 19.6533 21.3766 19.7827C21.3989 19.9056 21.3923 19.9451 21.3898 19.9566C21.3724 20.0387 21.3294 20.1131 21.2671 20.1692C21.2583 20.1771 21.2275 20.2026 21.1098 20.2447C20.9859 20.2889 20.8183 20.3343 20.5516 20.4058L18.8941 20.8499C18.6274 20.9214 18.4595 20.9659 18.3302 20.9895C18.2072 21.0119 18.1678 21.0052 18.1562 21.0028C18.0742 20.9853 17.9998 20.9424 17.9437 20.88C17.9358 20.8713 17.9103 20.8404 17.8683 20.7227C17.824 20.5989 17.7787 20.4313 17.7073 20.1645L17.2635 18.5069C17.1921 18.2402 17.1476 18.0724 17.124 17.943C17.1017 17.82 17.1083 17.7806 17.1108 17.769C17.1282 17.687 17.1712 17.6125 17.2335 17.5564Z" fill="#8AB8D1" style="fill:#8AB8D1;fill:color(display-p3 0.5403 0.7217 0.8212);fill-opacity:1;"/>
<path d="M18.4057 23.6948C18.1515 23.763 18.0005 24.0243 18.0686 24.2786L18.233 24.8925C18.301 25.1468 18.5624 25.2977 18.8166 25.2296L19.4305 25.0651C19.6848 24.997 19.8357 24.7356 19.7677 24.4813L19.6033 23.8674C19.5352 23.6131 19.2739 23.4622 19.0196 23.5303L18.4057 23.6948Z" fill="#8AB8D1" style="fill:#8AB8D1;fill:color(display-p3 0.5403 0.7217 0.8212);fill-opacity:1;"/>
<path d="M20.2088 25.5146C20.1407 25.2603 20.2916 24.9989 20.5459 24.9307L21.1598 24.7663C21.4141 24.6981 21.6754 24.849 21.7435 25.1033L21.9078 25.7172C21.9759 25.9715 21.825 26.2329 21.5707 26.301L20.9568 26.4655C20.7025 26.5337 20.4412 26.3828 20.3731 26.1285L20.2088 25.5146Z" fill="#8AB8D1" style="fill:#8AB8D1;fill:color(display-p3 0.5403 0.7217 0.8212);fill-opacity:1;"/>
<path d="M22.3489 26.7505C22.2809 26.4962 22.4318 26.2348 22.6861 26.1667L23.3 26.0022C23.5542 25.934 23.8156 26.085 23.8836 26.3393L24.048 26.9532C24.1161 27.2075 23.9651 27.4688 23.7109 27.537L23.097 27.7015C22.8427 27.7696 22.5814 27.6187 22.5133 27.3644L22.3489 26.7505Z" fill="#8AB8D1" style="fill:#8AB8D1;fill:color(display-p3 0.5403 0.7217 0.8212);fill-opacity:1;"/>
<path d="M21.7821 22.7901C21.5278 22.8583 21.3769 23.1196 21.4449 23.3739L21.6093 23.9879C21.6774 24.2421 21.9387 24.3931 22.193 24.3249L22.8069 24.1604C23.0611 24.0923 23.2121 23.8309 23.144 23.5766L22.9796 22.9627C22.9116 22.7084 22.6502 22.5575 22.396 22.6256L21.7821 22.7901Z" fill="#8AB8D1" style="fill:#8AB8D1;fill:color(display-p3 0.5403 0.7217 0.8212);fill-opacity:1;"/>
<path d="M18.9726 27.6552C18.9045 27.4009 19.0554 27.1395 19.3097 27.0714L19.9236 26.9069C20.1779 26.8387 20.4392 26.9897 20.5073 27.2439L20.6717 27.8579C20.7397 28.1121 20.5888 28.3735 20.3345 28.4417L19.7206 28.6062C19.4664 28.6743 19.205 28.5234 19.137 28.2691L18.9726 27.6552Z" fill="#8AB8D1" style="fill:#8AB8D1;fill:color(display-p3 0.5403 0.7217 0.8212);fill-opacity:1;"/>
<path d="M11.189 8.47383C11.1897 4.72986 14.2255 1.69477 17.9694 1.69477H31.5276C35.2715 1.69477 38.306 4.72986 38.3052 8.47383L38.3024 22.032C38.3017 25.7759 35.266 28.811 31.522 28.811H17.9639C14.2199 28.811 11.1854 25.7759 11.1862 22.032L11.189 8.47383Z" fill="#88A5E4" style="fill:#88A5E4;fill:color(display-p3 0.5328 0.6468 0.8924);fill-opacity:1;"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M17.9698 1.52926e-08L31.5279 0C36.2079 -5.27862e-09 40.001 3.79386 40 8.47383L39.9972 22.032C39.9963 26.7119 36.2016 30.5058 31.5216 30.5058H17.9635C13.2835 30.5058 9.49046 26.7119 9.49142 22.032L9.49421 8.47383C9.49517 3.79386 13.2898 2.05712e-08 17.9698 1.52926e-08ZM17.9694 1.69477C14.2255 1.69477 11.1897 4.72986 11.189 8.47383L11.1862 22.032C11.1854 25.7759 14.2199 28.811 17.9639 28.811H31.522C35.266 28.811 38.3017 25.7759 38.3024 22.032L38.3052 8.47383C38.306 4.72986 35.2715 1.69477 31.5276 1.69477H17.9694Z" fill="black" style="fill:black;fill-opacity:1;"/>
<path d="M15.4267 8.59483C15.427 7.12399 16.6196 5.93163 18.0905 5.93163H31.4065C32.8774 5.93163 34.0695 7.12399 34.0692 8.59483L34.0664 21.9109C34.0661 23.3817 32.8735 24.5741 31.4027 24.5741H18.0867C16.6158 24.5741 15.4237 23.3817 15.424 21.9109L15.4267 8.59483Z" fill="white" style="fill:white;fill-opacity:1;"/>
<path d="M20.4578 11.4397C20.4579 11.1764 20.6713 10.963 20.9346 10.963H21.5701C21.8334 10.963 22.0467 11.1764 22.0467 11.4397L22.0466 12.0752C22.0465 12.3385 21.8331 12.5519 21.5698 12.5519H20.9343C20.671 12.5519 20.4577 12.3385 20.4577 12.0752L20.4578 11.4397Z" fill="#6384CB" style="fill:#6384CB;fill:color(display-p3 0.3887 0.5181 0.7969);fill-opacity:1;"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M20.3741 8.81808H22.1315C22.3807 8.81807 22.6004 8.81806 22.7822 8.83292C22.9755 8.84871 23.1746 8.88404 23.368 8.9826C23.652 9.12731 23.8828 9.35822 24.0275 9.64223C24.126 9.83565 24.1613 10.0347 24.177 10.2281C24.1919 10.4099 24.1918 10.6295 24.1917 10.8787L24.1914 12.6362C24.1913 12.8854 24.1913 13.105 24.1764 13.2868C24.1606 13.4802 24.1252 13.6792 24.0266 13.8727C23.8818 14.1567 23.6509 14.3876 23.3668 14.5323C23.1734 14.6308 22.9743 14.6662 22.781 14.682C22.5992 14.6968 22.3795 14.6968 22.1303 14.6968H20.3729C20.1237 14.6968 19.904 14.6968 19.7222 14.682C19.5289 14.6662 19.3298 14.6308 19.1364 14.5323C18.8524 14.3876 18.6216 14.1567 18.4769 13.8727C18.3784 13.6792 18.3431 13.4802 18.3274 13.2868C18.3125 13.105 18.3126 12.8854 18.3127 12.6361L18.313 10.8787C18.3131 10.6295 18.3131 10.4099 18.328 10.2281C18.3438 10.0347 18.3792 9.83565 18.4778 9.64223C18.6226 9.35822 18.8535 9.12731 19.1376 8.9826C19.331 8.88404 19.53 8.84871 19.7234 8.83292C19.9052 8.81806 20.1249 8.81807 20.3741 8.81808ZM19.8137 9.94141C19.6892 9.95159 19.6528 9.96821 19.6423 9.97357C19.5675 10.0116 19.5067 10.0724 19.4687 10.1472C19.4633 10.1577 19.4467 10.194 19.4365 10.3186C19.4257 10.4497 19.4253 10.6233 19.4252 10.8995L19.4249 12.6154C19.4248 12.8915 19.4252 13.0652 19.4359 13.1963C19.446 13.3208 19.4626 13.3572 19.468 13.3677C19.5061 13.4425 19.5668 13.5032 19.6415 13.5413C19.652 13.5467 19.6884 13.5633 19.813 13.5735C19.9441 13.5842 20.1177 13.5846 20.3938 13.5846H22.1098C22.3859 13.5846 22.5596 13.5842 22.6906 13.5735C22.8152 13.5633 22.8516 13.5467 22.8621 13.5413C22.9369 13.5032 22.9976 13.4425 23.0357 13.3677C23.0411 13.3572 23.0577 13.3208 23.0679 13.1963C23.0787 13.0652 23.0791 12.8915 23.0792 12.6154L23.0795 10.8995C23.0796 10.6233 23.0792 10.4497 23.0685 10.3186C23.0584 10.194 23.0418 10.1577 23.0364 10.1472C22.9983 10.0724 22.9376 10.0116 22.8629 9.97357C22.8524 9.96821 22.816 9.95159 22.6914 9.94141C22.5603 9.9307 22.3867 9.93027 22.1105 9.93027H20.3946C20.1185 9.93027 19.9448 9.9307 19.8137 9.94141Z" fill="#6384CB" style="fill:#6384CB;fill:color(display-p3 0.3887 0.5181 0.7969);fill-opacity:1;"/>
<path d="M20.9332 17.9539C20.6699 17.9539 20.4565 18.1673 20.4564 18.4306L20.4563 19.0661C20.4562 19.3294 20.6696 19.5428 20.9328 19.5428H21.5684C21.8316 19.5428 22.0451 19.3294 22.0451 19.0661L22.0452 18.4306C22.0453 18.1673 21.8319 17.9539 21.5687 17.9539H20.9332Z" fill="#6384CB" style="fill:#6384CB;fill:color(display-p3 0.3887 0.5181 0.7969);fill-opacity:1;"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M20.3727 15.809H22.1301C22.3793 15.809 22.5989 15.809 22.7808 15.8238C22.9741 15.8396 23.1731 15.875 23.3665 15.9735C23.6505 16.1182 23.8814 16.3491 24.026 16.6331C24.1246 16.8266 24.1598 17.0256 24.1756 17.219C24.1904 17.4008 24.1904 17.6204 24.1903 17.8696L24.1899 19.6271C24.1899 19.8763 24.1899 20.0959 24.175 20.2777C24.1591 20.4711 24.1238 20.6701 24.0252 20.8636C23.8804 21.1476 23.6494 21.3785 23.3654 21.5232C23.172 21.6217 22.9729 21.6571 22.7795 21.6729C22.5977 21.6877 22.3781 21.6877 22.1289 21.6877H20.3714C20.1222 21.6877 19.9026 21.6877 19.7208 21.6729C19.5274 21.6571 19.3284 21.6217 19.135 21.5232C18.851 21.3785 18.6201 21.1476 18.4755 20.8636C18.377 20.6701 18.3417 20.4711 18.3259 20.2777C18.3111 20.0959 18.3112 19.8763 18.3112 19.6271L18.3116 17.8696C18.3116 17.6204 18.3117 17.4008 18.3265 17.219C18.3424 17.0256 18.3778 16.8266 18.4763 16.6331C18.6211 16.3491 18.8521 16.1182 19.1361 15.9735C19.3296 15.875 19.5286 15.8396 19.722 15.8238C19.9038 15.809 20.1234 15.809 20.3727 15.809ZM19.8123 16.9323C19.6877 16.9425 19.6513 16.9591 19.6408 16.9645C19.5661 17.0026 19.5053 17.0633 19.4672 17.1381C19.4619 17.1486 19.4452 17.185 19.435 17.3095C19.4243 17.4406 19.4238 17.6143 19.4238 17.8904L19.4234 19.6063C19.4234 19.8825 19.4238 20.0561 19.4344 20.1872C19.4446 20.3117 19.4612 20.3481 19.4666 20.3586C19.5046 20.4334 19.5654 20.4941 19.6401 20.5322C19.6506 20.5376 19.687 20.5542 19.8116 20.5644C19.9426 20.5751 20.1163 20.5755 20.3924 20.5755H22.1084C22.3845 20.5755 22.5581 20.5751 22.6892 20.5644C22.8138 20.5542 22.8502 20.5376 22.8607 20.5322C22.9354 20.4941 22.9962 20.4334 23.0343 20.3586C23.0397 20.3481 23.0563 20.3117 23.0665 20.1872C23.0772 20.0561 23.0777 19.8825 23.0778 19.6063L23.0781 17.8904C23.0782 17.6143 23.0778 17.4406 23.0671 17.3095C23.0569 17.185 23.0403 17.1486 23.035 17.1381C22.9969 17.0633 22.9361 17.0026 22.8614 16.9645C22.8509 16.9591 22.8145 16.9425 22.69 16.9323C22.5589 16.9216 22.3852 16.9212 22.1091 16.9212H20.3932C20.117 16.9212 19.9434 16.9216 19.8123 16.9323Z" fill="#6384CB" style="fill:#6384CB;fill:color(display-p3 0.3887 0.5181 0.7969);fill-opacity:1;"/>
<path d="M27.9255 10.963C27.6623 10.963 27.4488 11.1764 27.4487 11.4397L27.4486 12.0752C27.4486 12.3385 27.6619 12.5519 27.9252 12.5519H28.5607C28.824 12.5519 29.0374 12.3385 29.0375 12.0752L29.0376 11.4397C29.0376 11.1764 28.8243 10.963 28.561 10.963H27.9255Z" fill="#6384CB" style="fill:#6384CB;fill:color(display-p3 0.3887 0.5181 0.7969);fill-opacity:1;"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M27.365 8.81808C27.1158 8.81807 26.8962 8.81806 26.7143 8.83292C26.521 8.84871 26.3219 8.88404 26.1285 8.9826C25.8444 9.12731 25.6135 9.35822 25.4687 9.64223C25.3701 9.83565 25.3347 10.0347 25.3189 10.2281C25.304 10.4099 25.304 10.6295 25.3039 10.8787L25.3036 12.6361C25.3035 12.8854 25.3034 13.105 25.3183 13.2868C25.334 13.4802 25.3693 13.6792 25.4678 13.8727C25.6125 14.1567 25.8433 14.3876 26.1273 14.5323C26.3207 14.6308 26.5198 14.6662 26.7131 14.682C26.8949 14.6968 27.1146 14.6968 27.3637 14.6968H29.1212C29.3704 14.6968 29.5901 14.6968 29.7719 14.682C29.9653 14.6662 30.1643 14.6308 30.3577 14.5323C30.6418 14.3876 30.8727 14.1567 31.0175 13.8727C31.1161 13.6792 31.1515 13.4802 31.1673 13.2868C31.1822 13.105 31.1822 12.8854 31.1823 12.6362L31.1826 10.8787C31.1827 10.6295 31.1828 10.4099 31.1679 10.2281C31.1522 10.0347 31.1169 9.83565 31.0184 9.64223C30.8737 9.35822 30.6429 9.12731 30.3589 8.9826C30.1655 8.88404 29.9664 8.84871 29.7731 8.83292C29.5913 8.81806 29.3716 8.81807 29.1224 8.81808H27.365ZM26.6332 9.97357C26.6437 9.96821 26.6801 9.95159 26.8047 9.94141C26.9357 9.9307 27.1094 9.93027 27.3855 9.93027H29.1015C29.3776 9.93027 29.5512 9.9307 29.6823 9.94141C29.8069 9.95159 29.8433 9.96821 29.8538 9.97357C29.9285 10.0116 29.9892 10.0724 30.0273 10.1472C30.0327 10.1577 30.0493 10.194 30.0594 10.3186C30.0701 10.4497 30.0705 10.6233 30.0705 10.8995L30.0701 12.6154C30.07 12.8915 30.0696 13.0652 30.0588 13.1963C30.0486 13.3208 30.032 13.3572 30.0267 13.3677C29.9886 13.4425 29.9278 13.5032 29.853 13.5413C29.8425 13.5467 29.8061 13.5633 29.6816 13.5735C29.5505 13.5842 29.3768 13.5846 29.1007 13.5846H27.3848C27.1086 13.5846 26.935 13.5842 26.8039 13.5735C26.6793 13.5633 26.643 13.5467 26.6325 13.5413C26.5577 13.5032 26.497 13.4425 26.4589 13.3677C26.4536 13.3572 26.4369 13.3208 26.4268 13.1963C26.4161 13.0652 26.4157 12.8915 26.4158 12.6154L26.4161 10.8995C26.4162 10.6233 26.4166 10.4497 26.4274 10.3186C26.4376 10.194 26.4542 10.1577 26.4596 10.1472C26.4977 10.0724 26.5584 10.0116 26.6332 9.97357Z" fill="#6384CB" style="fill:#6384CB;fill:color(display-p3 0.3887 0.5181 0.7969);fill-opacity:1;"/>
<path d="M26.1767 16.2062C25.9134 16.2062 25.7 16.4196 25.6999 16.6829L25.6998 17.3184C25.6998 17.5816 25.9131 17.795 26.1764 17.795H26.8119C27.0752 17.795 27.2886 17.5816 27.2887 17.3184L27.2888 16.6829C27.2888 16.4196 27.0755 16.2062 26.8122 16.2062H26.1767Z" fill="#6384CB" style="fill:#6384CB;fill:color(display-p3 0.3887 0.5181 0.7969);fill-opacity:1;"/>
<path d="M27.4473 18.4306C27.4474 18.1673 27.6608 17.9539 27.9241 17.9539H28.5596C28.8228 17.9539 29.0362 18.1673 29.0362 18.4306L29.036 19.0661C29.036 19.3294 28.8225 19.5428 28.5593 19.5428H27.9237C27.6605 19.5428 27.4471 19.3294 27.4472 19.0661L27.4473 18.4306Z" fill="#6384CB" style="fill:#6384CB;fill:color(display-p3 0.3887 0.5181 0.7969);fill-opacity:1;"/>
<path d="M29.1947 20.1783C29.1947 19.9151 29.4082 19.7017 29.6714 19.7017H30.307C30.5702 19.7017 30.7836 19.9151 30.7835 20.1783L30.7834 20.8138C30.7833 21.0771 30.5699 21.2905 30.3066 21.2905H29.6711C29.4079 21.2905 29.1945 21.0771 29.1946 20.8138L29.1947 20.1783Z" fill="#6384CB" style="fill:#6384CB;fill:color(display-p3 0.3887 0.5181 0.7969);fill-opacity:1;"/>
<path d="M29.6722 16.2062C29.4089 16.2062 29.1955 16.4196 29.1954 16.6829L29.1953 17.3184C29.1952 17.5816 29.4086 17.795 29.6718 17.795H30.3074C30.5706 17.795 30.7841 17.5816 30.7841 17.3184L30.7842 16.6829C30.7843 16.4196 30.5709 16.2062 30.3077 16.2062H29.6722Z" fill="#6384CB" style="fill:#6384CB;fill:color(display-p3 0.3887 0.5181 0.7969);fill-opacity:1;"/>
<path d="M25.6992 20.1783C25.6993 19.9151 25.9127 19.7017 26.176 19.7017H26.8115C27.0748 19.7017 27.2881 19.9151 27.2881 20.1783L27.2879 20.8138C27.2879 21.0771 27.0744 21.2905 26.8112 21.2905H26.1757C25.9124 21.2905 25.699 21.0771 25.6991 20.8138L25.6992 20.1783Z" fill="#6384CB" style="fill:#6384CB;fill:color(display-p3 0.3887 0.5181 0.7969);fill-opacity:1;"/>
</svg>

After

Width:  |  Height:  |  Size: 21 KiB

View File

@ -0,0 +1,5 @@
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M40 20C40 8.9543 31.0457 0 20 0C8.9543 0 0 8.9543 0 20C0 31.0457 8.9543 40 20 40C31.0457 40 40 31.0457 40 20Z" fill="#ADB4F1" style="fill:#ADB4F1;fill:color(display-p3 0.6765 0.7053 0.9461);fill-opacity:1;"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M20 38.3333C9.87478 38.3333 1.66667 30.1252 1.66667 20C1.66667 9.87478 9.87478 1.66667 20 1.66667C30.1252 1.66667 38.3333 9.87478 38.3333 20C38.3333 30.1252 30.1252 38.3333 20 38.3333ZM20 40C31.0457 40 40 31.0457 40 20C40 8.9543 31.0457 0 20 0C8.9543 0 0 8.9543 0 20C0 31.0457 8.9543 40 20 40Z" fill="#6A73C0" style="fill:#6A73C0;fill:color(display-p3 0.4162 0.4523 0.7544);fill-opacity:1;"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M10 20C10 14.4772 14.4772 10 20 10C25.5228 10 30 14.4772 30 20C30 21.5325 29.6779 22.5276 29.2669 23.1078C28.8857 23.646 28.3909 23.8889 27.7778 23.8889C27.0484 23.8889 26.1111 23.0873 26.1111 21.9445V20C26.1111 16.625 23.3751 13.8889 20 13.8889C16.6249 13.8889 13.8889 16.625 13.8889 20C13.8889 23.3751 16.6249 26.1111 20 26.1111C21.7807 26.1111 23.3835 25.3495 24.5005 24.1343C25.2015 25.3056 26.4289 26.1111 27.7778 26.1111C29.1091 26.1111 30.281 25.5208 31.0803 24.3923C31.8499 23.3058 32.2222 21.8009 32.2222 20C32.2222 13.2499 26.7501 7.77781 20 7.77781C13.2499 7.77781 7.77778 13.2499 7.77778 20C7.77778 26.7502 13.2499 32.2223 20 32.2223C22.2244 32.2223 24.3131 31.627 26.1119 30.5865C26.6431 30.2792 26.8246 29.5995 26.5173 29.0683C26.2101 28.5371 25.5304 28.3556 24.9992 28.6629C23.5295 29.5131 21.8233 30 20 30C14.4772 30 10 25.5229 10 20ZM23.8889 20C23.8889 22.1478 22.1478 23.8889 20 23.8889C17.8522 23.8889 16.1111 22.1478 16.1111 20C16.1111 17.8523 17.8522 16.1111 20 16.1111C22.1478 16.1111 23.8889 17.8523 23.8889 20Z" fill="white" style="fill:white;fill-opacity:1;"/>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -0,0 +1,4 @@
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="20" cy="20" r="19.175" fill="#ADB4F1" stroke-width="1.65" stroke="black"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M10 20C10 14.4772 14.4772 10 20 10C25.5228 10 30 14.4772 30 20C30 21.5324 29.6779 22.5276 29.2669 23.1078C28.8857 23.6459 28.3909 23.8889 27.7778 23.8889C27.0484 23.8889 26.1111 23.0873 26.1111 21.9444V20C26.1111 16.6249 23.3751 13.8889 20 13.8889C16.6249 13.8889 13.8889 16.6249 13.8889 20C13.8889 23.3751 16.6249 26.1111 20 26.1111C21.7807 26.1111 23.3835 25.3495 24.5005 24.1342C25.2015 25.3055 26.4289 26.1111 27.7778 26.1111C29.1091 26.1111 30.281 25.5207 31.0803 24.3922C31.8499 23.3057 32.2222 21.8009 32.2222 20C32.2222 13.2499 26.7501 7.77778 20 7.77778C13.2499 7.77778 7.77778 13.2499 7.77778 20C7.77778 26.7501 13.2499 32.2222 20 32.2222C22.2244 32.2222 24.3131 31.627 26.1119 30.5864C26.6431 30.2792 26.8246 29.5995 26.5173 29.0683C26.2101 28.5371 25.5304 28.3556 24.9992 28.6629C23.5295 29.5131 21.8233 30 20 30C14.4772 30 10 25.5228 10 20ZM23.8889 20C23.8889 17.8522 22.1478 16.1111 20 16.1111C17.8522 16.1111 16.1111 17.8522 16.1111 20C16.1111 22.1478 17.8522 23.8889 20 23.8889C22.1478 23.8889 23.8889 22.1478 23.8889 20Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -265,6 +265,7 @@ $z-index-negative: -1;
$z-index-base: 1;
$z-index-above-base: 2;
$z-index-above-above-base: 3;
$z-index-megaphone: 75;
$z-index-popup-overlay: 99;
$z-index-popup: 100;
$z-index-context-menu: 125;

View File

@ -6,7 +6,6 @@
@include font-body-2;
position: absolute;
align-items: stretch;
border-radius: $border-radius-px;
box-shadow: 0px 0px 4px rgba(0, 0, 0, 0.05), 0px 4px 12px rgba(0, 0, 0, 0.3);
@ -14,11 +13,14 @@
justify-content: space-between;
user-select: none;
overflow: hidden;
z-index: $z-index-toast;
bottom: 62px;
width: fit-content;
max-width: 280px;
background-color: $color-gray-75;
color: $color-gray-05;
z-index: $z-index-toast;
inset-inline-start: 20px;
text-align: start;
&:focus {
outline: none;
@ -27,15 +29,13 @@
}
}
&--align-center {
@include position-absolute-center-x;
text-align: center;
.ToastManager--narrow-sidebar & {
min-width: max-content;
}
&--align-left {
inset-inline-start: 20px;
bottom: 18px;
text-align: start;
.ToastManager--narrow-sidebar.ToastManager--composition-area-visible & {
min-width: initial;
text-align: center;
}
&__content {

View File

@ -0,0 +1,45 @@
// Copyright 2024 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
.ToastManager {
display: flex;
flex-direction: column;
pointer-events: none;
gap: 16px;
// Sync inner width with left pane
position: fixed;
width: inherit;
bottom: 0;
z-index: $z-index-toast;
padding: 16px;
& * {
pointer-events: auto;
}
// Separate container used when modals are on screen
&__root {
display: flex;
flex-direction: column;
position: fixed;
bottom: 16px;
z-index: $z-index-toast;
inset-inline-start: 0;
width: 100%;
align-items: center;
}
}
.ToastManager--narrow-sidebar.ToastManager--composition-area-visible {
inset-inline-start: 0;
width: 100%;
align-items: center;
// Roughly size of composer + a bit of padding
bottom: 40px;
}

View File

@ -0,0 +1,110 @@
// Copyright 2024 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
.UsernameMegaphone {
@include font-body-2;
border-radius: 10px;
box-shadow: 0px 4px 8px 0px rgba(0, 0, 0, 0.08);
display: flex;
flex-direction: column;
user-select: none;
z-index: $z-index-megaphone;
padding-block: 12px;
padding-inline: 8px;
@include light-theme {
background-color: $color-white;
border: 1px solid $color-gray-20;
}
@include dark-theme {
background: $color-gray-75;
border: 1px solid $color-gray-60;
}
&__row {
display: flex;
flex-direction: row;
margin-top: 4px;
margin-bottom: 12px;
gap: 12px;
}
&__row__icon {
flex-shrink: 0;
width: 40px;
height: 40px;
margin-bottom: 2px;
margin-inline-start: 8px;
background-size: cover;
@include light-theme {
background-image: url(../images/usernames_40_color.svg);
}
@include dark-theme {
background-image: url(../images/usernames_40_color_dark.svg);
}
}
&__row__text {
@include font-body-2;
h2 {
@include font-body-2-bold;
margin: 0;
line-height: 20px;
}
p {
margin: 0;
@include light-theme {
color: $color-gray-60;
}
@include dark-theme {
color: $color-gray-25;
}
}
}
&__buttons {
display: flex;
flex-direction: row;
justify-content: end;
gap: 12px;
}
&__buttons__button {
margin-bottom: 0;
font-weight: 600;
padding-block: 5px;
@include light-theme {
background: transparent;
&:hover,
&:active {
@include not-disabled {
background: transparent;
}
}
}
@include dark-theme {
background: transparent;
&:hover,
&:active {
@include not-disabled {
background: transparent;
}
}
}
}
.NavSidebar--narrow & {
display: none;
}
}

View File

@ -0,0 +1,125 @@
// Copyright 2023 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
.UsernameOnboardingModal {
display: flex;
flex-direction: column;
align-items: center;
user-select: none;
&__title {
@include font-title-2;
margin-bottom: 20px;
max-width: 240px;
text-align: center;
}
&__row {
display: flex;
gap: 24px;
margin-bottom: 32px;
&__icon {
flex-shrink: 0;
width: 40px;
height: 40px;
background-size: cover;
&--number {
@include light-theme {
background-image: url(../images/phone_40_color.svg);
}
@include dark-theme {
background-image: url(../images/phone_40_color_dark.svg);
}
}
&--username {
@include light-theme {
background-image: url(../images/usernames_40_color.svg);
}
@include dark-theme {
background-image: url(../images/usernames_40_color_dark.svg);
}
}
&--qr {
@include light-theme {
background-image: url(../images/qr_codes_40_color.svg);
}
@include dark-theme {
background-image: url(../images/qr_codes_40_color_dark.svg);
}
}
}
&__body {
@include font-body-2;
@include light-theme {
color: $color-gray-60;
}
@include dark-theme {
color: $color-gray-25;
}
max-width: 248px;
h2 {
@include font-body-1;
margin-top: 0;
margin-bottom: 2px;
font-weight: 400;
@include light-theme {
color: $color-gray-90;
}
@include dark-theme {
color: $color-gray-05;
}
}
}
&--center {
justify-content: center;
}
}
&__submit {
width: 100%;
max-width: 296px;
margin-top: 16px;
margin-bottom: 12px;
}
&__skip {
margin-bottom: 0;
@include light-theme {
background: transparent;
&:hover,
&:active {
@include not-disabled {
background: transparent;
}
}
}
@include dark-theme {
background: transparent;
&:hover,
&:active {
@include not-disabled {
background: transparent;
}
}
}
}
}

View File

@ -1,106 +0,0 @@
// Copyright 2023 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
.UsernameOnboardingModalBody {
display: flex;
flex-direction: column;
align-items: center;
user-select: none;
&__large-at {
display: flex;
align-items: center;
justify-content: center;
width: 48px;
height: 48px;
border-radius: 24px;
margin-bottom: 12px;
@include light-theme {
background-color: $color-gray-04;
}
@include dark-theme {
background-color: $color-gray-65;
}
&::after {
display: block;
width: 28px;
height: 28px;
content: '';
@include light-theme {
@include color-svg('../images/icons/v3/at/at.svg', $color-gray-75);
}
@include dark-theme {
@include color-svg('../images/icons/v3/at/at.svg', $color-gray-15);
}
}
}
&__title {
@include font-title-2;
margin-bottom: 20px;
max-width: 240px;
text-align: center;
}
&__row {
display: flex;
gap: 16px;
margin-bottom: 24px;
&__icon {
flex-shrink: 0;
width: 32px;
height: 32px;
&--number {
background: url(../images/icons/v2/number_color_32.svg);
}
&--link {
width: 32px;
height: 34px;
background: url(../images/qr-and-link.svg);
}
&--lock {
background: url(../images/icons/v2/lock_color_32.svg);
}
}
&__body {
@include font-body-2;
@include light-theme {
color: $color-gray-60;
}
@include dark-theme {
color: $color-gray-25;
}
max-width: 248px;
}
&--center {
justify-content: center;
}
}
&__learn-more {
text-decoration: none;
font-weight: 600;
}
&__submit {
width: 100%;
max-width: 296px;
margin-bottom: 16px;
}
}

View File

@ -155,8 +155,10 @@
@import './components/TimelineWarning.scss';
@import './components/TimelineWarnings.scss';
@import './components/Toast.scss';
@import './components/ToastManager.scss';
@import './components/Waveform.scss';
@import './components/WaveformScrubber.scss';
@import './components/UsernameLinkModalBody.scss';
@import './components/UsernameOnboardingModalBody.scss';
@import './components/UsernameMegaphone.scss';
@import './components/UsernameOnboardingModal.scss';
@import './components/WhatsNew.scss';

View File

@ -29,6 +29,7 @@ import { ReceiptType } from './types/Receipt';
import { SocketStatus } from './types/SocketStatus';
import { DEFAULT_CONVERSATION_COLOR } from './types/Colors';
import { ThemeType } from './types/Util';
import { ToastType } from './types/Toast';
import { ChallengeHandler } from './challenge';
import * as durations from './util/durations';
import { drop } from './util/drop';
@ -143,9 +144,6 @@ import { normalizeAci } from './util/normalizeAci';
import * as log from './logging/log';
import { loadRecentEmojis } from './util/loadRecentEmojis';
import { deleteAllLogs } from './util/deleteAllLogs';
import { ToastCaptchaFailed } from './components/ToastCaptchaFailed';
import { ToastCaptchaSolved } from './components/ToastCaptchaSolved';
import { showToast } from './util/showToast';
import { startInteractionMode } from './services/InteractionMode';
import type { MainWindowStatsType } from './windows/context';
import { ReactionSource } from './reactions/ReactionSource';
@ -278,11 +276,15 @@ export async function startApp(): Promise<void> {
onChallengeFailed() {
// TODO: DESKTOP-1530
// Display humanized `retryAfter`
showToast(ToastCaptchaFailed);
window.reduxActions.toast.showToast({
toastType: ToastType.CaptchaFailed,
});
},
onChallengeSolved() {
showToast(ToastCaptchaSolved);
window.reduxActions.toast.showToast({
toastType: ToastType.CaptchaSolved,
});
},
setChallengeStatus(challengeStatus) {

View File

@ -5,15 +5,12 @@ import React, { useEffect } from 'react';
import { Globals } from '@react-spring/web';
import classNames from 'classnames';
import type { AnyToast } from '../types/Toast';
import type { ViewStoryActionCreatorType } from '../state/ducks/stories';
import type { LocalizerType } from '../types/Util';
import type { VerificationTransport } from '../types/VerificationTransport';
import { ThemeType } from '../types/Util';
import { AppViewType } from '../state/ducks/app';
import { SmartInstallScreen } from '../state/smart/InstallScreen';
import { StandaloneRegistration } from './StandaloneRegistration';
import { ToastManager } from './ToastManager';
import { usePageVisibility } from '../hooks/usePageVisibility';
import { useReducedMotion } from '../hooks/useReducedMotion';
@ -27,7 +24,6 @@ type PropsType = {
) => Promise<void>;
renderCallManager: () => JSX.Element;
renderGlobalModalContainer: () => JSX.Element;
i18n: LocalizerType;
hasSelectedStoryData: boolean;
renderStoryViewer: (closeView: () => unknown) => JSX.Element;
renderLightbox: () => JSX.Element | null;
@ -39,13 +35,8 @@ type PropsType = {
theme: ThemeType;
isMaximized: boolean;
isFullScreen: boolean;
onUndoArchive: (conversationId: string) => unknown;
openFileInFolder: (target: string) => unknown;
OS: string;
osClassName: string;
hideToast: () => unknown;
toast?: AnyToast;
scrollToMessage: (conversationId: string, messageId: string) => unknown;
viewStory: ViewStoryActionCreatorType;
renderInbox: () => JSX.Element;
@ -54,14 +45,9 @@ type PropsType = {
export function App({
appView,
hasSelectedStoryData,
hideToast,
i18n,
isFullScreen,
isMaximized,
onUndoArchive,
openFileInFolder,
openInbox,
OS,
osClassName,
registerSingleDevice,
renderCallManager,
@ -71,7 +57,6 @@ export function App({
renderStoryViewer,
requestVerification,
theme,
toast,
viewStory,
}: PropsType): JSX.Element {
let contents;
@ -139,14 +124,6 @@ export function App({
})}
>
{contents}
<ToastManager
OS={OS}
hideToast={hideToast}
i18n={i18n}
onUndoArchive={onUndoArchive}
openFileInFolder={openFileInFolder}
toast={toast}
/>
{renderGlobalModalContainer()}
{renderCallManager()}
{renderLightbox()}

View File

@ -17,6 +17,7 @@ import type { ActiveCallStateType } from '../state/ducks/calling';
import { ContextMenu } from './ContextMenu';
import { ConfirmationDialog } from './ConfirmationDialog';
import type { UnreadStats } from '../util/countUnreadStats';
import type { WidthBreakpoint } from './_util';
enum CallsTabSidebarView {
CallsListView,
@ -50,6 +51,9 @@ type CallsTabProps = Readonly<{
conversationId: string,
callHistoryGroup: CallHistoryGroup | null
) => JSX.Element;
renderToastManager: (_: {
containerWidthBreakpoint: WidthBreakpoint;
}) => JSX.Element;
regionCode: string | undefined;
savePreferredLeftPaneWidth: (preferredLeftPaneWidth: number) => void;
}>;
@ -73,6 +77,7 @@ export function CallsTab({
onOutgoingVideoCallInConversation,
preferredLeftPaneWidth,
renderConversationDetails,
renderToastManager,
regionCode,
savePreferredLeftPaneWidth,
}: CallsTabProps): JSX.Element {
@ -175,6 +180,7 @@ export function CallsTab({
requiresFullWidth
preferredLeftPaneWidth={preferredLeftPaneWidth}
savePreferredLeftPaneWidth={savePreferredLeftPaneWidth}
renderToastManager={renderToastManager}
actions={
<>
{sidebarView === CallsTabSidebarView.CallsListView && (

View File

@ -563,6 +563,7 @@ export function CompositionArea({
conversationId={conversationId}
draftAttachments={draftAttachments}
i18n={i18n}
showToast={showToast}
startRecording={startRecording}
/>
</div>

View File

@ -51,6 +51,8 @@ export function Default(): JSX.Element {
errorRecording={_ => action('error')()}
addAttachment={action('addAttachment')}
completeRecording={action('completeRecording')}
showToast={action('showToast')}
hideToast={action('hideToast')}
/>
)}
</>

View File

@ -5,14 +5,16 @@ import { noop } from 'lodash';
import React, { useCallback, useEffect, useRef, useState } from 'react';
import { useEscapeHandling } from '../hooks/useEscapeHandling';
import { usePrevious } from '../hooks/usePrevious';
import type { HideToastAction, ShowToastAction } from '../state/ducks/toast';
import type { InMemoryAttachmentDraftType } from '../types/Attachment';
import { ErrorDialogAudioRecorderType } from '../types/AudioRecorder';
import type { LocalizerType } from '../types/Util';
import type { AnyToast } from '../types/Toast';
import { ToastType } from '../types/Toast';
import { DurationInSeconds, SECOND } from '../util/durations';
import { durationToPlaybackText } from '../util/durationToPlaybackText';
import { ConfirmationDialog } from './ConfirmationDialog';
import { RecordingComposer } from './RecordingComposer';
import { ToastVoiceNoteLimit } from './ToastVoiceNoteLimit';
export type Props = {
i18n: LocalizerType;
@ -29,6 +31,8 @@ export type Props = {
conversationId: string,
onRecordingComplete: (rec: InMemoryAttachmentDraftType) => unknown
) => unknown;
showToast: ShowToastAction;
hideToast: HideToastAction;
};
export function CompositionRecording({
@ -40,11 +44,11 @@ export function CompositionRecording({
errorDialogAudioRecorderType,
addAttachment,
completeRecording,
showToast,
hideToast,
}: Props): JSX.Element {
useEscapeHandling(onCancel);
const [showVoiceNoteLimitToast, setShowVoiceNoteLimitToast] = useState(true);
// when interrupted (blur, switching convos)
// stop recording and save draft
const handleRecordingInterruption = useCallback(() => {
@ -69,15 +73,12 @@ export function CompositionRecording({
}
});
const handleCloseToast = useCallback(() => {
setShowVoiceNoteLimitToast(false);
}, []);
useEffect(() => {
return () => {
handleCloseToast();
};
}, [handleCloseToast]);
const toast: AnyToast = { toastType: ToastType.VoiceNoteLimit };
showToast(toast);
return () => hideToast(toast);
}, [showToast, hideToast]);
const startTime = useRef(Date.now());
const [duration, setDuration] = useState(0);
@ -148,9 +149,6 @@ export function CompositionRecording({
</div>
{confirmationDialog}
{showVoiceNoteLimitToast && (
<ToastVoiceNoteLimit i18n={i18n} onClose={handleCloseToast} />
)}
</RecordingComposer>
);
}

View File

@ -6,13 +6,15 @@ import React, { useEffect, useState } from 'react';
import copyText from 'copy-text-to-clipboard';
import type { LocalizerType } from '../types/Util';
import * as Errors from '../types/errors';
import type { AnyToast } from '../types/Toast';
import { ToastType } from '../types/Toast';
import * as log from '../logging/log';
import { Button, ButtonVariant } from './Button';
import { Spinner } from './Spinner';
import { ToastDebugLogError } from './ToastDebugLogError';
import { ToastLinkCopied } from './ToastLinkCopied';
import { ToastLoadingFullLogs } from './ToastLoadingFullLogs';
import { ToastManager } from './ToastManager';
import { WidthBreakpoint } from './_util';
import { createSupportUrl } from '../util/createSupportUrl';
import { shouldNeverBeCalled } from '../util/shouldNeverBeCalled';
import { openLinkInWebBrowser } from '../util/openLinkInWebBrowser';
import { useEscapeHandling } from '../hooks/useEscapeHandling';
@ -31,12 +33,6 @@ export type PropsType = {
uploadLogs: (logs: string) => Promise<string>;
};
enum ToastType {
Copied,
Error,
Loading,
}
export function DebugLogWindow({
closeWindow,
downloadLog,
@ -50,7 +46,7 @@ export function DebugLogWindow({
const [textAreaValue, setTextAreaValue] = useState<string>(
i18n('icu:loading')
);
const [toastType, setToastType] = useState<ToastType | undefined>();
const [toast, setToast] = useState<AnyToast | undefined>();
useEscapeHandling(closeWindow);
@ -66,7 +62,7 @@ export function DebugLogWindow({
return;
}
setToastType(ToastType.Loading);
setToast({ toastType: ToastType.LoadingFullLogs });
setLogText(fetchedLogText);
setLoadState(LoadState.Loaded);
@ -76,7 +72,7 @@ export function DebugLogWindow({
const value = fetchedLogText.split(/\n/g, linesToShow).join('\n');
setTextAreaValue(`${value}\n\n\n${i18n('icu:debugLogLogIsIncomplete')}`);
setToastType(undefined);
setToast(undefined);
}
void doFetchLogs();
@ -103,28 +99,19 @@ export function DebugLogWindow({
} catch (error) {
log.error('DebugLogWindow error:', Errors.toLogFormat(error));
setLoadState(LoadState.Loaded);
setToastType(ToastType.Error);
setToast({ toastType: ToastType.DebugLogError });
}
};
function closeToast() {
setToastType(undefined);
}
let toastElement: JSX.Element | undefined;
if (toastType === ToastType.Loading) {
toastElement = <ToastLoadingFullLogs i18n={i18n} onClose={closeToast} />;
} else if (toastType === ToastType.Copied) {
toastElement = <ToastLinkCopied i18n={i18n} onClose={closeToast} />;
} else if (toastType === ToastType.Error) {
toastElement = <ToastDebugLogError i18n={i18n} onClose={closeToast} />;
setToast(undefined);
}
if (publicLogURL) {
const copyLog = (ev: MouseEvent) => {
ev.preventDefault();
copyText(publicLogURL);
setToastType(ToastType.Copied);
setToast({ toastType: ToastType.LinkCopied });
};
const supportURL = createSupportUrl({
@ -162,7 +149,16 @@ export function DebugLogWindow({
</Button>
<Button onClick={copyLog}>{i18n('icu:debugLogCopy')}</Button>
</div>
{toastElement}
<ToastManager
OS="unused"
hideToast={closeToast}
i18n={i18n}
onShowDebugLog={shouldNeverBeCalled}
onUndoArchive={shouldNeverBeCalled}
openFileInFolder={shouldNeverBeCalled}
toast={toast}
containerWidthBreakpoint={WidthBreakpoint.Narrow}
/>
</div>
);
}
@ -209,7 +205,16 @@ export function DebugLogWindow({
{i18n('icu:submit')}
</Button>
</div>
{toastElement}
<ToastManager
OS="unused"
hideToast={closeToast}
i18n={i18n}
onShowDebugLog={shouldNeverBeCalled}
onUndoArchive={shouldNeverBeCalled}
openFileInFolder={shouldNeverBeCalled}
toast={toast}
containerWidthBreakpoint={WidthBreakpoint.Narrow}
/>
</div>
);
}

View File

@ -14,6 +14,7 @@ import type {
UserNotFoundModalStateType,
} from '../state/ducks/globalModals';
import type { LocalizerType, ThemeType } from '../types/Util';
import { UsernameOnboardingState } from '../types/globalModals';
import type { ExplodePromiseResultType } from '../util/explodePromise';
import { missingCaseError } from '../util/missingCaseError';
@ -90,6 +91,9 @@ export type PropsType = {
// WhatsNewModal
isWhatsNewVisible: boolean;
hideWhatsNewModal: () => unknown;
// UsernameOnboarding
usernameOnboardingState: UsernameOnboardingState;
renderUsernameOnboarding: () => JSX.Element;
// AuthArtCreatorModal
authArtCreatorData?: AuthorizeArtCreatorDataType;
isAuthorizingArtCreator?: boolean;
@ -151,6 +155,9 @@ export function GlobalModalContainer({
// WhatsNewModal
hideWhatsNewModal,
isWhatsNewVisible,
// UsernameOnboarding
usernameOnboardingState,
renderUsernameOnboarding,
// AuthArtCreatorModal
authArtCreatorData,
isAuthorizingArtCreator,
@ -253,6 +260,10 @@ export function GlobalModalContainer({
return <WhatsNewModal hideWhatsNewModal={hideWhatsNewModal} i18n={i18n} />;
}
if (usernameOnboardingState === UsernameOnboardingState.Open) {
return renderUsernameOnboarding();
}
if (safetyNumberModalContactId) {
return renderSafetyNumber();
}

View File

@ -8,6 +8,7 @@ import type { PropsType } from './LeftPane';
import { LeftPane, LeftPaneMode } from './LeftPane';
import { CaptchaDialog } from './CaptchaDialog';
import { CrashReportDialog } from './CrashReportDialog';
import { ToastManager } from './ToastManager';
import type { PropsType as DialogNetworkStatusPropsType } from './DialogNetworkStatus';
import { DialogExpiredBuild } from './DialogExpiredBuild';
import { DialogNetworkStatus } from './DialogNetworkStatus';
@ -251,6 +252,19 @@ const useProps = (overrideProps: OverridePropsType = {}): PropsType => {
{...props}
/>
),
renderToastManager: ({ containerWidthBreakpoint }) => (
<ToastManager
OS="unused"
hideToast={action('hideToast')}
i18n={i18n}
onShowDebugLog={action('onShowDebugLog')}
onUndoArchive={action('onUndoArchive')}
openFileInFolder={action('openFileInFolder')}
toast={undefined}
megaphone={undefined}
containerWidthBreakpoint={containerWidthBreakpoint}
/>
),
selectedConversationId: undefined,
targetedMessageId: undefined,
savePreferredLeftPaneWidth: action('savePreferredLeftPaneWidth'),

View File

@ -158,6 +158,9 @@ export type PropsType = {
renderCaptchaDialog: (props: { onSkip(): void }) => JSX.Element;
renderCrashReportDialog: () => JSX.Element;
renderExpiredBuildDialog: (_: DialogExpiredBuildPropsType) => JSX.Element;
renderToastManager: (_: {
containerWidthBreakpoint: WidthBreakpoint;
}) => JSX.Element;
} & LookupConversationWithoutServiceIdActionsType;
export function LeftPane({
@ -200,6 +203,7 @@ export function LeftPane({
renderUnsupportedOSDialog,
renderRelinkDialog,
renderUpdateDialog,
renderToastManager,
savePreferredLeftPaneWidth,
searchInConversation,
selectedConversationId,
@ -597,6 +601,7 @@ export function LeftPane({
modeSpecificProps.isAboutToSearch
}
savePreferredLeftPaneWidth={savePreferredLeftPaneWidth}
renderToastManager={renderToastManager}
actions={
<>
<NavSidebarActionButton

View File

@ -36,6 +36,7 @@ export default {
onForward: jest.fn(action('onForward')),
onSave: jest.fn(action('onSave')),
hasViewReceiptSetting: false,
renderToastManager: () => <i />,
queueStoryDownload: action('queueStoryDownload'),
retryMessageSend: action('retryMessageSend'),
viewStory: action('viewStory'),

View File

@ -20,6 +20,7 @@ import { Theme } from '../util/theme';
import { resolveStorySendStatus } from '../util/resolveStorySendStatus';
import { useRetryStorySend } from '../hooks/useRetryStorySend';
import { NavSidebar } from './NavSidebar';
import type { WidthBreakpoint } from './_util';
import type { UnreadStats } from '../util/countUnreadStats';
export type PropsType = {
@ -40,6 +41,9 @@ export type PropsType = {
viewStory: ViewStoryActionCreatorType;
hasViewReceiptSetting: boolean;
preferredLeftPaneWidth: number;
renderToastManager: (_: {
containerWidthBreakpoint: WidthBreakpoint;
}) => JSX.Element;
savePreferredLeftPaneWidth: (preferredLeftPaneWidth: number) => void;
theme: ThemeType;
};
@ -62,6 +66,7 @@ export function MyStories({
onMediaPlaybackStart,
onToggleNavTabsCollapse,
preferredLeftPaneWidth,
renderToastManager,
savePreferredLeftPaneWidth,
theme,
}: PropsType): JSX.Element {
@ -98,6 +103,7 @@ export function MyStories({
onToggleNavTabsCollapse={onToggleNavTabsCollapse}
preferredLeftPaneWidth={preferredLeftPaneWidth}
requiresFullWidth
renderToastManager={renderToastManager}
savePreferredLeftPaneWidth={savePreferredLeftPaneWidth}
>
<div className="Stories__pane__list">

View File

@ -55,6 +55,9 @@ export type NavSidebarProps = Readonly<{
savePreferredLeftPaneWidth: (width: number) => void;
title: string;
otherTabsUnreadStats: UnreadStats;
renderToastManager: (_: {
containerWidthBreakpoint: WidthBreakpoint;
}) => JSX.Element;
}>;
enum DragState {
@ -78,6 +81,7 @@ export function NavSidebar({
savePreferredLeftPaneWidth,
title,
otherTabsUnreadStats,
renderToastManager,
}: NavSidebarProps): JSX.Element {
const isRTL = i18n.getLocaleDirection() === 'rtl';
const [dragState, setDragState] = useState(DragState.INITIAL);
@ -218,6 +222,8 @@ export function NavSidebar({
tabIndex={0}
{...moveProps}
/>
{renderToastManager({ containerWidthBreakpoint: widthBreakpoint })}
</div>
);
}

View File

@ -39,6 +39,7 @@ import type {
import { Button, ButtonVariant } from './Button';
import { ChatColorPicker } from './ChatColorPicker';
import { Checkbox } from './Checkbox';
import { WidthBreakpoint } from './_util';
import {
CircleCheckbox,
Variant as CircleCheckboxVariant,
@ -1581,9 +1582,11 @@ export function Preferences({
OS="unused"
hideToast={() => setToast(undefined)}
i18n={i18n}
onShowDebugLog={shouldNeverBeCalled}
onUndoArchive={shouldNeverBeCalled}
openFileInFolder={shouldNeverBeCalled}
toast={toast}
containerWidthBreakpoint={WidthBreakpoint.Narrow}
/>
</>
);

View File

@ -79,7 +79,6 @@ export default {
replaceAvatar: action('replaceAvatar'),
resetUsernameLink: action('resetUsernameLink'),
saveAvatarToDisk: action('saveAvatarToDisk'),
markCompletedUsernameOnboarding: action('markCompletedUsernameOnboarding'),
markCompletedUsernameLinkOnboarding: action(
'markCompletedUsernameLinkOnboarding'
),

View File

@ -39,7 +39,6 @@ import { missingCaseError } from '../util/missingCaseError';
import { ConfirmationDialog } from './ConfirmationDialog';
import { ContextMenu } from './ContextMenu';
import { UsernameLinkModalBody } from './UsernameLinkModalBody';
import { UsernameOnboardingModalBody } from './UsernameOnboardingModalBody';
import {
ConversationDetailsIcon,
IconType,
@ -54,7 +53,6 @@ export enum EditState {
ProfileName = 'ProfileName',
Bio = 'Bio',
Username = 'Username',
UsernameOnboarding = 'UsernameOnboarding',
UsernameLink = 'UsernameLink',
}
@ -75,13 +73,13 @@ export type PropsDataType = {
conversationId: string;
familyName?: string;
firstName: string;
hasCompletedUsernameOnboarding: boolean;
hasCompletedUsernameLinkOnboarding: boolean;
i18n: LocalizerType;
isUsernameFlagEnabled: boolean;
phoneNumber?: string;
userAvatarData: ReadonlyArray<AvatarDataType>;
username?: string;
initialEditState?: EditState;
usernameCorrupted: boolean;
usernameEditState: UsernameEditState;
usernameLinkState: UsernameLinkState;
@ -92,7 +90,6 @@ export type PropsDataType = {
type PropsActionType = {
deleteAvatarFromDisk: DeleteAvatarFromDiskActionType;
markCompletedUsernameOnboarding: () => void;
markCompletedUsernameLinkOnboarding: () => void;
onSetSkinTone: (tone: number) => unknown;
replaceAvatar: ReplaceAvatarActionType;
@ -147,11 +144,10 @@ export function ProfileEditor({
deleteUsername,
familyName,
firstName,
hasCompletedUsernameOnboarding,
hasCompletedUsernameLinkOnboarding,
i18n,
initialEditState = EditState.None,
isUsernameFlagEnabled,
markCompletedUsernameOnboarding,
markCompletedUsernameLinkOnboarding,
onEditStateChanged,
onProfileChanged,
@ -179,7 +175,7 @@ export function ProfileEditor({
usernameLinkCorrupted,
}: PropsType): JSX.Element {
const focusInputRef = useRef<HTMLInputElement | null>(null);
const [editState, setEditState] = useState<EditState>(EditState.None);
const [editState, setEditState] = useState<EditState>(initialEditState);
const [confirmDiscardAction, setConfirmDiscardAction] = useState<
(() => unknown) | undefined
>(undefined);
@ -518,16 +514,6 @@ export function ProfileEditor({
content = renderEditUsernameModalBody({
onClose: () => setEditState(EditState.None),
});
} else if (editState === EditState.UsernameOnboarding) {
content = (
<UsernameOnboardingModalBody
i18n={i18n}
onNext={() => {
markCompletedUsernameOnboarding();
setEditState(EditState.Username);
}}
/>
);
} else if (editState === EditState.UsernameLink) {
content = (
<UsernameLinkModalBody
@ -686,11 +672,7 @@ export function ProfileEditor({
}
openUsernameReservationModal();
if (username || hasCompletedUsernameOnboarding) {
setEditState(EditState.Username);
} else {
setEditState(EditState.UsernameOnboarding);
}
setEditState(EditState.Username);
}}
alwaysShowActions={alwaysShowActions}
actions={actions}

View File

@ -37,7 +37,6 @@ export function ProfileEditorModal({
[EditState.Bio]: i18n('icu:ProfileEditorModal--about'),
[EditState.None]: i18n('icu:ProfileEditorModal--profile'),
[EditState.ProfileName]: i18n('icu:ProfileEditorModal--name'),
[EditState.UsernameOnboarding]: undefined,
[EditState.Username]: i18n('icu:ProfileEditorModal--username'),
[EditState.UsernameLink]: undefined,
};

View File

@ -33,6 +33,7 @@ export default {
onSaveStory: action('onSaveStory'),
preferredWidthFromStorage: 380,
queueStoryDownload: action('queueStoryDownload'),
renderToastManager: () => <i />,
renderStoryCreator: () => <>StoryCreator</>,
retryMessageSend: action('retryMessageSend'),
showConversation: action('showConversation'),

View File

@ -24,6 +24,7 @@ import { StoriesPane } from './StoriesPane';
import { NavSidebar, NavSidebarActionButton } from './NavSidebar';
import { StoriesAddStoryButton } from './StoriesAddStoryButton';
import { ContextMenu } from './ContextMenu';
import type { WidthBreakpoint } from './_util';
import type { UnreadStats } from '../util/countUnreadStats';
export type PropsType = {
@ -50,6 +51,9 @@ export type PropsType = {
preferredWidthFromStorage: number;
queueStoryDownload: (storyId: string) => unknown;
renderStoryCreator: () => JSX.Element;
renderToastManager: (_: {
containerWidthBreakpoint: WidthBreakpoint;
}) => JSX.Element;
retryMessageSend: (messageId: string) => unknown;
savePreferredLeftPaneWidth: (preferredLeftPaneWidth: number) => void;
setAddStoryData: (data: AddStoryData) => unknown;
@ -84,6 +88,7 @@ export function StoriesTab({
preferredLeftPaneWidth,
queueStoryDownload,
renderStoryCreator,
renderToastManager,
retryMessageSend,
savePreferredLeftPaneWidth,
setAddStoryData,
@ -127,6 +132,7 @@ export function StoriesTab({
preferredLeftPaneWidth={preferredLeftPaneWidth}
queueStoryDownload={queueStoryDownload}
retryMessageSend={retryMessageSend}
renderToastManager={renderToastManager}
savePreferredLeftPaneWidth={savePreferredLeftPaneWidth}
theme={theme}
viewStory={viewStory}
@ -143,6 +149,7 @@ export function StoriesTab({
requiresFullWidth
savePreferredLeftPaneWidth={savePreferredLeftPaneWidth}
otherTabsUnreadStats={otherTabsUnreadStats}
renderToastManager={renderToastManager}
actions={
<>
<StoriesAddStoryButton

View File

@ -4,10 +4,8 @@
import type { KeyboardEvent, MouseEvent, ReactNode } from 'react';
import React, { memo, useEffect } from 'react';
import classNames from 'classnames';
import { createPortal } from 'react-dom';
import { useRestoreFocus } from '../hooks/useRestoreFocus';
import { clearTimeoutIfNecessary } from '../util/clearTimeoutIfNecessary';
import * as log from '../logging/log';
export type PropsType = {
autoDismissDisabled?: boolean;
@ -33,51 +31,10 @@ export const Toast = memo(function ToastInner({
timeout = 8000,
toastAction,
}: PropsType): JSX.Element | null {
const [root, setRoot] = React.useState<HTMLElement | null>(null);
const [focusRef] = useRestoreFocus();
const [align, setAlign] = React.useState<'left' | 'center'>('left');
useEffect(() => {
function updateAlign() {
const leftPane = document.querySelector('.module-left-pane');
const composer = document.querySelector(
'.ConversationView__composition-area'
);
if (
leftPane != null &&
composer != null &&
leftPane.classList.contains('module-left-pane--width-narrow')
) {
setAlign('center');
return;
}
setAlign('left');
}
updateAlign();
if (window.reduxStore == null) {
log.warn('Toast: No redux store');
return;
}
return window.reduxStore.subscribe(updateAlign);
}, []);
useEffect(() => {
const div = document.createElement('div');
document.body.appendChild(div);
setRoot(div);
return () => {
document.body.removeChild(div);
setRoot(null);
};
}, []);
useEffect(() => {
if (!root || autoDismissDisabled) {
if (autoDismissDisabled) {
return;
}
@ -86,56 +43,53 @@ export const Toast = memo(function ToastInner({
return () => {
clearTimeoutIfNecessary(timeoutId);
};
}, [autoDismissDisabled, onClose, root, timeout]);
}, [autoDismissDisabled, onClose, timeout]);
return root
? createPortal(
return (
<div
aria-live="assertive"
className={classNames('Toast', className)}
onClick={() => {
if (!disableCloseOnClick) {
onClose();
}
}}
onKeyDown={(ev: KeyboardEvent<HTMLDivElement>) => {
if (ev.key === 'Enter' || ev.key === ' ') {
if (!disableCloseOnClick) {
onClose();
}
}
}}
role="button"
tabIndex={0}
style={style}
>
<div className="Toast__content">{children}</div>
{toastAction && (
<div
aria-live="assertive"
className={classNames('Toast', `Toast--align-${align}`, className)}
onClick={() => {
if (!disableCloseOnClick) {
onClose();
}
className="Toast__button"
onClick={(ev: MouseEvent<HTMLDivElement>) => {
ev.stopPropagation();
ev.preventDefault();
toastAction.onClick();
onClose();
}}
onKeyDown={(ev: KeyboardEvent<HTMLDivElement>) => {
if (ev.key === 'Enter' || ev.key === ' ') {
if (!disableCloseOnClick) {
onClose();
}
ev.stopPropagation();
ev.preventDefault();
toastAction.onClick();
onClose();
}
}}
ref={focusRef}
role="button"
tabIndex={0}
style={style}
>
<div className="Toast__content">{children}</div>
{toastAction && (
<div
className="Toast__button"
onClick={(ev: MouseEvent<HTMLDivElement>) => {
ev.stopPropagation();
ev.preventDefault();
toastAction.onClick();
onClose();
}}
onKeyDown={(ev: KeyboardEvent<HTMLDivElement>) => {
if (ev.key === 'Enter' || ev.key === ' ') {
ev.stopPropagation();
ev.preventDefault();
toastAction.onClick();
onClose();
}
}}
ref={focusRef}
role="button"
tabIndex={0}
>
{toastAction.label}
</div>
)}
</div>,
root
)
: null;
{toastAction.label}
</div>
)}
</div>
);
});

View File

@ -1,26 +0,0 @@
// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React from 'react';
import { action } from '@storybook/addon-actions';
import type { Meta } from '@storybook/react';
import type { PropsType } from './ToastAlreadyRequestedToJoin';
import { ToastAlreadyRequestedToJoin } from './ToastAlreadyRequestedToJoin';
import { setupI18n } from '../util/setupI18n';
import enMessages from '../../_locales/en/messages.json';
const i18n = setupI18n('en', enMessages);
const defaultProps = {
i18n,
onClose: action('onClose'),
};
export default {
title: 'Components/ToastAlreadyRequestedToJoin',
} satisfies Meta<PropsType>;
export const _ToastAlreadyRequestedToJoin = (): JSX.Element => (
<ToastAlreadyRequestedToJoin {...defaultProps} />
);

View File

@ -1,22 +0,0 @@
// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React from 'react';
import type { LocalizerType } from '../types/Util';
import { Toast } from './Toast';
export type PropsType = {
i18n: LocalizerType;
onClose: () => unknown;
};
export function ToastAlreadyRequestedToJoin({
i18n,
onClose,
}: PropsType): JSX.Element {
return (
<Toast onClose={onClose}>
{i18n('icu:GroupV2--join--already-awaiting-approval')}
</Toast>
);
}

View File

@ -1,25 +0,0 @@
// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React from 'react';
import { action } from '@storybook/addon-actions';
import type { Meta } from '@storybook/react';
import type { PropsType } from './ToastCaptchaFailed';
import { ToastCaptchaFailed } from './ToastCaptchaFailed';
import { setupI18n } from '../util/setupI18n';
import enMessages from '../../_locales/en/messages.json';
const i18n = setupI18n('en', enMessages);
const defaultProps = {
i18n,
onClose: action('onClose'),
};
export default {
title: 'Components/ToastCaptchaFailed',
} satisfies Meta<PropsType>;
export const _ToastCaptchaFailed = (): JSX.Element => (
<ToastCaptchaFailed {...defaultProps} />
);

View File

@ -1,15 +0,0 @@
// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React from 'react';
import type { LocalizerType } from '../types/Util';
import { Toast } from './Toast';
export type PropsType = {
i18n: LocalizerType;
onClose: () => unknown;
};
export function ToastCaptchaFailed({ i18n, onClose }: PropsType): JSX.Element {
return <Toast onClose={onClose}>{i18n('icu:verificationFailed')}</Toast>;
}

View File

@ -1,25 +0,0 @@
// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React from 'react';
import { action } from '@storybook/addon-actions';
import type { Meta } from '@storybook/react';
import type { PropsType } from './ToastCaptchaSolved';
import { ToastCaptchaSolved } from './ToastCaptchaSolved';
import { setupI18n } from '../util/setupI18n';
import enMessages from '../../_locales/en/messages.json';
const i18n = setupI18n('en', enMessages);
const defaultProps = {
i18n,
onClose: action('onClose'),
};
export default {
title: 'Components/ToastCaptchaSolved',
} satisfies Meta<PropsType>;
export const _ToastCaptchaSolved = (): JSX.Element => (
<ToastCaptchaSolved {...defaultProps} />
);

View File

@ -1,15 +0,0 @@
// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React from 'react';
import type { LocalizerType } from '../types/Util';
import { Toast } from './Toast';
export type PropsType = {
i18n: LocalizerType;
onClose: () => unknown;
};
export function ToastCaptchaSolved({ i18n, onClose }: PropsType): JSX.Element {
return <Toast onClose={onClose}>{i18n('icu:verificationComplete')}</Toast>;
}

View File

@ -1,25 +0,0 @@
// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React from 'react';
import { action } from '@storybook/addon-actions';
import type { Meta } from '@storybook/react';
import type { PropsType } from './ToastDebugLogError';
import { ToastDebugLogError } from './ToastDebugLogError';
import { setupI18n } from '../util/setupI18n';
import enMessages from '../../_locales/en/messages.json';
const i18n = setupI18n('en', enMessages);
const defaultProps = {
i18n,
onClose: action('onClose'),
};
export default {
title: 'Components/ToastDebugLogError',
} satisfies Meta<PropsType>;
export const _ToastDebugLogError = (): JSX.Element => (
<ToastDebugLogError {...defaultProps} />
);

View File

@ -1,15 +0,0 @@
// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React from 'react';
import type { LocalizerType } from '../types/Util';
import { Toast } from './Toast';
export type PropsType = {
i18n: LocalizerType;
onClose: () => unknown;
};
export function ToastDebugLogError({ i18n, onClose }: PropsType): JSX.Element {
return <Toast onClose={onClose}>{i18n('icu:debugLogError')}</Toast>;
}

View File

@ -1,22 +0,0 @@
// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React from 'react';
import type { LocalizerType } from '../types/Util';
import { Toast } from './Toast';
type PropsType = {
i18n: LocalizerType;
onClose: () => unknown;
};
export function ToastFailedToFetchPhoneNumber({
i18n,
onClose,
}: PropsType): JSX.Element {
return (
<Toast onClose={onClose} style={{ maxWidth: '280px' }}>
{i18n('icu:Toast--failed-to-fetch-phone-number')}
</Toast>
);
}

View File

@ -1,22 +0,0 @@
// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React from 'react';
import type { LocalizerType } from '../types/Util';
import { Toast } from './Toast';
type PropsType = {
i18n: LocalizerType;
onClose: () => unknown;
};
export function ToastFailedToFetchUsername({
i18n,
onClose,
}: PropsType): JSX.Element {
return (
<Toast onClose={onClose} style={{ maxWidth: '280px' }}>
{i18n('icu:Toast--failed-to-fetch-username')}
</Toast>
);
}

View File

@ -1,25 +0,0 @@
// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React from 'react';
import { action } from '@storybook/addon-actions';
import type { Meta } from '@storybook/react';
import type { PropsType } from './ToastFileSize';
import { ToastFileSize } from './ToastFileSize';
import { setupI18n } from '../util/setupI18n';
import enMessages from '../../_locales/en/messages.json';
const i18n = setupI18n('en', enMessages);
const defaultProps = {
i18n,
onClose: action('onClose'),
};
export default {
title: 'Components/ToastFileSize',
} satisfies Meta<PropsType>;
export const _ToastFileSize = (): JSX.Element => (
<ToastFileSize {...defaultProps} limit={100} units="MB" />
);

View File

@ -1,29 +0,0 @@
// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React from 'react';
import type { LocalizerType } from '../types/Util';
import { Toast } from './Toast';
export type ToastPropsType = {
limit: number;
units: string;
};
export type PropsType = {
i18n: LocalizerType;
onClose: () => unknown;
} & ToastPropsType;
export function ToastFileSize({
i18n,
limit,
onClose,
units,
}: PropsType): JSX.Element {
return (
<Toast onClose={onClose}>
{i18n('icu:fileSizeWarning', { limit, units })}
</Toast>
);
}

View File

@ -1,25 +0,0 @@
// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React from 'react';
import { action } from '@storybook/addon-actions';
import type { Meta } from '@storybook/react';
import type { PropsType } from './ToastGroupLinkCopied';
import { ToastGroupLinkCopied } from './ToastGroupLinkCopied';
import { setupI18n } from '../util/setupI18n';
import enMessages from '../../_locales/en/messages.json';
const i18n = setupI18n('en', enMessages);
const defaultProps = {
i18n,
onClose: action('onClose'),
};
export default {
title: 'Components/ToastGroupLinkCopied',
} satisfies Meta<PropsType>;
export const _ToastGroupLinkCopied = (): JSX.Element => (
<ToastGroupLinkCopied {...defaultProps} />
);

View File

@ -1,22 +0,0 @@
// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React from 'react';
import type { LocalizerType } from '../types/Util';
import { Toast } from './Toast';
export type PropsType = {
i18n: LocalizerType;
onClose: () => unknown;
};
export function ToastGroupLinkCopied({
i18n,
onClose,
}: PropsType): JSX.Element {
return (
<Toast onClose={onClose}>
{i18n('icu:GroupLinkManagement--clipboard')}
</Toast>
);
}

View File

@ -1,45 +0,0 @@
// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React from 'react';
import { action } from '@storybook/addon-actions';
import type { Meta } from '@storybook/react';
import type { PropsType } from './ToastInternalError';
import {
ToastInternalError,
ToastInternalErrorKind,
} from './ToastInternalError';
import { setupI18n } from '../util/setupI18n';
import enMessages from '../../_locales/en/messages.json';
const i18n = setupI18n('en', enMessages);
const defaultProps = {
i18n,
onClose: action('onClose'),
onShowDebugLog: action('onShowDebugLog'),
};
export default {
title: 'Components/ToastInternalError',
} satisfies Meta<PropsType>;
export function ToastDecryptionError(): JSX.Element {
return (
<ToastInternalError
kind={ToastInternalErrorKind.DecryptionError}
deviceId={3}
name="Someone Somewhere"
{...defaultProps}
/>
);
}
export function ToastCDSMirroringError(): JSX.Element {
return (
<ToastInternalError
kind={ToastInternalErrorKind.CDSMirroringError}
{...defaultProps}
/>
);
}

View File

@ -1,63 +0,0 @@
// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React from 'react';
import type { LocalizerType } from '../types/Util';
import { missingCaseError } from '../util/missingCaseError';
import { Toast } from './Toast';
export enum ToastInternalErrorKind {
DecryptionError = 'DecryptionError',
CDSMirroringError = 'CDSMirroringError',
}
export type ToastPropsType = {
onShowDebugLog: () => unknown;
} & (
| {
kind: ToastInternalErrorKind.DecryptionError;
deviceId: number;
name: string;
}
| {
kind: ToastInternalErrorKind.CDSMirroringError;
}
);
export type PropsType = {
i18n: LocalizerType;
onClose: () => unknown;
} & ToastPropsType;
export function ToastInternalError(props: PropsType): JSX.Element {
const { kind, i18n, onClose, onShowDebugLog } = props;
let body: string;
if (kind === ToastInternalErrorKind.DecryptionError) {
const { deviceId, name } = props;
body = i18n('icu:decryptionErrorToast', {
name,
deviceId,
});
} else if (kind === ToastInternalErrorKind.CDSMirroringError) {
body = i18n('icu:cdsMirroringErrorToast');
} else {
throw missingCaseError(kind);
}
return (
<Toast
autoDismissDisabled
className="internal-error-toast"
onClose={onClose}
style={{ maxWidth: '500px' }}
toastAction={{
label: i18n('icu:decryptionErrorToastAction'),
onClick: onShowDebugLog,
}}
>
{body}
</Toast>
);
}

View File

@ -1,25 +0,0 @@
// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React from 'react';
import { action } from '@storybook/addon-actions';
import type { Meta } from '@storybook/react';
import type { PropsType } from './ToastLinkCopied';
import { ToastLinkCopied } from './ToastLinkCopied';
import { setupI18n } from '../util/setupI18n';
import enMessages from '../../_locales/en/messages.json';
const i18n = setupI18n('en', enMessages);
const defaultProps = {
i18n,
onClose: action('onClose'),
};
export default {
title: 'Components/ToastLinkCopied',
} satisfies Meta<PropsType>;
export const _ToastLinkCopied = (): JSX.Element => (
<ToastLinkCopied {...defaultProps} />
);

View File

@ -1,15 +0,0 @@
// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React from 'react';
import type { LocalizerType } from '../types/Util';
import { Toast } from './Toast';
export type PropsType = {
i18n: LocalizerType;
onClose: () => unknown;
};
export function ToastLinkCopied({ i18n, onClose }: PropsType): JSX.Element {
return <Toast onClose={onClose}>{i18n('icu:debugLogLinkCopied')}</Toast>;
}

View File

@ -1,25 +0,0 @@
// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React from 'react';
import { action } from '@storybook/addon-actions';
import type { Meta } from '@storybook/react';
import type { PropsType } from './ToastLoadingFullLogs';
import { ToastLoadingFullLogs } from './ToastLoadingFullLogs';
import { setupI18n } from '../util/setupI18n';
import enMessages from '../../_locales/en/messages.json';
const i18n = setupI18n('en', enMessages);
const defaultProps = {
i18n,
onClose: action('onClose'),
};
export default {
title: 'Components/ToastLoadingFullLogs',
} satisfies Meta<PropsType>;
export const _ToastLoadingFullLogs = (): JSX.Element => (
<ToastLoadingFullLogs {...defaultProps} />
);

View File

@ -1,18 +0,0 @@
// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React from 'react';
import type { LocalizerType } from '../types/Util';
import { Toast } from './Toast';
export type PropsType = {
i18n: LocalizerType;
onClose: () => unknown;
};
export function ToastLoadingFullLogs({
i18n,
onClose,
}: PropsType): JSX.Element {
return <Toast onClose={onClose}>{i18n('icu:loading')}</Toast>;
}

View File

@ -9,6 +9,8 @@ import enMessages from '../../_locales/en/messages.json';
import { ToastManager } from './ToastManager';
import type { AnyToast } from '../types/Toast';
import { ToastType } from '../types/Toast';
import type { AnyActionableMegaphone } from '../types/Megaphone';
import { MegaphoneType } from '../types/Megaphone';
import { setupI18n } from '../util/setupI18n';
import { missingCaseError } from '../util/missingCaseError';
import type { PropsType } from './ToastManager';
@ -41,6 +43,10 @@ function getToast(toastType: ToastType): AnyToast {
return { toastType: ToastType.CannotOpenGiftBadgeOutgoing };
case ToastType.CannotStartGroupCall:
return { toastType: ToastType.CannotStartGroupCall };
case ToastType.CaptchaFailed:
return { toastType: ToastType.CaptchaFailed };
case ToastType.CaptchaSolved:
return { toastType: ToastType.CaptchaSolved };
case ToastType.ConversationArchived:
return {
toastType: ToastType.ConversationArchived,
@ -61,6 +67,16 @@ function getToast(toastType: ToastType): AnyToast {
return { toastType: ToastType.CopiedUsernameLink };
case ToastType.DangerousFileType:
return { toastType: ToastType.DangerousFileType };
case ToastType.DebugLogError:
return { toastType: ToastType.DebugLogError };
case ToastType.DecryptionError:
return {
toastType: ToastType.DecryptionError,
parameters: {
deviceId: 2,
name: 'Alice',
},
};
case ToastType.DeleteForEveryoneFailed:
return { toastType: ToastType.DeleteForEveryoneFailed };
case ToastType.Error:
@ -69,6 +85,10 @@ function getToast(toastType: ToastType): AnyToast {
return { toastType: ToastType.Expired };
case ToastType.FailedToDeleteUsername:
return { toastType: ToastType.FailedToDeleteUsername };
case ToastType.FailedToFetchPhoneNumber:
return { toastType: ToastType.FailedToFetchPhoneNumber };
case ToastType.FailedToFetchUsername:
return { toastType: ToastType.FailedToFetchUsername };
case ToastType.FileSaved:
return {
toastType: ToastType.FileSaved,
@ -79,10 +99,16 @@ function getToast(toastType: ToastType): AnyToast {
toastType: ToastType.FileSize,
parameters: { limit: 100, units: 'MB' },
};
case ToastType.GroupLinkCopied:
return { toastType: ToastType.GroupLinkCopied };
case ToastType.InvalidConversation:
return { toastType: ToastType.InvalidConversation };
case ToastType.LeftGroup:
return { toastType: ToastType.LeftGroup };
case ToastType.LinkCopied:
return { toastType: ToastType.LinkCopied };
case ToastType.LoadingFullLogs:
return { toastType: ToastType.LoadingFullLogs };
case ToastType.MaxAttachments:
return { toastType: ToastType.MaxAttachments };
case ToastType.MessageBodyTooLong:
@ -95,6 +121,8 @@ function getToast(toastType: ToastType): AnyToast {
return { toastType: ToastType.ReactionFailed };
case ToastType.ReportedSpamAndBlocked:
return { toastType: ToastType.ReportedSpamAndBlocked };
case ToastType.StickerPackInstallFailed:
return { toastType: ToastType.StickerPackInstallFailed };
case ToastType.StoryMuted:
return { toastType: ToastType.StoryMuted };
case ToastType.StoryReact:
@ -130,6 +158,10 @@ function getToast(toastType: ToastType): AnyToast {
group: 'Hike Group 🏔',
},
};
case ToastType.VoiceNoteLimit:
return { toastType: ToastType.VoiceNoteLimit };
case ToastType.VoiceNoteMustBeTheOnlyAttachment:
return { toastType: ToastType.VoiceNoteMustBeTheOnlyAttachment };
case ToastType.WhoCanFindMeReadOnly:
return { toastType: ToastType.WhoCanFindMeReadOnly };
default:
@ -137,8 +169,22 @@ function getToast(toastType: ToastType): AnyToast {
}
}
type Args = Omit<PropsType, 'toast'> & {
function getMegaphone(megaphoneType: MegaphoneType): AnyActionableMegaphone {
switch (megaphoneType) {
case MegaphoneType.UsernameOnboarding:
return {
type: megaphoneType,
onLearnMore: action('onLearnMore'),
onDismiss: action('onDismiss'),
};
default:
throw missingCaseError(megaphoneType);
}
}
type Args = Omit<PropsType, 'toast' | 'megaphone'> & {
toastType: ToastType;
megaphoneType: MegaphoneType;
};
export default {
@ -149,24 +195,34 @@ export default {
options: ToastType,
control: { type: 'select' },
},
megaphoneType: {
options: MegaphoneType,
control: { type: 'select' },
},
},
args: {
hideToast: action('hideToast'),
openFileInFolder: action('openFileInFolder'),
onShowDebugLog: action('onShowDebugLog'),
onUndoArchive: action('onUndoArchive'),
i18n,
toastType: ToastType.AddingUserToGroup,
megaphoneType: MegaphoneType.UsernameOnboarding,
OS: 'macOS',
},
} satisfies Meta<Args>;
// eslint-disable-next-line react/function-component-definition
const Template: StoryFn<Args> = args => {
const { toastType, ...rest } = args;
const { toastType, megaphoneType, ...rest } = args;
return (
<>
<p>Select a toast type in controls</p>
<ToastManager toast={getToast(toastType)} {...rest} />
<ToastManager
toast={getToast(toastType)}
megaphone={getMegaphone(megaphoneType)}
{...rest}
/>
</>
);
};

View File

@ -1,29 +1,43 @@
// Copyright 2022 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import classNames from 'classnames';
import React from 'react';
import { createPortal } from 'react-dom';
import type { LocalizerType } from '../types/Util';
import { SECOND } from '../util/durations';
import { Toast } from './Toast';
import { WidthBreakpoint } from './_util';
import { UsernameMegaphone } from './UsernameMegaphone';
import { assertDev } from '../util/assert';
import { missingCaseError } from '../util/missingCaseError';
import type { AnyToast } from '../types/Toast';
import { ToastType } from '../types/Toast';
import type { AnyActionableMegaphone } from '../types/Megaphone';
import { MegaphoneType } from '../types/Megaphone';
export type PropsType = {
hideToast: () => unknown;
i18n: LocalizerType;
openFileInFolder: (target: string) => unknown;
OS: string;
onShowDebugLog: () => unknown;
onUndoArchive: (conversaetionId: string) => unknown;
toast?: AnyToast;
megaphone?: AnyActionableMegaphone;
centerToast?: boolean;
containerWidthBreakpoint: WidthBreakpoint;
isCompositionAreaVisible?: boolean;
};
const SHORT_TIMEOUT = 3 * SECOND;
export function ToastManager({
export function renderToast({
hideToast,
i18n,
openFileInFolder,
onShowDebugLog,
onUndoArchive,
OS,
toast,
@ -116,6 +130,16 @@ export function ToastManager({
);
}
if (toastType === ToastType.CaptchaFailed) {
return <Toast onClose={hideToast}>{i18n('icu:verificationFailed')}</Toast>;
}
if (toastType === ToastType.CaptchaSolved) {
return (
<Toast onClose={hideToast}>{i18n('icu:verificationComplete')}</Toast>
);
}
if (toastType === ToastType.CannotStartGroupCall) {
return (
<Toast onClose={hideToast}>
@ -184,6 +208,10 @@ export function ToastManager({
return <Toast onClose={hideToast}>{i18n('icu:dangerousFileType')}</Toast>;
}
if (toastType === ToastType.DebugLogError) {
return <Toast onClose={hideToast}>{i18n('icu:debugLogError')}</Toast>;
}
if (toastType === ToastType.DeleteForEveryoneFailed) {
return (
<Toast onClose={hideToast}>{i18n('icu:deleteForEveryoneFailed')}</Toast>
@ -217,6 +245,22 @@ export function ToastManager({
);
}
if (toastType === ToastType.FailedToFetchPhoneNumber) {
return (
<Toast onClose={hideToast} style={{ maxWidth: '280px' }}>
{i18n('icu:Toast--failed-to-fetch-phone-number')}
</Toast>
);
}
if (toastType === ToastType.FailedToFetchUsername) {
return (
<Toast onClose={hideToast} style={{ maxWidth: '280px' }}>
{i18n('icu:Toast--failed-to-fetch-username')}
</Toast>
);
}
if (toastType === ToastType.FileSaved) {
return (
<Toast
@ -244,6 +288,41 @@ export function ToastManager({
);
}
if (toastType === ToastType.GroupLinkCopied) {
return (
<Toast onClose={hideToast}>
{i18n('icu:GroupLinkManagement--clipboard')}
</Toast>
);
}
if (toastType === ToastType.DecryptionError) {
assertDev(
toast.toastType === ToastType.DecryptionError,
'Pacify typescript'
);
const { parameters } = toast;
const { deviceId, name } = parameters;
return (
<Toast
autoDismissDisabled
className="internal-error-toast"
onClose={hideToast}
style={{ maxWidth: '500px' }}
toastAction={{
label: i18n('icu:decryptionErrorToastAction'),
onClick: onShowDebugLog,
}}
>
{i18n('icu:decryptionErrorToast', {
name,
deviceId,
})}
</Toast>
);
}
if (toastType === ToastType.InvalidConversation) {
return <Toast onClose={hideToast}>{i18n('icu:invalidConversation')}</Toast>;
}
@ -252,6 +331,14 @@ export function ToastManager({
return <Toast onClose={hideToast}>{i18n('icu:youLeftTheGroup')}</Toast>;
}
if (toastType === ToastType.LinkCopied) {
return <Toast onClose={hideToast}>{i18n('icu:debugLogLinkCopied')}</Toast>;
}
if (toastType === ToastType.LoadingFullLogs) {
return <Toast onClose={hideToast}>{i18n('icu:loading')}</Toast>;
}
if (toastType === ToastType.MaxAttachments) {
return <Toast onClose={hideToast}>{i18n('icu:maximumAttachments')}</Toast>;
}
@ -284,6 +371,14 @@ export function ToastManager({
);
}
if (toastType === ToastType.StickerPackInstallFailed) {
return (
<Toast onClose={hideToast}>
{i18n('icu:stickers--toast--InstallFailed')}
</Toast>
);
}
if (toastType === ToastType.StoryMuted) {
return (
<Toast onClose={hideToast} timeout={SHORT_TIMEOUT}>
@ -392,6 +487,18 @@ export function ToastManager({
);
}
if (toastType === ToastType.VoiceNoteLimit) {
return <Toast onClose={hideToast}>{i18n('icu:voiceNoteLimit')}</Toast>;
}
if (toastType === ToastType.VoiceNoteMustBeTheOnlyAttachment) {
return (
<Toast onClose={hideToast}>
{i18n('icu:voiceNoteMustBeOnlyAttachment')}
</Toast>
);
}
if (toastType === ToastType.WhoCanFindMeReadOnly) {
return (
<Toast onClose={hideToast}>{i18n('icu:WhoCanFindMeReadOnlyToast')}</Toast>
@ -400,3 +507,43 @@ export function ToastManager({
throw missingCaseError(toastType);
}
export function renderMegaphone({
i18n,
megaphone,
}: PropsType): JSX.Element | null {
if (!megaphone) {
return null;
}
if (megaphone.type === MegaphoneType.UsernameOnboarding) {
return <UsernameMegaphone i18n={i18n} {...megaphone} />;
}
throw missingCaseError(megaphone.type);
}
export function ToastManager(props: PropsType): JSX.Element {
const { centerToast, containerWidthBreakpoint, isCompositionAreaVisible } =
props;
const toast = renderToast(props);
return (
<div
className={classNames('ToastManager', {
'ToastManager--narrow-sidebar':
containerWidthBreakpoint === WidthBreakpoint.Narrow,
'ToastManager--composition-area-visible': isCompositionAreaVisible,
})}
>
{centerToast
? createPortal(
<div className="ToastManager__root">{toast}</div>,
document.body
)
: toast}
{renderMegaphone(props)}
</div>
);
}

View File

@ -1,25 +0,0 @@
// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React from 'react';
import { action } from '@storybook/addon-actions';
import type { Meta } from '@storybook/react';
import type { PropsType } from './ToastStickerPackInstallFailed';
import { ToastStickerPackInstallFailed } from './ToastStickerPackInstallFailed';
import { setupI18n } from '../util/setupI18n';
import enMessages from '../../_locales/en/messages.json';
const i18n = setupI18n('en', enMessages);
const defaultProps = {
i18n,
onClose: action('onClose'),
};
export default {
title: 'Components/ToastStickerPackInstallFailed',
} satisfies Meta<PropsType>;
export const _ToastStickerPackInstallFailed = (): JSX.Element => (
<ToastStickerPackInstallFailed {...defaultProps} />
);

View File

@ -1,22 +0,0 @@
// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React from 'react';
import type { LocalizerType } from '../types/Util';
import { Toast } from './Toast';
export type PropsType = {
i18n: LocalizerType;
onClose: () => unknown;
};
export function ToastStickerPackInstallFailed({
i18n,
onClose,
}: PropsType): JSX.Element {
return (
<Toast onClose={onClose}>
{i18n('icu:stickers--toast--InstallFailed')}
</Toast>
);
}

View File

@ -1,15 +0,0 @@
// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React from 'react';
import type { LocalizerType } from '../types/Util';
import { Toast } from './Toast';
type PropsType = {
i18n: LocalizerType;
onClose: () => unknown;
};
export function ToastVoiceNoteLimit({ i18n, onClose }: PropsType): JSX.Element {
return <Toast onClose={onClose}>{i18n('icu:voiceNoteError')}</Toast>;
}

View File

@ -1,25 +0,0 @@
// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React from 'react';
import { action } from '@storybook/addon-actions';
import type { Meta } from '@storybook/react';
import type { PropsType } from './ToastVoiceNoteLimit';
import { ToastVoiceNoteLimit } from './ToastVoiceNoteLimit';
import { setupI18n } from '../util/setupI18n';
import enMessages from '../../_locales/en/messages.json';
const i18n = setupI18n('en', enMessages);
const defaultProps = {
i18n,
onClose: action('onClose'),
};
export default {
title: 'Components/ToastVoiceNoteLimit',
} satisfies Meta<PropsType>;
export const _ToastVoiceNoteLimit = (): JSX.Element => (
<ToastVoiceNoteLimit {...defaultProps} />
);

View File

@ -1,15 +0,0 @@
// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React from 'react';
import type { LocalizerType } from '../types/Util';
import { Toast } from './Toast';
export type PropsType = {
i18n: LocalizerType;
onClose: () => unknown;
};
export function ToastVoiceNoteLimit({ i18n, onClose }: PropsType): JSX.Element {
return <Toast onClose={onClose}>{i18n('icu:voiceNoteLimit')}</Toast>;
}

View File

@ -1,25 +0,0 @@
// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React from 'react';
import { action } from '@storybook/addon-actions';
import type { Meta } from '@storybook/react';
import type { PropsType } from './ToastVoiceNoteMustBeOnlyAttachment';
import { ToastVoiceNoteMustBeOnlyAttachment } from './ToastVoiceNoteMustBeOnlyAttachment';
import { setupI18n } from '../util/setupI18n';
import enMessages from '../../_locales/en/messages.json';
const i18n = setupI18n('en', enMessages);
const defaultProps = {
i18n,
onClose: action('onClose'),
};
export default {
title: 'Components/ToastVoiceNoteMustBeOnlyAttachment',
} satisfies Meta<PropsType>;
export const _ToastVoiceNoteMustBeOnlyAttachment = (): JSX.Element => (
<ToastVoiceNoteMustBeOnlyAttachment {...defaultProps} />
);

View File

@ -1,20 +0,0 @@
// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React from 'react';
import type { LocalizerType } from '../types/Util';
import { Toast } from './Toast';
export type PropsType = {
i18n: LocalizerType;
onClose: () => unknown;
};
export function ToastVoiceNoteMustBeOnlyAttachment({
i18n,
onClose,
}: PropsType): JSX.Element {
return (
<Toast onClose={onClose}>{i18n('icu:voiceNoteMustBeOnlyAttachment')}</Toast>
);
}

View File

@ -0,0 +1,27 @@
// Copyright 2024 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React from 'react';
import { action } from '@storybook/addon-actions';
import type { PropsType } from './UsernameMegaphone';
import { UsernameMegaphone } from './UsernameMegaphone';
import { type ComponentMeta } from '../storybook/types';
import { setupI18n } from '../util/setupI18n';
import enMessages from '../../_locales/en/messages.json';
const i18n = setupI18n('en', enMessages);
export default {
title: 'Components/UsernameMegaphone',
component: UsernameMegaphone,
argTypes: {},
args: {
i18n,
onLearnMore: action('onLearnMore'),
onDismiss: action('onDismiss'),
},
} satisfies ComponentMeta<PropsType>;
export function Defaults(args: PropsType): JSX.Element {
return <UsernameMegaphone {...args} />;
}

View File

@ -0,0 +1,50 @@
// Copyright 2023 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React from 'react';
import type { LocalizerType } from '../types/Util';
import type { UsernameOnboardingActionableMegaphoneType } from '../types/Megaphone';
import { Button, ButtonSize, ButtonVariant } from './Button';
export type PropsType = {
i18n: LocalizerType;
} & Omit<UsernameOnboardingActionableMegaphoneType, 'type'>;
export function UsernameMegaphone({
i18n,
onLearnMore,
onDismiss,
}: PropsType): JSX.Element {
return (
<div className="UsernameMegaphone">
<div className="UsernameMegaphone__row">
<i className="UsernameMegaphone__row__icon" />
<div className="UsernameMegaphone__row__text">
<h2>{i18n('icu:UsernameMegaphone__title')}</h2>
<p>{i18n('icu:UsernameMegaphone__body')}</p>
</div>
</div>
<div className="UsernameMegaphone__buttons">
<Button
className="UsernameMegaphone__buttons__button"
variant={ButtonVariant.SecondaryAffirmative}
size={ButtonSize.Small}
onClick={onDismiss}
>
{i18n('icu:UsernameMegaphone__dismiss')}
</Button>
<Button
className="UsernameMegaphone__buttons__button"
variant={ButtonVariant.SecondaryAffirmative}
size={ButtonSize.Small}
onClick={onLearnMore}
>
{i18n('icu:UsernameMegaphone__learn-more')}
</Button>
</div>
</div>
);
}

View File

@ -8,23 +8,25 @@ import { action } from '@storybook/addon-actions';
import enMessages from '../../_locales/en/messages.json';
import { setupI18n } from '../util/setupI18n';
import type { PropsType } from './UsernameOnboardingModalBody';
import { UsernameOnboardingModalBody } from './UsernameOnboardingModalBody';
import type { PropsType } from './UsernameOnboardingModal';
import { UsernameOnboardingModal } from './UsernameOnboardingModal';
const i18n = setupI18n('en', enMessages);
export default {
component: UsernameOnboardingModalBody,
title: 'Components/UsernameOnboardingModalBody',
component: UsernameOnboardingModal,
title: 'Components/UsernameOnboardingModal',
args: {
i18n,
onNext: action('onNext'),
onSkip: action('onSkip'),
onClose: action('onClose'),
},
} satisfies Meta<PropsType>;
// eslint-disable-next-line react/function-component-definition
const Template: StoryFn<PropsType> = args => {
return <UsernameOnboardingModalBody {...args} />;
return <UsernameOnboardingModal {...args} />;
};
export const Normal = Template.bind({});

View File

@ -0,0 +1,80 @@
// Copyright 2023 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React from 'react';
import type { LocalizerType } from '../types/Util';
import { Button, ButtonVariant } from './Button';
import { Modal } from './Modal';
export type PropsType = Readonly<{
i18n: LocalizerType;
onNext: () => void;
onSkip: () => void;
onClose: () => void;
}>;
export function UsernameOnboardingModal({
i18n,
onNext,
onSkip,
onClose,
}: PropsType): JSX.Element {
return (
<Modal
modalName="UsernameOnboardingModal"
hasXButton
i18n={i18n}
onClose={onClose}
>
<div className="UsernameOnboardingModal">
<div className="UsernameOnboardingModal__title">
{i18n('icu:UsernameOnboardingModalBody__title')}
</div>
<div className="UsernameOnboardingModal__row">
<div className="UsernameOnboardingModal__row__icon UsernameOnboardingModal__row__icon--number" />
<div className="UsernameOnboardingModal__row__body">
<h2>
{i18n('icu:UsernameOnboardingModalBody__row__number__title')}
</h2>
{i18n('icu:UsernameOnboardingModalBody__row__number__body')}
</div>
</div>
<div className="UsernameOnboardingModal__row">
<div className="UsernameOnboardingModal__row__icon UsernameOnboardingModal__row__icon--username" />
<div className="UsernameOnboardingModal__row__body">
<h2>
{i18n('icu:UsernameOnboardingModalBody__row__username__title')}
</h2>
{i18n('icu:UsernameOnboardingModalBody__row__username__body')}
</div>
</div>
<div className="UsernameOnboardingModal__row">
<div className="UsernameOnboardingModal__row__icon UsernameOnboardingModal__row__icon--qr" />
<div className="UsernameOnboardingModal__row__body">
<h2>{i18n('icu:UsernameOnboardingModalBody__row__qr__title')}</h2>
{i18n('icu:UsernameOnboardingModalBody__row__qr__body')}
</div>
</div>
<Button className="UsernameOnboardingModal__submit" onClick={onNext}>
{i18n('icu:UsernameOnboardingModalBody__continue')}
</Button>
<Button
className="UsernameOnboardingModal__skip"
variant={ButtonVariant.SecondaryAffirmative}
onClick={onSkip}
>
{i18n('icu:UsernameOnboardingModalBody__skip')}
</Button>
</div>
</Modal>
);
}

View File

@ -1,70 +0,0 @@
// Copyright 2023 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React from 'react';
import type { LocalizerType } from '../types/Util';
import { Button } from './Button';
export type PropsType = Readonly<{
i18n: LocalizerType;
onNext: () => void;
}>;
const CLASS = 'UsernameOnboardingModalBody';
const SUPPORT_URL = 'https://support.signal.org/hc/articles/5389476324250';
export function UsernameOnboardingModalBody({
i18n,
onNext,
}: PropsType): JSX.Element {
return (
<div className={CLASS}>
<div className={`${CLASS}__large-at`} />
<div className={`${CLASS}__title`}>
{i18n('icu:UsernameOnboardingModalBody__title')}
</div>
<div className={`${CLASS}__row`}>
<div className={`${CLASS}__row__icon ${CLASS}__row__icon--number`} />
<div className={`${CLASS}__row__body`}>
{i18n('icu:UsernameOnboardingModalBody__row__number')}
</div>
</div>
<div className={`${CLASS}__row`}>
<div className={`${CLASS}__row__icon ${CLASS}__row__icon--link`} />
<div className={`${CLASS}__row__body`}>
{i18n('icu:UsernameOnboardingModalBody__row__link')}
</div>
</div>
<div className={`${CLASS}__row`}>
<div className={`${CLASS}__row__icon ${CLASS}__row__icon--lock`} />
<div className={`${CLASS}__row__body`}>
{i18n('icu:UsernameOnboardingModalBody__row__lock')}
</div>
</div>
<div className={`${CLASS}__row ${CLASS}__row--center`}>
<a
className={`${CLASS}__learn-more`}
href={SUPPORT_URL}
rel="noreferrer"
target="_blank"
>
{i18n('icu:UsernameOnboardingModalBody__learn-more')}
</a>
</div>
<Button className={`${CLASS}__submit`} onClick={onNext}>
{i18n('icu:UsernameOnboardingModalBody__continue')}
</Button>
</div>
);
}

View File

@ -1,11 +1,12 @@
// Copyright 2016 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React, { useCallback, useState } from 'react';
import React, { useCallback } from 'react';
import type { ShowToastAction } from '../../state/ducks/toast';
import type { AttachmentDraftType } from '../../types/Attachment';
import type { LocalizerType } from '../../types/Util';
import { ToastVoiceNoteMustBeOnlyAttachment } from '../ToastVoiceNoteMustBeOnlyAttachment';
import { ToastType } from '../../types/Toast';
import {
useStartRecordingShortcut,
useKeyboardShortcuts,
@ -16,6 +17,7 @@ export type PropsType = {
draftAttachments: ReadonlyArray<AttachmentDraftType>;
i18n: LocalizerType;
startRecording: (id: string) => unknown;
showToast: ShowToastAction;
};
export function AudioCapture({
@ -23,9 +25,8 @@ export function AudioCapture({
draftAttachments,
i18n,
startRecording,
showToast,
}: PropsType): JSX.Element {
const [showOnlyAttachmentToast, setShowOnlyAttachmentToast] = useState(false);
const recordConversation = useCallback(
() => startRecording(conversationId),
[conversationId, startRecording]
@ -33,40 +34,23 @@ export function AudioCapture({
const startRecordingShortcut = useStartRecordingShortcut(recordConversation);
useKeyboardShortcuts(startRecordingShortcut);
const handleCloseToast = useCallback(() => {
setShowOnlyAttachmentToast(false);
}, []);
const handleClick = useCallback(() => {
if (draftAttachments.length) {
setShowOnlyAttachmentToast(true);
showToast({ toastType: ToastType.VoiceNoteMustBeTheOnlyAttachment });
} else {
startRecording(conversationId);
}
}, [
conversationId,
draftAttachments,
setShowOnlyAttachmentToast,
startRecording,
]);
}, [conversationId, draftAttachments, showToast, startRecording]);
return (
<>
<div className="AudioCapture">
<button
aria-label={i18n('icu:voiceRecording--start')}
className="AudioCapture__microphone"
onClick={handleClick}
title={i18n('icu:voiceRecording--start')}
type="button"
/>
</div>
{showOnlyAttachmentToast && (
<ToastVoiceNoteMustBeOnlyAttachment
i18n={i18n}
onClose={handleCloseToast}
/>
)}
</>
<div className="AudioCapture">
<button
aria-label={i18n('icu:voiceRecording--start')}
className="AudioCapture__microphone"
onClick={handleClick}
title={i18n('icu:voiceRecording--start')}
type="button"
/>
</div>
);
}

View File

@ -4,6 +4,8 @@
import type { ThunkAction } from 'redux-thunk';
import type { ReadonlyDeep } from 'type-fest';
import type { StateType as RootStateType } from '../reducer';
import type { BoundActionCreatorsMapObject } from '../../hooks/useBoundActions';
import { useBoundActions } from '../../hooks/useBoundActions';
import * as log from '../../logging/log';
// State
@ -57,6 +59,9 @@ export const actions = {
openStandalone,
};
export const useAppActions = (): BoundActionCreatorsMapObject<typeof actions> =>
useBoundActions(actions);
function initialLoadComplete(): InitialLoadCompleteActionType {
return {
type: INITIAL_LOAD_COMPLETE,

View File

@ -2,11 +2,14 @@
// SPDX-License-Identifier: AGPL-3.0-only
import type { ReadonlyDeep } from 'type-fest';
import type { ThunkAction } from 'redux-thunk';
import * as log from '../../logging/log';
import { showToast } from '../../util/showToast';
import * as Errors from '../../types/errors';
import { ToastLinkCopied } from '../../components/ToastLinkCopied';
import { ToastDebugLogError } from '../../components/ToastDebugLogError';
import { ToastType } from '../../types/Toast';
import type { StateType as RootStateType } from '../reducer';
import { showToast } from './toast';
import type { ShowToastActionType } from './toast';
import type { PromiseAction } from '../util';
// State
@ -45,12 +48,43 @@ function setCrashReportCount(count: number): SetCrashReportCountActionType {
return { type: SET_COUNT, payload: count };
}
function uploadCrashReports(): PromiseAction<typeof UPLOAD> {
return { type: UPLOAD, payload: window.IPC.crashReports.upload() };
function uploadCrashReports(): ThunkAction<
void,
RootStateType,
unknown,
PromiseAction<typeof UPLOAD> | ShowToastActionType
> {
return dispatch => {
async function run() {
try {
await window.IPC.crashReports.upload();
dispatch(showToast({ toastType: ToastType.LinkCopied }));
} catch (error) {
dispatch(showToast({ toastType: ToastType.DebugLogError }));
throw error;
}
}
dispatch({ type: UPLOAD, payload: run() });
};
}
function eraseCrashReports(): PromiseAction<typeof ERASE> {
return { type: ERASE, payload: window.IPC.crashReports.erase() };
function eraseCrashReports(): ThunkAction<
void,
RootStateType,
unknown,
PromiseAction<typeof ERASE> | ShowToastActionType
> {
return dispatch => {
async function run() {
try {
await window.IPC.crashReports.erase();
} catch (error) {
dispatch(showToast({ toastType: ToastType.DebugLogError }));
throw error;
}
}
dispatch({ type: ERASE, payload: run() });
};
}
// Reducer
@ -87,9 +121,6 @@ export function reducer(
action.type === `${UPLOAD}_FULFILLED` ||
action.type === `${ERASE}_FULFILLED`
) {
if (action.type === `${UPLOAD}_FULFILLED`) {
showToast(ToastLinkCopied);
}
return {
...state,
count: 0,
@ -107,8 +138,6 @@ export function reducer(
`Failed to upload crash report due to error ${Errors.toLogFormat(error)}`
);
showToast(ToastDebugLogError);
return {
...state,
count: 0,

View File

@ -16,10 +16,12 @@ import type {
import type { MessagePropsType } from '../selectors/message';
import type { RecipientsByConversation } from './stories';
import type { SafetyNumberChangeSource } from '../../components/SafetyNumberChangeDialog';
import type { EditState as ProfileEditorEditState } from '../../components/ProfileEditor';
import type { StateType as RootStateType } from '../reducer';
import * as Errors from '../../types/errors';
import * as SingleServePromise from '../../services/singleServePromise';
import * as Stickers from '../../types/Stickers';
import { UsernameOnboardingState } from '../../types/globalModals';
import * as log from '../../logging/log';
import { getMessagePropsSelector } from '../selectors/message';
import type { BoundActionCreatorsMapObject } from '../../hooks/useBoundActions';
@ -96,7 +98,9 @@ export type GlobalModalsStateType = ReadonlyDeep<{
isSignalConnectionsVisible: boolean;
isStoriesSettingsVisible: boolean;
isWhatsNewVisible: boolean;
usernameOnboardingState: UsernameOnboardingState;
profileEditorHasError: boolean;
profileEditorInitialEditState: ProfileEditorEditState | undefined;
safetyNumberChangedBlockingData?: SafetyNumberChangedBlockingDataType;
safetyNumberModalContactId?: string;
sendEditWarningData?: SendEditWarningDataType;
@ -151,6 +155,7 @@ const CONFIRM_AUTH_ART_CREATOR_FULFILLED =
'globalModals/CONFIRM_AUTH_ART_CREATOR_FULFILLED';
const SHOW_EDIT_HISTORY_MODAL = 'globalModals/SHOW_EDIT_HISTORY_MODAL';
const CLOSE_EDIT_HISTORY_MODAL = 'globalModals/CLOSE_EDIT_HISTORY_MODAL';
const TOGGLE_USERNAME_ONBOARDING = 'globalModals/TOGGLE_USERNAME_ONBOARDING';
export type ContactModalStateType = ReadonlyDeep<{
contactId: string;
@ -206,6 +211,9 @@ type ToggleForwardMessagesModalActionType = ReadonlyDeep<{
type ToggleProfileEditorActionType = ReadonlyDeep<{
type: typeof TOGGLE_PROFILE_EDITOR;
payload: {
initialEditState?: ProfileEditorEditState;
};
}>;
export type ToggleProfileEditorErrorActionType = ReadonlyDeep<{
@ -231,6 +239,10 @@ type ToggleConfirmationModalActionType = ReadonlyDeep<{
payload: boolean;
}>;
type ToggleUsernameOnboardingActionType = ReadonlyDeep<{
type: typeof TOGGLE_USERNAME_ONBOARDING;
}>;
type ShowStoriesSettingsActionType = ReadonlyDeep<{
type: typeof SHOW_STORIES_SETTINGS;
}>;
@ -368,6 +380,7 @@ export type GlobalModalsActionType = ReadonlyDeep<
| ToggleProfileEditorErrorActionType
| ToggleSafetyNumberModalActionType
| ToggleSignalConnectionsModalActionType
| ToggleUsernameOnboardingActionType
>;
// Action Creators
@ -406,6 +419,7 @@ export const actions = {
toggleProfileEditorHasError,
toggleSafetyNumberModal,
toggleSignalConnectionsModal,
toggleUsernameOnboarding,
};
export const useGlobalModalActions = (): BoundActionCreatorsMapObject<
@ -585,8 +599,10 @@ function toggleForwardMessagesModal(
};
}
function toggleProfileEditor(): ToggleProfileEditorActionType {
return { type: TOGGLE_PROFILE_EDITOR };
function toggleProfileEditor(
initialEditState?: ProfileEditorEditState
): ToggleProfileEditorActionType {
return { type: TOGGLE_PROFILE_EDITOR, payload: { initialEditState } };
}
function toggleProfileEditorHasError(): ToggleProfileEditorErrorActionType {
@ -626,6 +642,10 @@ function toggleConfirmationModal(
};
}
function toggleUsernameOnboarding(): ToggleUsernameOnboardingActionType {
return { type: TOGGLE_USERNAME_ONBOARDING };
}
function showBlockingSafetyNumberChangeDialog(
untrustedByConversation: RecipientsByConversation,
explodedPromise: ExplodePromiseResultType<boolean>,
@ -861,7 +881,9 @@ export function getEmptyState(): GlobalModalsStateType {
isSignalConnectionsVisible: false,
isStoriesSettingsVisible: false,
isWhatsNewVisible: false,
usernameOnboardingState: UsernameOnboardingState.NeverShown,
profileEditorHasError: false,
profileEditorInitialEditState: undefined,
};
}
@ -873,6 +895,7 @@ export function reducer(
return {
...state,
isProfileEditorVisible: !state.isProfileEditorVisible,
profileEditorInitialEditState: action.payload.initialEditState,
};
}
@ -983,6 +1006,16 @@ export function reducer(
};
}
if (action.type === TOGGLE_USERNAME_ONBOARDING) {
return {
...state,
usernameOnboardingState:
state.usernameOnboardingState === UsernameOnboardingState.Open
? UsernameOnboardingState.Closed
: UsernameOnboardingState.Open,
};
}
if (action.type === SHOW_SEND_ANYWAY_DIALOG) {
const { promiseUuid, source } = action.payload;

View File

@ -27,20 +27,7 @@ export type ItemsStateType = ReadonlyDeep<
[key: string]: unknown;
remoteConfig?: RemoteConfigType;
serverTimeSkew?: number;
} & Partial<
Pick<
StorageAccessType,
| 'universalExpireTimer'
| 'defaultConversationColor'
| 'customColors'
| 'preferredLeftPaneWidth'
| 'navTabsCollapsed'
| 'preferredReactionEmoji'
| 'areWeASubscriber'
| 'usernameLinkColor'
| 'usernameLink'
>
>
} & Partial<StorageAccessType>
>;
// Actions

View File

@ -23,6 +23,7 @@ export const SHOW_TOAST = 'toast/SHOW_TOAST';
type HideToastActionType = ReadonlyDeep<{
type: typeof HIDE_TOAST;
payload: AnyToast | undefined;
}>;
// eslint-disable-next-line local-rules/type-alias-readonlydeep
@ -36,9 +37,12 @@ export type ToastActionType = HideToastActionType | ShowToastActionType;
// Action Creators
function hideToast(): HideToastActionType {
export type HideToastAction = ReadonlyDeep<(toast?: AnyToast) => void>;
function hideToast(toast?: AnyToast): HideToastActionType {
return {
type: HIDE_TOAST,
payload: toast,
};
}
@ -80,6 +84,10 @@ export function reducer(
action: Readonly<ToastActionType>
): ToastStateType {
if (action.type === HIDE_TOAST) {
if (action.payload != null && state.toast !== action.payload) {
return state;
}
return {
...state,
toast: undefined,

View File

@ -28,6 +28,8 @@ import {
import { showToast } from './toast';
import { ToastType } from '../../types/Toast';
import type { ToastActionType } from './toast';
import type { BoundActionCreatorsMapObject } from '../../hooks/useBoundActions';
import { useBoundActions } from '../../hooks/useBoundActions';
export type UsernameReservationStateType = ReadonlyDeep<{
state: UsernameReservationState;
@ -129,6 +131,10 @@ export const actions = {
markCompletedUsernameLinkOnboarding,
};
export const useUsernameActions = (): BoundActionCreatorsMapObject<
typeof actions
> => useBoundActions(actions);
export function setUsernameEditState(
editState: UsernameEditState
): SetUsernameEditStateActionType {

View File

@ -5,6 +5,7 @@ import { createSelector } from 'reselect';
import type { StateType } from '../reducer';
import type { GlobalModalsStateType } from '../ducks/globalModals';
import { UsernameOnboardingState } from '../../types/globalModals';
export const getGlobalModalsState = (state: StateType): GlobalModalsStateType =>
state.globalModals;
@ -12,5 +13,11 @@ export const getGlobalModalsState = (state: StateType): GlobalModalsStateType =>
export const isShowingAnyModal = createSelector(
getGlobalModalsState,
(globalModalsState): boolean =>
Object.values(globalModalsState).some(value => Boolean(value))
Object.entries(globalModalsState).some(([key, value]) => {
if (key === 'usernameOnboardingState') {
return value === UsernameOnboardingState.Open;
}
return Boolean(value);
})
);

View File

@ -2,7 +2,7 @@
// SPDX-License-Identifier: AGPL-3.0-only
import React from 'react';
import { connect } from 'react-redux';
import { useSelector } from 'react-redux';
import type { VerificationTransport } from '../../types/VerificationTransport';
import { App } from '../../components/App';
@ -12,18 +12,16 @@ import { SmartCallManager } from './CallManager';
import { SmartGlobalModalContainer } from './GlobalModalContainer';
import { SmartLightbox } from './Lightbox';
import { SmartStoryViewer } from './StoryViewer';
import type { StateType } from '../reducer';
import {
getIntl,
getLocaleMessages,
getTheme,
getIsMainWindowMaximized,
getIsMainWindowFullScreen,
getMenuOptions,
} from '../selectors/user';
import { hasSelectedStoryData } from '../selectors/stories';
import { getHideMenuBar } from '../selectors/items';
import { mapDispatchToProps } from '../actions';
import type { StateType } from '../reducer';
import { useAppActions } from '../ducks/app';
import { useConversationsActions } from '../ducks/conversations';
import { useStoriesActions } from '../ducks/stories';
import { ErrorBoundary } from '../../components/ErrorBoundary';
import { ModalContainer } from '../../components/ModalContainer';
import { SmartInbox } from './Inbox';
@ -32,58 +30,58 @@ function renderInbox(): JSX.Element {
return <SmartInbox />;
}
const mapStateToProps = (state: StateType) => {
const i18n = getIntl(state);
export function SmartApp(): JSX.Element {
const app = useSelector((state: StateType) => state.app);
return {
...state.app,
i18n,
localeMessages: getLocaleMessages(state),
isMaximized: getIsMainWindowMaximized(state),
isFullScreen: getIsMainWindowFullScreen(state),
menuOptions: getMenuOptions(state),
OS: OS.getName(),
osClassName: OS.getClassName(),
hideMenuBar: getHideMenuBar(state),
renderCallManager: () => (
<ModalContainer className="module-calling__modal-container">
<SmartCallManager />
</ModalContainer>
),
renderGlobalModalContainer: () => <SmartGlobalModalContainer />,
renderLightbox: () => <SmartLightbox />,
hasSelectedStoryData: hasSelectedStoryData(state),
renderStoryViewer: (closeView: () => unknown) => (
<ErrorBoundary name="App/renderStoryViewer" closeView={closeView}>
<SmartStoryViewer />
</ErrorBoundary>
),
renderInbox,
requestVerification: (
number: string,
captcha: string,
transport: VerificationTransport
): Promise<{ sessionId: string }> => {
const { server } = window.textsecure;
strictAssert(server !== undefined, 'WebAPI not available');
const { openInbox } = useAppActions();
return server.requestVerification(number, captcha, transport);
},
registerSingleDevice: (
number: string,
code: string,
sessionId: string
): Promise<void> => {
return window
.getAccountManager()
.registerSingleDevice(number, code, sessionId);
},
theme: getTheme(state),
const { scrollToMessage } = useConversationsActions();
toast: state.toast.toast,
};
};
const { viewStory } = useStoriesActions();
const smart = connect(mapStateToProps, mapDispatchToProps);
return (
<App
{...app}
isMaximized={useSelector(getIsMainWindowMaximized)}
isFullScreen={useSelector(getIsMainWindowFullScreen)}
osClassName={OS.getClassName()}
renderCallManager={() => (
<ModalContainer className="module-calling__modal-container">
<SmartCallManager />
</ModalContainer>
)}
renderGlobalModalContainer={() => <SmartGlobalModalContainer />}
renderLightbox={() => <SmartLightbox />}
hasSelectedStoryData={useSelector(hasSelectedStoryData)}
renderStoryViewer={(closeView: () => unknown) => (
<ErrorBoundary name="App/renderStoryViewer" closeView={closeView}>
<SmartStoryViewer />
</ErrorBoundary>
)}
renderInbox={renderInbox}
requestVerification={(
number: string,
captcha: string,
transport: VerificationTransport
): Promise<{ sessionId: string }> => {
const { server } = window.textsecure;
strictAssert(server !== undefined, 'WebAPI not available');
export const SmartApp = smart(App);
return server.requestVerification(number, captcha, transport);
}}
registerSingleDevice={(
number: string,
code: string,
sessionId: string
): Promise<void> => {
return window
.getAccountManager()
.registerSingleDevice(number, code, sessionId);
}}
theme={useSelector(getTheme)}
openInbox={openInbox}
scrollToMessage={scrollToMessage}
viewStory={viewStory}
/>
);
}

View File

@ -9,6 +9,7 @@ import {
getPreferredLeftPaneWidth,
} from '../selectors/items';
import { getIntl, getRegionCode } from '../selectors/user';
import type { WidthBreakpoint } from '../../components/_util';
import { CallsTab } from '../../components/CallsTab';
import {
getAllConversations,
@ -23,6 +24,7 @@ import type {
} from '../../types/CallDisposition';
import type { ConversationType } from '../ducks/conversations';
import { SmartConversationDetails } from './ConversationDetails';
import { SmartToastManager } from './ToastManager';
import { useCallingActions } from '../ducks/calling';
import { getActiveCallState } from '../selectors/calling';
import { useCallHistoryActions } from '../ducks/callHistory';
@ -80,6 +82,12 @@ function renderConversationDetails(
);
}
function renderToastManager(props: {
containerWidthBreakpoint: WidthBreakpoint;
}): JSX.Element {
return <SmartToastManager disableMegaphone {...props} />;
}
export function SmartCallsTab(): JSX.Element {
const i18n = useSelector(getIntl);
const navTabsCollapsed = useSelector(getNavTabsCollapsed);
@ -172,6 +180,7 @@ export function SmartCallsTab(): JSX.Element {
onOutgoingVideoCallInConversation={onOutgoingVideoCallInConversation}
preferredLeftPaneWidth={preferredLeftPaneWidth}
renderConversationDetails={renderConversationDetails}
renderToastManager={renderToastManager}
regionCode={regionCode}
savePreferredLeftPaneWidth={savePreferredLeftPaneWidth}
/>

View File

@ -14,10 +14,10 @@ import { usePrevious } from '../../hooks/usePrevious';
import { TargetedMessageSource } from '../ducks/conversationsEnums';
import type { ConversationsStateType } from '../ducks/conversations';
import { useConversationsActions } from '../ducks/conversations';
import { useToastActions } from '../ducks/toast';
import type { StateType } from '../reducer';
import { strictAssert } from '../../util/assert';
import { showToast } from '../../util/showToast';
import { ToastStickerPackInstallFailed } from '../../components/ToastStickerPackInstallFailed';
import { ToastType } from '../../types/Toast';
import { getNavTabsCollapsed } from '../selectors/items';
import { useItemsActions } from '../ducks/items';
import { getHasAnyFailedStorySends } from '../selectors/stories';
@ -56,6 +56,7 @@ export function SmartChatsTab(): JSX.Element {
} = useConversationsActions();
const { showWhatsNewModal } = useGlobalModalActions();
const { toggleNavTabsCollapse } = useItemsActions();
const { showToast } = useToastActions();
const lastOpenedConversationId = useRef<string | undefined>();
@ -121,7 +122,7 @@ export function SmartChatsTab(): JSX.Element {
}
function packInstallFailed() {
showToast(ToastStickerPackInstallFailed);
showToast({ toastType: ToastType.StickerPackInstallFailed });
}
window.Whisper.events.on('pack-install-failed', packInstallFailed);
@ -133,7 +134,7 @@ export function SmartChatsTab(): JSX.Element {
window.Whisper.events.off('refreshConversation', refreshConversation);
window.Whisper.events.off('setupAsNewDevice', unload);
};
}, [onConversationClosed, prevConversationId, showConversation]);
}, [onConversationClosed, prevConversationId, showConversation, showToast]);
useEffect(() => {
if (!selectedConversationId) {

View File

@ -7,6 +7,7 @@ import { CompositionRecording } from '../../components/CompositionRecording';
import { mapDispatchToProps } from '../actions';
import { useAudioRecorderActions } from '../ducks/audioRecorder';
import { useComposerActions } from '../ducks/composer';
import { useToastActions } from '../ducks/toast';
import { getSelectedConversationId } from '../selectors/conversations';
import { getIntl } from '../selectors/user';
@ -22,6 +23,7 @@ export function SmartCompositionRecording({
const { cancelRecording, completeRecording } = useAudioRecorderActions();
const { sendMultiMediaMessage } = useComposerActions();
const { hideToast, showToast } = useToastActions();
const handleCancel = useCallback(() => {
cancelRecording();
@ -54,6 +56,8 @@ export function SmartCompositionRecording({
errorRecording={mapDispatchToProps.errorRecording}
addAttachment={mapDispatchToProps.addAttachment}
completeRecording={mapDispatchToProps.completeRecording}
showToast={showToast}
hideToast={hideToast}
/>
);
}

View File

@ -13,6 +13,7 @@ import { SmartContactModal } from './ContactModal';
import { SmartEditHistoryMessagesModal } from './EditHistoryMessagesModal';
import { SmartForwardMessagesModal } from './ForwardMessagesModal';
import { SmartProfileEditorModal } from './ProfileEditorModal';
import { SmartUsernameOnboardingModal } from './UsernameOnboardingModal';
import { SmartSafetyNumberModal } from './SafetyNumberModal';
import { SmartSendAnywayDialog } from './SendAnywayDialog';
import { SmartShortcutGuideModal } from './ShortcutGuideModal';
@ -31,6 +32,10 @@ function renderProfileEditor(): JSX.Element {
return <SmartProfileEditorModal />;
}
function renderUsernameOnboarding(): JSX.Element {
return <SmartUsernameOnboardingModal />;
}
function renderContactModal(): JSX.Element {
return <SmartContactModal />;
}
@ -77,6 +82,7 @@ export function SmartGlobalModalContainer(): JSX.Element {
isSignalConnectionsVisible,
isStoriesSettingsVisible,
isWhatsNewVisible,
usernameOnboardingState,
safetyNumberChangedBlockingData,
safetyNumberModalContactId,
sendEditWarningData,
@ -157,6 +163,7 @@ export function SmartGlobalModalContainer(): JSX.Element {
renderDeleteMessagesModal={renderDeleteMessagesModal}
renderForwardMessagesModal={renderForwardMessagesModal}
renderProfileEditor={renderProfileEditor}
renderUsernameOnboarding={renderUsernameOnboarding}
renderSafetyNumber={renderSafetyNumber}
renderSendAnywayDialog={renderSendAnywayDialog}
renderShortcutGuideModal={renderShortcutGuideModal}
@ -171,6 +178,7 @@ export function SmartGlobalModalContainer(): JSX.Element {
theme={theme}
toggleSignalConnectionsModal={toggleSignalConnectionsModal}
userNotFoundModalState={userNotFoundModalState}
usernameOnboardingState={usernameOnboardingState}
isAuthorizingArtCreator={isAuthorizingArtCreator}
authArtCreatorData={authArtCreatorData}
cancelAuthorizeArtCreator={cancelAuthorizeArtCreator}

View File

@ -24,6 +24,7 @@ import {
} from '../../components/InstallScreen';
import { InstallError } from '../../components/installScreen/InstallScreenErrorStep';
import { MAX_DEVICE_NAME_LENGTH } from '../../components/installScreen/InstallScreenChoosingDeviceNameStep';
import { WidthBreakpoint } from '../../components/_util';
import { HTTPError } from '../../textsecure/Errors';
import { isRecord } from '../../util/isRecord';
import * as Errors from '../../types/errors';
@ -32,6 +33,7 @@ import OS from '../../util/os/osMain';
import { SECOND } from '../../util/durations';
import { BackOff } from '../../util/BackOff';
import { drop } from '../../util/drop';
import { SmartToastManager } from './ToastManager';
type PropsType = ComponentProps<typeof InstallScreen>;
@ -328,5 +330,13 @@ export function SmartInstallScreen(): ReactElement {
throw missingCaseError(state);
}
return <InstallScreen {...props} />;
return (
<>
<InstallScreen {...props} />
<SmartToastManager
disableMegaphone
containerWidthBreakpoint={WidthBreakpoint.Narrow}
/>
</>
);
}

View File

@ -77,6 +77,7 @@ import { SmartMessageSearchResult } from './MessageSearchResult';
import { SmartNetworkStatus } from './NetworkStatus';
import { SmartRelinkDialog } from './RelinkDialog';
import { SmartUnsupportedOSDialog } from './UnsupportedOSDialog';
import { SmartToastManager } from './ToastManager';
import type { PropsType as SmartUnsupportedOSDialogPropsType } from './UnsupportedOSDialog';
import { SmartUpdateDialog } from './UpdateDialog';
import { SmartCaptchaDialog } from './CaptchaDialog';
@ -116,6 +117,17 @@ function renderUnsupportedOSDialog(
): JSX.Element {
return <SmartUnsupportedOSDialog {...props} />;
}
function renderToastManager(props: {
containerWidthBreakpoint: WidthBreakpoint;
}): JSX.Element {
return <SmartToastManager {...props} />;
}
function renderToastManagerWithoutMegaphone(props: {
containerWidthBreakpoint: WidthBreakpoint;
}): JSX.Element {
return <SmartToastManager disableMegaphone {...props} />;
}
const getModeSpecificProps = (
state: StateType
@ -223,6 +235,10 @@ const mapStateToProps = (state: StateType) => {
unsupportedOSDialogType = 'warning';
}
const composerStep = getComposerStep(state);
const showArchived = getShowArchived(state);
const hasSearchQuery = isSearching(state);
return {
hasNetworkDialog: hasNetworkDialog(state),
hasExpiredDialog,
@ -238,7 +254,7 @@ const mapStateToProps = (state: StateType) => {
preferredWidthFromStorage: getPreferredLeftPaneWidth(state),
selectedConversationId: getSelectedConversationId(state),
targetedMessageId: getTargetedMessage(state)?.id,
showArchived: getShowArchived(state),
showArchived,
getPreferredBadge: getPreferredBadgeSelector(state),
i18n: getIntl(state),
isMacOS: getIsMacOS(state),
@ -253,6 +269,10 @@ const mapStateToProps = (state: StateType) => {
renderCrashReportDialog,
renderExpiredBuildDialog,
renderUnsupportedOSDialog,
renderToastManager:
composerStep == null && !showArchived && !hasSearchQuery
? renderToastManager
: renderToastManagerWithoutMegaphone,
lookupConversationWithoutServiceId,
theme: getTheme(state),
};

View File

@ -14,7 +14,6 @@ import { getIntl } from '../selectors/user';
import {
getEmojiSkinTone,
getUsernamesEnabled,
getHasCompletedUsernameOnboarding,
getHasCompletedUsernameLinkOnboarding,
getUsernameCorrupted,
getUsernameLinkColor,
@ -53,8 +52,6 @@ function mapStateToProps(
const recentEmojis = selectRecentEmojis(state);
const skinTone = getEmojiSkinTone(state);
const isUsernameFlagEnabled = getUsernamesEnabled(state);
const hasCompletedUsernameOnboarding =
getHasCompletedUsernameOnboarding(state);
const hasCompletedUsernameLinkOnboarding =
getHasCompletedUsernameLinkOnboarding(state);
const usernameEditState = getUsernameEditState(state);
@ -72,9 +69,9 @@ function mapStateToProps(
conversationId,
familyName,
firstName: String(firstName),
hasCompletedUsernameOnboarding,
hasCompletedUsernameLinkOnboarding,
hasError: state.globalModals.profileEditorHasError,
initialEditState: state.globalModals.profileEditorInitialEditState,
i18n: getIntl(state),
isUsernameFlagEnabled,
recentEmojis,

View File

@ -7,6 +7,8 @@ import { useSelector } from 'react-redux';
import type { LocalizerType } from '../../types/Util';
import type { StateType } from '../reducer';
import { SmartStoryCreator } from './StoryCreator';
import { SmartToastManager } from './ToastManager';
import type { WidthBreakpoint } from '../../components/_util';
import { StoriesTab } from '../../components/StoriesTab';
import { getMaximumOutgoingAttachmentSizeInKb } from '../../types/AttachmentSize';
import type { ConfigKeyType } from '../../RemoteConfig';
@ -38,6 +40,12 @@ function renderStoryCreator(): JSX.Element {
return <SmartStoryCreator />;
}
function renderToastManager(props: {
containerWidthBreakpoint: WidthBreakpoint;
}): JSX.Element {
return <SmartToastManager disableMegaphone {...props} />;
}
export function SmartStoriesTab(): JSX.Element | null {
const storiesActions = useStoriesActions();
const {
@ -122,6 +130,7 @@ export function SmartStoriesTab(): JSX.Element | null {
preferredLeftPaneWidth={preferredLeftPaneWidth}
preferredWidthFromStorage={preferredWidthFromStorage}
renderStoryCreator={renderStoryCreator}
renderToastManager={renderToastManager}
retryMessageSend={retryMessageSend}
savePreferredLeftPaneWidth={savePreferredLeftPaneWidth}
showConversation={showConversation}

View File

@ -0,0 +1,107 @@
// Copyright 2024 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React from 'react';
import { useSelector } from 'react-redux';
import type { AnyActionableMegaphone } from '../../types/Megaphone';
import { MegaphoneType } from '../../types/Megaphone';
import { UsernameOnboardingState } from '../../types/globalModals';
import OS from '../../util/os/osMain';
import { drop } from '../../util/drop';
import { getIntl } from '../selectors/user';
import {
getGlobalModalsState,
isShowingAnyModal as getIsShowingAnyModal,
} from '../selectors/globalModals';
import { hasSelectedStoryData } from '../selectors/stories';
import { shouldShowLightbox } from '../selectors/lightbox';
import { isInFullScreenCall as getIsInFullScreenCall } from '../selectors/calling';
import { getSelectedNavTab } from '../selectors/nav';
import type { StateType } from '../reducer';
import { useConversationsActions } from '../ducks/conversations';
import type { ConversationsStateType } from '../ducks/conversations';
import { useToastActions } from '../ducks/toast';
import { useGlobalModalActions } from '../ducks/globalModals';
import { NavTab } from '../ducks/nav';
import {
getUsernamesEnabled,
getHasCompletedUsernameOnboarding,
} from '../selectors/items';
import { ToastManager } from '../../components/ToastManager';
import type { WidthBreakpoint } from '../../components/_util';
export type SmartPropsType = Readonly<{
disableMegaphone?: boolean;
containerWidthBreakpoint: WidthBreakpoint;
}>;
export function SmartToastManager({
disableMegaphone = false,
containerWidthBreakpoint,
}: SmartPropsType): JSX.Element {
const i18n = useSelector(getIntl);
const isUsernameFlagEnabled = useSelector(getUsernamesEnabled);
const hasCompletedUsernameOnboarding = useSelector(
getHasCompletedUsernameOnboarding
);
const toast = useSelector((state: StateType) => state.toast.toast);
const globalModals = useSelector(getGlobalModalsState);
const isShowingAnyModal = useSelector(getIsShowingAnyModal);
const isShowingStory = useSelector(hasSelectedStoryData);
const isShowingLightbox = useSelector(shouldShowLightbox);
const isInFullScreenCall = useSelector(getIsInFullScreenCall);
const selectedNavTab = useSelector(getSelectedNavTab);
const { selectedConversationId } = useSelector<
StateType,
ConversationsStateType
>(state => state.conversations);
const { onUndoArchive } = useConversationsActions();
const { openFileInFolder, hideToast } = useToastActions();
const { toggleUsernameOnboarding } = useGlobalModalActions();
let megaphone: AnyActionableMegaphone | undefined;
if (
isUsernameFlagEnabled &&
!hasCompletedUsernameOnboarding &&
globalModals.usernameOnboardingState === UsernameOnboardingState.NeverShown
) {
megaphone = {
type: MegaphoneType.UsernameOnboarding,
onLearnMore: toggleUsernameOnboarding,
onDismiss: () => {
drop(window.storage.put('hasCompletedUsernameOnboarding', true));
},
};
}
const centerToast =
isShowingAnyModal ||
isShowingStory ||
isShowingLightbox ||
isInFullScreenCall;
const isCompositionAreaVisible =
selectedNavTab === NavTab.Chats && Boolean(selectedConversationId);
return (
<ToastManager
i18n={i18n}
OS={OS.getName()}
toast={toast}
megaphone={disableMegaphone ? undefined : megaphone}
onShowDebugLog={() => window.IPC.showDebugLog()}
onUndoArchive={onUndoArchive}
openFileInFolder={openFileInFolder}
hideToast={hideToast}
centerToast={centerToast}
containerWidthBreakpoint={containerWidthBreakpoint}
isCompositionAreaVisible={isCompositionAreaVisible}
/>
);
}

View File

@ -0,0 +1,43 @@
// Copyright 2024 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React, { useCallback } from 'react';
import { useSelector } from 'react-redux';
import { UsernameOnboardingModal } from '../../components/UsernameOnboardingModal';
import { EditState } from '../../components/ProfileEditor';
import { getIntl } from '../selectors/user';
import { useGlobalModalActions } from '../ducks/globalModals';
import { useUsernameActions } from '../ducks/username';
export function SmartUsernameOnboardingModal(): JSX.Element {
const i18n = useSelector(getIntl);
const { toggleProfileEditor, toggleUsernameOnboarding } =
useGlobalModalActions();
const { openUsernameReservationModal } = useUsernameActions();
const onNext = useCallback(async () => {
await window.storage.put('hasCompletedUsernameOnboarding', true);
openUsernameReservationModal();
toggleProfileEditor(EditState.Username);
toggleUsernameOnboarding();
}, [
toggleProfileEditor,
toggleUsernameOnboarding,
openUsernameReservationModal,
]);
const onSkip = useCallback(async () => {
await window.storage.put('hasCompletedUsernameOnboarding', true);
toggleUsernameOnboarding();
}, [toggleUsernameOnboarding]);
return (
<UsernameOnboardingModal
i18n={i18n}
onNext={onNext}
onSkip={onSkip}
onClose={toggleUsernameOnboarding}
/>
);
}

View File

@ -54,7 +54,8 @@ describe('both/state/selectors/items', () => {
0.1,
1.2,
NaN,
].forEach(skinTone => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- for testing
].forEach((skinTone: any) => {
const state = getRootState({ skinTone });
assert.strictEqual(getEmojiSkinTone(state), 0);
});

View File

@ -156,9 +156,6 @@ describe('pnp/username', function (this: Mocha.Suite) {
const profileEditor = window.locator('.ProfileEditor');
await profileEditor.locator('.ProfileEditor__row >> "Username"').click();
debug('skipping onboarding');
await profileEditor.locator('.module-Button >> "Continue"').click();
debug('entering new username');
const usernameField = profileEditor.locator('.Input__input');
await usernameField.type(NICKNAME);

20
ts/types/Megaphone.ts Normal file
View File

@ -0,0 +1,20 @@
// Copyright 2024 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
export enum MegaphoneType {
UsernameOnboarding = 'UsernameOnboarding',
}
export type UsernameOnboardingMegaphoneType = {
type: MegaphoneType.UsernameOnboarding;
};
export type UsernameOnboardingActionableMegaphoneType =
UsernameOnboardingMegaphoneType & {
onLearnMore: () => void;
onDismiss: () => void;
};
export type AnyMegaphone = UsernameOnboardingMegaphoneType;
export type AnyActionableMegaphone = UsernameOnboardingActionableMegaphoneType;

View File

@ -8,6 +8,8 @@ export enum ToastType {
Blocked = 'Blocked',
BlockedGroup = 'BlockedGroup',
CallHistoryCleared = 'CallHistoryCleared',
CaptchaFailed = 'CaptchaFailed',
CaptchaSolved = 'CaptchaSolved',
CannotEditMessage = 'CannotEditMessage',
CannotForwardEmptyMessage = 'CannotForwardEmptyMessage',
CannotMixMultiAndNonMultiAttachments = 'CannotMixMultiAndNonMultiAttachments',
@ -21,20 +23,28 @@ export enum ToastType {
CopiedUsername = 'CopiedUsername',
CopiedUsernameLink = 'CopiedUsernameLink',
DangerousFileType = 'DangerousFileType',
DecryptionError = 'DecryptionError',
DebugLogError = 'DebugLogError',
DeleteForEveryoneFailed = 'DeleteForEveryoneFailed',
Error = 'Error',
Expired = 'Expired',
FailedToDeleteUsername = 'FailedToDeleteUsername',
FailedToFetchPhoneNumber = 'FailedToFetchPhoneNumber',
FailedToFetchUsername = 'FailedToFetchUsername',
FileSaved = 'FileSaved',
FileSize = 'FileSize',
GroupLinkCopied = 'GroupLinkCopied',
InvalidConversation = 'InvalidConversation',
LeftGroup = 'LeftGroup',
LinkCopied = 'LinkCopied',
LoadingFullLogs = 'LoadingFullLogs',
MaxAttachments = 'MaxAttachments',
MessageBodyTooLong = 'MessageBodyTooLong',
OriginalMessageNotFound = 'OriginalMessageNotFound',
PinnedConversationsFull = 'PinnedConversationsFull',
ReactionFailed = 'ReactionFailed',
ReportedSpamAndBlocked = 'ReportedSpamAndBlocked',
StickerPackInstallFailed = 'StickerPackInstallFailed',
StoryMuted = 'StoryMuted',
StoryReact = 'StoryReact',
StoryReply = 'StoryReply',
@ -48,6 +58,8 @@ export enum ToastType {
UnsupportedMultiAttachment = 'UnsupportedMultiAttachment',
UnsupportedOS = 'UnsupportedOS',
UserAddedToGroup = 'UserAddedToGroup',
VoiceNoteLimit = 'VoiceNoteLimit',
VoiceNoteMustBeTheOnlyAttachment = 'VoiceNoteMustBeTheOnlyAttachment',
WhoCanFindMeReadOnly = 'WhoCanFindMeReadOnly',
}
@ -64,6 +76,8 @@ export type AnyToast =
| { toastType: ToastType.CannotOpenGiftBadgeIncoming }
| { toastType: ToastType.CannotOpenGiftBadgeOutgoing }
| { toastType: ToastType.CannotStartGroupCall }
| { toastType: ToastType.CaptchaFailed }
| { toastType: ToastType.CaptchaSolved }
| {
toastType: ToastType.ConversationArchived;
parameters: { conversationId: string };
@ -74,23 +88,37 @@ export type AnyToast =
| { toastType: ToastType.CopiedUsername }
| { toastType: ToastType.CopiedUsernameLink }
| { toastType: ToastType.DangerousFileType }
| { toastType: ToastType.DebugLogError }
| { toastType: ToastType.DeleteForEveryoneFailed }
| { toastType: ToastType.Error }
| { toastType: ToastType.Expired }
| { toastType: ToastType.FailedToDeleteUsername }
| { toastType: ToastType.FailedToFetchPhoneNumber }
| { toastType: ToastType.FailedToFetchUsername }
| { toastType: ToastType.FileSaved; parameters: { fullPath: string } }
| {
toastType: ToastType.FileSize;
parameters: { limit: number; units: string };
}
| { toastType: ToastType.GroupLinkCopied }
| {
toastType: ToastType.DecryptionError;
parameters: {
name: string;
deviceId: number;
};
}
| { toastType: ToastType.InvalidConversation }
| { toastType: ToastType.LeftGroup }
| { toastType: ToastType.LinkCopied }
| { toastType: ToastType.LoadingFullLogs }
| { toastType: ToastType.MaxAttachments }
| { toastType: ToastType.MessageBodyTooLong }
| { toastType: ToastType.OriginalMessageNotFound }
| { toastType: ToastType.PinnedConversationsFull }
| { toastType: ToastType.ReactionFailed }
| { toastType: ToastType.ReportedSpamAndBlocked }
| { toastType: ToastType.StickerPackInstallFailed }
| { toastType: ToastType.StoryMuted }
| { toastType: ToastType.StoryReact }
| { toastType: ToastType.StoryReply }
@ -110,4 +138,6 @@ export type AnyToast =
toastType: ToastType.UserAddedToGroup;
parameters: { contact: string; group: string };
}
| { toastType: ToastType.VoiceNoteLimit }
| { toastType: ToastType.VoiceNoteMustBeTheOnlyAttachment }
| { toastType: ToastType.WhoCanFindMeReadOnly };

8
ts/types/globalModals.ts Normal file
View File

@ -0,0 +1,8 @@
// Copyright 2024 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
export enum UsernameOnboardingState {
NeverShown = 'NeverShown',
Open = 'Open',
Closed = 'Closed',
}

View File

@ -1,10 +1,9 @@
// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import { showToast } from './showToast';
import { ToastGroupLinkCopied } from '../components/ToastGroupLinkCopied';
import { ToastType } from '../types/Toast';
export async function copyGroupLink(groupLink: string): Promise<void> {
await window.navigator.clipboard.writeText(groupLink);
showToast(ToastGroupLinkCopied);
window.reduxActions.toast.showToast({ toastType: ToastType.GroupLinkCopied });
}

View File

@ -18,11 +18,7 @@ import * as RemoteConfig from '../RemoteConfig';
import { Address } from '../types/Address';
import { QualifiedAddress } from '../types/QualifiedAddress';
import type { AciString, ServiceIdString } from '../types/ServiceId';
import {
ToastInternalError,
ToastInternalErrorKind,
} from '../components/ToastInternalError';
import { showToast } from './showToast';
import { ToastType } from '../types/Toast';
import * as Errors from '../types/errors';
import type { ConversationModel } from '../models/conversations';
@ -200,11 +196,12 @@ function maybeShowDecryptionToast(
}
log.info(`maybeShowDecryptionToast/${logId}: Showing decryption error toast`);
showToast(ToastInternalError, {
kind: ToastInternalErrorKind.DecryptionError,
deviceId,
name,
onShowDebugLog: () => window.IPC.showDebugLog(),
window.reduxActions.toast.showToast({
toastType: ToastType.DecryptionError,
parameters: {
deviceId,
name,
},
});
}

View File

@ -3,14 +3,12 @@
import { usernames, LibSignalErrorBase } from '@signalapp/libsignal-client';
import { ToastFailedToFetchUsername } from '../components/ToastFailedToFetchUsername';
import { ToastFailedToFetchPhoneNumber } from '../components/ToastFailedToFetchPhoneNumber';
import type { UserNotFoundModalStateType } from '../state/ducks/globalModals';
import * as log from '../logging/log';
import type { AciString } from '../types/ServiceId';
import * as Errors from '../types/errors';
import { ToastType } from '../types/Toast';
import { HTTPError } from '../textsecure/Errors';
import { showToast } from './showToast';
import { strictAssert } from './assert';
import type { UUIDFetchStateKeyType } from './uuidFetchState';
import { getServiceIdsForE164s } from './getServiceIdsForE164s';
@ -121,9 +119,13 @@ export async function lookupConversationWithoutServiceId(
);
if (options.type === 'e164') {
showToast(ToastFailedToFetchPhoneNumber);
window.reduxActions.toast.showToast({
toastType: ToastType.FailedToFetchPhoneNumber,
});
} else {
showToast(ToastFailedToFetchUsername);
window.reduxActions.toast.showToast({
toastType: ToastType.FailedToFetchUsername,
});
}
return undefined;

View File

@ -17,9 +17,8 @@ import { fileToBytes } from './fileToBytes';
import { handleImageAttachment } from './handleImageAttachment';
import { handleVideoAttachment } from './handleVideoAttachment';
import { isHeic, stringToMIMEType } from '../types/MIME';
import { ToastType } from '../types/Toast';
import { isImageTypeSupported, isVideoTypeSupported } from './GoogleChrome';
import { showToast } from './showToast';
import { ToastFileSize } from '../components/ToastFileSize';
export async function processAttachment(
file: File,
@ -80,7 +79,10 @@ function isAttachmentSizeOkay(attachment: Readonly<AttachmentType>): boolean {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
if ((attachment.data.byteLength / KIBIBYTE).toFixed(4) >= limitKb) {
showToast(ToastFileSize, getRenderDetailsForLimit(limitKb));
window.reduxActions.toast.showToast({
toastType: ToastType.FileSize,
parameters: getRenderDetailsForLimit(limitKb),
});
return false;
}

View File

@ -1,58 +0,0 @@
// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React from 'react';
import { render, unmountComponentAtNode } from 'react-dom';
import type { ToastCaptchaFailed } from '../components/ToastCaptchaFailed';
import type { ToastCaptchaSolved } from '../components/ToastCaptchaSolved';
import type {
ToastInternalError,
ToastPropsType as ToastInternalErrorPropsType,
} from '../components/ToastInternalError';
import type {
ToastFileSize,
ToastPropsType as ToastFileSizePropsType,
} from '../components/ToastFileSize';
import type { ToastGroupLinkCopied } from '../components/ToastGroupLinkCopied';
import type { ToastLinkCopied } from '../components/ToastLinkCopied';
import type { ToastLoadingFullLogs } from '../components/ToastLoadingFullLogs';
import type { ToastStickerPackInstallFailed } from '../components/ToastStickerPackInstallFailed';
import type { ToastVoiceNoteLimit } from '../components/ToastVoiceNoteLimit';
import type { ToastVoiceNoteMustBeOnlyAttachment } from '../components/ToastVoiceNoteMustBeOnlyAttachment';
export function showToast(Toast: typeof ToastCaptchaFailed): void;
export function showToast(Toast: typeof ToastCaptchaSolved): void;
export function showToast(
Toast: typeof ToastInternalError,
props: ToastInternalErrorPropsType
): void;
export function showToast(
Toast: typeof ToastFileSize,
props: ToastFileSizePropsType
): void;
export function showToast(Toast: typeof ToastGroupLinkCopied): void;
export function showToast(Toast: typeof ToastLinkCopied): void;
export function showToast(Toast: typeof ToastLoadingFullLogs): void;
export function showToast(Toast: typeof ToastStickerPackInstallFailed): void;
export function showToast(Toast: typeof ToastVoiceNoteLimit): void;
export function showToast(
Toast: typeof ToastVoiceNoteMustBeOnlyAttachment
): void;
// eslint-disable-next-line max-len
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
export function showToast(Toast: any, props = {}): void {
const node = document.getElementById('toast');
function onClose() {
if (!node) {
return;
}
unmountComponentAtNode(node);
}
render(<Toast i18n={window.i18n} onClose={onClose} {...props} />, node);
}