Table About Modal: Redesign (#6523)
@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" viewBox="0 0 32 32"><path d="M18.5 4.1c1.9 0 3.5 1.6 3.5 3.5q0 .75-.3 1.5h2c.4 0 .9.1 1.3.3.7.3 1.3.9 1.7 1.7.2.4.3.8.3 1.3V15c0 .3-.1.6-.2.9-.2.5-.6.8-1 1.1v7.7c0 .5-.1.9-.3 1.4-.3.7-.9 1.2-1.5 1.5-.4.2-.9.3-1.4.3H9.7c-.5 0-.9-.1-1.4-.3-.8-.4-1.3-.9-1.7-1.6-.2-.4-.3-.9-.3-1.4v-7.7c-.4-.3-.8-.6-1-1.1-.2-.2-.3-.5-.3-.8v-2.6c0-.4.1-.9.3-1.3.4-.8 1-1.4 1.7-1.7.4-.2.8-.3 1.3-.3h2q-.3-.75-.3-1.5c0-1.9 1.6-3.5 3.5-3.5 1 0 1.9.4 2.5 1.1.6-.7 1.5-1.1 2.5-1.1m5.2 13.2H17v8.6h5.4c.4 0 .5-.1.6-.1.3-.1.5-.4.7-.7.1-.1.1-.3.1-.6v-1.6zM8.2 22.9v1.5c0 .4.1.5.1.6.1.3.4.5.7.7.1.1.3.1.6.1H15v-8.6H8.2zm8.8-7.6h7.7c.1 0 .2-.1.2-.2v-2.5c0-.3-.1-.5-.1-.6-.1-.3-.4-.6-.7-.7-.1 0-.3-.1-.6-.1H17zm-7.1-4.2H8.4c-.3 0-.5.1-.6.1-.3.1-.6.4-.7.7 0 .1-.1.3-.1.6V15c0 .1.1.2.2.2H15V11H9.9zm3.6-5c-.8 0-1.5.7-1.5 1.5s.7 1.5 1.5 1.5H15V7.6c0-.9-.7-1.5-1.5-1.5m5 0c-.8 0-1.5.7-1.5 1.5v1.5h1.5c.8 0 1.5-.7 1.5-1.5 0-.9-.7-1.5-1.5-1.5"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path d="M19.4 0C21.9 0 24 2.1 24 4.7c0 .7-.2 1.4-.5 2h2.8c.6 0 1.2.1 1.7.4 1 .5 1.8 1.3 2.2 2.2.3.5.4 1.1.4 1.7v3.5q0 .6-.3 1.2c-.3.6-.8 1.1-1.4 1.5v10.3c-.1.6-.2 1.3-.5 1.8-.4.9-1.2 1.6-2 2-.6.3-1.2.4-1.8.5s-1.4 0-2.3 0h-15c-.6-.1-1.3-.2-1.8-.5-.9-.4-1.6-1.2-2-2-.4-.4-.5-1-.5-1.7V17.3c-.6-.3-1.1-.9-1.4-1.5q-.3-.6-.3-1.2v-3.5c0-.6.1-1.2.4-1.7.5-1 1.3-1.8 2.2-2.2.5-.3 1.1-.4 1.7-.4h2.8C8.1 6.1 8 5.4 8 4.7 8 2.1 10.1 0 12.6 0 14 0 15.1.5 16 1.4 16.9.5 18 0 19.4 0m6.9 17.8h-8.9v11.6h7.1c.5 0 .7-.1.8-.2q.6-.3.9-.9c.1-.1.1-.4.2-.8v-9.6zM5.6 25.3v2.1c0 .5.1.7.2.8q.3.6.9.9c.1.1.4.1.8.2h7.1V17.8h-9zm11.7-10.2h10.2c.1-.1.3-.2.3-.3v-3.3c0-.4-.1-.7-.2-.8-.2-.4-.5-.8-1-1-.1-.1-.3-.1-.8-.2H17v5.6zM7.8 9.4h-2c-.4 0-.7.1-.8.2-.4.2-.8.5-1 1 .1.1 0 .3 0 .7v3.3c.1.1.2.3.3.3h10.2V9.4zm4.8-6.7c-1.1 0-2 .9-2 2s.9 2 2 2h2v-2c.1-1.1-.8-2-2-2m6.8 0c-1.1 0-2 .9-2 2v2h2c1.1 0 2-.9 2-2s-.9-2-2-2"/></svg>
|
||||||
|
Before Width: | Height: | Size: 974 B After Width: | Height: | Size: 951 B |
@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="none"><path fill="#000" d="M19.58 16C23.868 14.353 27 10.153 27 5.294A3.306 3.306 0 0 0 23.703 2H7.297A3.305 3.305 0 0 0 4 5.294C4 10.153 7.05 14.353 11.42 16 7.132 17.647 4 21.847 4 26.706A3.306 3.306 0 0 0 7.297 30h16.406A3.306 3.306 0 0 0 27 26.706c0-4.859-3.133-9.059-7.42-10.706M5.65 5.294c0-.906.742-1.647 1.648-1.647h16.406c.906 0 1.648.741 1.648 1.647 0 5.435-4.451 9.8-9.81 9.8-5.358 0-9.892-4.365-9.892-9.8m18.054 23.059H7.297a1.653 1.653 0 0 1-1.648-1.647c0-5.435 4.451-9.8 9.81-9.8 5.358 0 9.892 4.365 9.892 9.8 0 .906-.742 1.647-1.648 1.647"/><path fill="#000" d="m9.688 24.235.824 1.4 4.947-3.13 5.029 3.13.824-1.4-5.853-3.623zM19.498 9l.99.741.989-1.317-.99-.742c-1.154-.906-2.802-.906-4.039 0-.577.494-1.401.494-2.06 0a3.47 3.47 0 0 0-4.123 0l-.824.742.99 1.317.906-.741a1.62 1.62 0 0 1 2.06 0c1.155.906 2.886.906 4.04 0 .66-.412 1.484-.412 2.061 0"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path d="M21.525 15.999c4.1-2.084 6.721-6.484 6.721-11.361 0-2.42-1.846-4.388-4.115-4.388H7.865C5.595.25 3.75 2.219 3.75 4.638c0 4.88 2.623 9.28 6.725 11.363-4.1 2.084-6.72 6.484-6.72 11.362 0 2.42 1.845 4.387 4.114 4.387h16.267c2.268 0 4.114-1.968 4.114-4.387 0-4.88-2.623-9.282-6.725-11.364m-6.004 1.22h.962c5.213 0 9.453 4.547 9.453 10.137 0 1.073-.807 1.946-1.8 1.946H7.869c-.993 0-1.8-.873-1.8-1.946 0-5.59 4.24-10.137 9.452-10.137m.958-2.445h-.963c-5.212 0-9.453-4.547-9.453-10.136 0-1.074.809-1.947 1.802-1.947h16.266c.993 0 1.801.873 1.801 1.947 0 5.59-4.24 10.136-9.453 10.136" class="st0"/><path d="M8.044 27.952q.12.027.24.026c.219 0 .435-.066.623-.195l6.868-4.668a.39.39 0 0 1 .446 0l6.866 4.667c.516.358 1.275.182 1.607-.377.335-.562.177-1.313-.352-1.674l-6.868-4.669a2.62 2.62 0 0 0-2.954.001l-6.867 4.668c-.53.36-.687 1.112-.352 1.674.168.284.432.479.743.547M23.19 6.253c-1.675-1.57-3.924-1.57-5.598 0l-.326.305c-.802.75-1.722.751-2.528-.001l-.324-.303c-1.674-1.57-3.925-1.57-5.6 0l-.862.807a1.27 1.27 0 0 0-.108 1.71c.204.25.488.4.801.421.313.011.61-.088.842-.304l.863-.809c.803-.752 1.725-.752 2.528 0l.325.305c.818.766 1.787 1.172 2.8 1.172s1.98-.405 2.797-1.17l.328-.308c.802-.75 1.721-.754 2.525 0l.854.799c.231.219.528.333.838.306.313-.019.6-.17.806-.421a1.273 1.273 0 0 0-.108-1.71z"/></svg>
|
||||||
|
Before Width: | Height: | Size: 942 B After Width: | Height: | Size: 1.3 KiB |
@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32"><path d="M17.75 4.875a2.833 2.833 0 0 1 3.933 2.612v7.304l.354-.713a2.637 2.637 0 0 1 3.542-1.179 2.714 2.714 0 0 1 1.267 3.533L23.7 23.507a8.962 8.962 0 0 1-8.183 5.321h-.742c-5.442-.004-9.858-4.421-9.858-9.867v-8.512A2.833 2.833 0 0 1 7.75 7.616c.3 0 .592.046.867.133v-.263a2.833 2.833 0 0 1 3.933-2.612 2.843 2.843 0 0 1 2.6-1.704 2.847 2.847 0 0 1 2.6 1.704zm.238 2.612v7.771c0 .542-.442.983-.983.983s-.983-.442-.983-.983v-9.25a.866.866 0 1 0-1.734 0v9.25c0 .542-.442.983-.983.983s-.983-.442-.983-.983V7.487a.866.866 0 1 0-1.734 0v8.512c0 .542-.442.983-.983.983s-.983-.442-.983-.983v-5.55a.866.866 0 1 0-1.734 0v8.512a7.896 7.896 0 0 0 7.896 7.896h.742a6.991 6.991 0 0 0 6.388-4.15l3.146-7.075a.745.745 0 0 0-.35-.971.668.668 0 0 0-.9.3l-2.225 4.438c-.462.929-1.867.6-1.867-.442V7.486a.866.866 0 1 0-1.73 0z"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path d="M29.414 12.344c-1.333-.661-3.035-.23-3.894 1.01l-1.098 2.142-.002-9.994a3.24 3.24 0 0 0-.847-2.357c-.61-.67-1.477-1.061-2.452-1.104-.529 0-1.044.125-1.51.363a3.307 3.307 0 0 0-6.212.046 3.3 3.3 0 0 0-1.494-.357A3.31 3.31 0 0 0 8.6 5.396v.656a3.308 3.308 0 0 0-4.61 3.035V19.69c0 6.65 5.41 12.06 12.06 12.06h.925c4.314 0 8.236-2.548 9.99-6.49l3.917-8.812a3.143 3.143 0 0 0-1.47-4.104M9.6 17.45c.8 0 1.451-.651 1.451-1.451V5.396a.854.854 0 0 1 1.707 0v9.681c0 .8.652 1.451 1.451 1.451s1.452-.651 1.452-1.45V3.553a.854.854 0 0 1 1.707 0v11.523c0 .8.65 1.451 1.45 1.451s1.451-.651 1.451-1.45c0-.097-.002-9.543.001-9.784.02-.443.383-.803.796-.804.281.013.528.12.695.304.152.166.222.38.21.65l.001 14.241c0 .42.16.791.468 1.079.268.239.634.377 1.002.377.556 0 1.036-.3 1.282-.801l2.809-5.592a.62.62 0 0 1 .788-.211.7.7 0 0 1 .324.915l-3.919 8.813a8.49 8.49 0 0 1-7.75 5.035h-.925c-5.299 0-9.61-4.31-9.61-9.61V9.087a.855.855 0 0 1 1.709 0V16c0 .8.65 1.451 1.45 1.451"/></svg>
|
||||||
|
Before Width: | Height: | Size: 883 B After Width: | Height: | Size: 1.0 KiB |
@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32"><path d="m23.327 8.372.006.295v2.193c.403.087.741.211 1.088.388a5.331 5.331 0 0 1 2.394 2.458l.112.249c.137.331.229.665.29 1.1l.04.347.03.394.021.451.014.516.008.591.004 4.246-.004 1.046-.008.591-.014.516-.021.451-.03.394-.04.347c-.069.49-.176.852-.344 1.224l-.121.251a5.337 5.337 0 0 1-2.458 2.394l-.249.112a4.32 4.32 0 0 1-1.1.29l-.347.04-.394.03-.451.021-.516.014-9.883.008-.591-.008-.516-.014-.451-.021-.394-.03-.347-.04a4.248 4.248 0 0 1-1.224-.344l-.251-.121a5.331 5.331 0 0 1-2.331-2.331c-.338-.663-.485-1.296-.544-2.405l-.023-.597a31.653 31.653 0 0 1-.007-.333l-.007-.742v-4.695l.002-.384.011-.689.023-.596c.06-1.108.206-1.74.544-2.403a5.331 5.331 0 0 1 2.331-2.331 4.312 4.312 0 0 1 1.088-.388V8.664a7.333 7.333 0 0 1 14.66-.295zm-2.66 2.297V8.667a4.667 4.667 0 0 0-9.327-.256l-.007.256v2.004l.321-.003h8.695l.317.002zm-.014 2.667h-9.302l-.789.014-.425.018-.355.025-.295.034-.245.043c-.185.04-.328.091-.453.154-.502.256-.91.664-1.165 1.165a1.799 1.799 0 0 0-.154.453l-.043.244-.034.295-.014.169-.021.388-.014.462-.008.546v5.303l.014.789.018.425.025.355.034.295.043.245c.04.185.091.328.154.453.256.502.664.91 1.165 1.165l.128.059.141.051.161.043.188.036.222.029.413.033.339.016.398.011 1.002.011 8.974-.004.863-.019.339-.016.413-.033.222-.029.188-.036c.029-.007.057-.013.083-.021l.15-.047.068-.026.128-.059a2.66 2.66 0 0 0 1.195-1.228l.055-.133c.008-.023.017-.047.024-.072l.043-.161.036-.188.029-.222.033-.413.016-.339.011-.398.011-1.002.001-3.818-.005-1.156-.019-.863-.016-.339-.033-.413-.029-.222-.036-.188c-.007-.029-.013-.057-.021-.083l-.047-.15a1.368 1.368 0 0 0-.026-.068l-.059-.128a2.666 2.666 0 0 0-1.165-1.165l-.077-.037a1.91 1.91 0 0 0-.375-.118l-.244-.043-.295-.034-.169-.014-.388-.021-.462-.014-.546-.008z"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path d="M24.151 10.992V8.345C24.151 3.85 20.495.193 16 .193S7.849 3.85 7.849 8.345v2.647c-2.59.355-4.599 2.559-4.599 5.244v10.252a5.324 5.324 0 0 0 5.317 5.319h14.866a5.324 5.324 0 0 0 5.317-5.319V16.236c0-2.685-2.009-4.89-4.599-5.244M16 2.693a5.66 5.66 0 0 1 5.651 5.652v2.574H10.35V8.345A5.66 5.66 0 0 1 16 2.693m10.25 23.795a2.82 2.82 0 0 1-2.817 2.819H8.567a2.82 2.82 0 0 1-2.817-2.819V16.236a2.82 2.82 0 0 1 2.817-2.817h14.866a2.82 2.82 0 0 1 2.817 2.817z"/></svg>
|
||||||
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 530 B |
@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" x="0" y="0" version="1.1" viewBox="0 0 32 32"><path d="M12.5 27.1c-.5-.3-.6-.9-.2-1.4l2.7-3.9c.3-.5.9-.6 1.4-.2.5.3.6.9.2 1.4l-1.4 2c3.4.2 6.8-1.2 8.9-4.2 3.2-4.5 2.1-10.7-2.4-13.9C17.2 3.6 11 4.7 7.8 9.2s-2.1 10.7 2.4 13.9c.5.3.6.9.2 1.4-.3.5-.9.6-1.4.2-5.3-3.8-6.6-11.2-2.8-16.6s11.2-6.7 16.7-3c5.4 3.8 6.7 11.2 2.9 16.6-2.4 3.4-6.2 5.2-10.1 5.1l1.9 1.3c.5.3.6.9.2 1.4-.3.5-.9.6-1.4.2z" class="st3"/><path d="M19.1 21.5c-.5 0-.9-.1-1.3-.4l-1.8-1-1.7 1c-1.2.7-2.7.3-3.5-.8-.4-.6-.5-1.3-.3-2l.4-1.4c0-.1.1-.2.1-.4-.2-.1-.4-.2-.6-.4l-.9-.8c-.5-.4-.9-1.1-.9-1.7-.1-.7.2-1.4.6-1.9s1.1-.8 1.7-.9l2-.2.9-2c.6-1 1.8-1.5 2.9-1.2l.4.2c.5.2.9.6 1.1 1l.1.2.8 1.8 2 .2q1.05.15 1.8.9c.4.5.6 1.2.6 1.8-.1.7-.4 1.3-.9 1.7l-1.5 1.2.5 1.8c.2.7.1 1.3-.3 1.9s-.9 1-1.6 1.2c-.3.2-.5.2-.6.2M16 17.8l2.8 1.6c.1.1.3.1.4.1s.3-.1.3-.2c.1-.1.1-.2.1-.4l-.8-3 2.5-2c.1-.1.2-.2.2-.4 0-.1 0-.3-.1-.4s-.2-.2-.4-.2l-3.3-.2-1.3-3-.2-.2-.1-.1c-.2 0-.4 0-.6.2l-.1.1-1.2 2.8-3.2.3c-.1 0-.3.1-.4.2s-.1.3-.1.4.1.3.2.4l.9.8c.3.2.6.4 1 .4l4.1-.5-3.5 2.2c-.2.2-.3.5-.4.7l-.4 1.4c0 .1 0 .3.1.4.2.2.5.3.8.2z" class="st3"/><path d="m12.6 15 4.2-.7c.1 0 .2.1.1.2l-3.7 2.1"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" viewBox="0 0 32 32"><path d="M11.9 28.5c-.5-.4-.7-1.1-.3-1.6l3.3-4.6c.4-.5 1.1-.7 1.6-.3s.7 1.1.3 1.6l-1.6 2.3c4 .3 8-1.5 10.5-5 3.7-5.3 2.4-12.7-2.9-16.4C17.4.8 10.1 2.1 6.3 7.4c-3.7 5.3-2.4 12.7 2.9 16.4.5.4.7 1.1.3 1.6s-1.1.7-1.6.3C1.5 21.3-.1 12.4 4.4 6s13.3-8 19.7-3.5 8 13.3 3.5 19.7c-2.8 4-7.4 6.1-11.9 6l2.2 1.5c.5.4.7 1.1.3 1.6s-1.1.7-1.6.3z"/><path d="M19.6 21.9c-.5 0-1.1-.1-1.5-.4L16 20.2l-2.1 1.2c-1.4.8-3.2.4-4.1-1-.4-.7-.6-1.6-.4-2.4l.5-1.7c0-.1.1-.3.1-.4-.2-.1-.5-.3-.7-.5l-1.1-.9c-.6-.5-1-1.3-1.1-2.1s.2-1.6.7-2.2 1.3-1 2-1l2.4-.2 1-2.4c.7-1.2 2.1-1.8 3.5-1.4l.5.2c.6.3 1 .7 1.3 1.2l.2.4.9 2.2 2.4.2c.8.1 1.6.4 2.1 1.1.5.6.8 1.4.7 2.2s-.5 1.6-1.1 2.1L22 16.1l.5 2.1c.2.8.1 1.6-.3 2.3s-1.1 1.2-1.9 1.4zM16 17.5l3.3 1.9c.1.1.3.1.5.1s.3-.1.4-.3c.1-.1.1-.3.1-.5l-.9-3.6 2.9-2.4c.1-.1.2-.3.2-.4 0-.2 0-.3-.1-.4s-.3-.2-.5-.2l-3.9-.3-1.5-3.5c0-.1-.1-.1-.2-.2l-.2-.1c-.2-.1-.5 0-.7.3V8l-1.5 3.4-3.8.3c-.2 0-.3.1-.4.2-.1.2-.2.3-.1.4 0 .2.1.3.2.4l1.1.9c.3.3.7.4 1.2.5l4.8-.6-4.2 2.6c-.2.2-.4.6-.5.9l-.5 1.7c0 .2 0 .3.1.5.2.3.6.4.9.2z"/><path d="m12 14.2 5-.8c.1 0 .2.2.1.2l-4.4 2.5"/></svg>
|
||||||
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.1 KiB |
@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32"><path d="M13.867 3.198c0-.561.631-.89 1.091-.568l3.431 2.402a.694.694 0 0 1 0 1.136L14.958 8.57a.693.693 0 0 1-1.091-.568V6.679C9.614 7.648 6.44 11.454 6.44 16A9.56 9.56 0 0 0 16 25.56a9.56 9.56 0 0 0 5.355-17.481 1.107 1.107 0 1 1 1.242-1.832A11.762 11.762 0 0 1 27.774 16c0 6.502-5.271 11.773-11.773 11.773S4.228 22.502 4.228 16c0-5.774 4.156-10.577 9.64-11.581V3.198z"/><path d="M10.307 20c-.544 0-.814-.304-.814-.739 0-.327.126-.544.476-.865l2.464-2.355c1.02-.98 1.283-1.381 1.283-1.977 0-.682-.527-1.169-1.266-1.169-.665 0-1.123.332-1.421.997-.195.344-.395.504-.768.504-.464 0-.739-.275-.739-.705 0-.132.023-.252.063-.372.281-.917 1.318-1.77 2.882-1.77 1.753 0 2.933.985 2.933 2.406 0 1.008-.493 1.639-1.845 2.916l-1.787 1.719v.034h3.117c.447 0 .716.269.716.688 0 .407-.269.687-.716.687h-4.578zm9.197.183c-1.312 0-2.458-.613-2.87-1.49a1.291 1.291 0 0 1-.137-.567c0-.441.275-.705.722-.705.344 0 .561.12.756.43.298.596.785.957 1.53.957.899 0 1.547-.647 1.547-1.541 0-.871-.642-1.49-1.541-1.49a1.72 1.72 0 0 0-1.197.493c-.338.315-.51.401-.894.401-.567 0-.837-.395-.814-.859 0-.023 0-.04.006-.069l.241-3.031c.057-.699.418-.98 1.089-.98h3.627c.43 0 .71.269.71.688s-.275.688-.71.688h-3.266l-.195 2.297h.034c.338-.533 1.014-.865 1.856-.865 1.581 0 2.704 1.111 2.704 2.687 0 1.765-1.312 2.956-3.197 2.956z"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path d="M13.3.9c0-.7.8-1.1 1.4-.7l4.3 3c.4.3.5.8.2 1.2 0 0-.1.2-.2.2l-4.3 3c-.4.3-.9.2-1.2-.2-.1-.1-.2-.3-.2-.5V5.2c-5.4 1.2-9.4 6-9.4 11.8S9.3 29.1 16 29.1 28.1 23.7 28.1 17c0-4-2-7.8-5.3-10-.7-.4-.8-1.3-.4-1.9s1.3-.8 1.9-.4c4.1 2.8 6.6 7.4 6.6 12.4C30.9 25.3 24.2 32 16 32S1.1 25.3 1.1 17.1 6.4 3.7 13.3 2.4z"/><path d="M8.8 22.2c-.7 0-1-.4-1-.9s.2-.7.6-1.1l3.1-3c1.3-1.2 1.6-1.7 1.6-2.5s-.7-1.5-1.6-1.5-1.4.4-1.8 1.3c-.2.4-.5.6-1 .6s-.9-.3-.9-.9v-.5c.4-1.2 1.7-2.2 3.6-2.2s3.7 1.2 3.7 3-.6 2.1-2.3 3.7l-2.3 2.2h3.9q.9 0 .9.9c0 .9-.3.9-.9.9H8.6Zm11.6.2c-1.7 0-3.1-.8-3.6-1.9-.1-.2-.2-.5-.2-.7q0-.9.9-.9c.9 0 .7.2 1 .5.4.8 1 1.2 1.9 1.2s2-.8 2-2-.8-1.9-2-1.9q-.9 0-1.5.6c-.4.4-.6.5-1.1.5-.7 0-1.1-.5-1-1.1l.3-3.8c0-.9.5-1.2 1.4-1.2h4.6c.5 0 .9.3.9.9s-.3.9-.9.9H19l-.2 2.9c.4-.7 1.3-1.1 2.4-1.1 2 0 3.4 1.4 3.4 3.4s-1.7 3.7-4 3.7Z"/></svg>
|
||||||
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 900 B |
@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" width="33" height="32"><path d="M18.8 3.198a.693.693 0 0 0-1.091-.568l-3.431 2.402a.694.694 0 0 0 0 1.136l3.431 2.402a.693.693 0 0 0 1.091-.568V6.679c4.253.969 7.427 4.775 7.427 9.321a9.56 9.56 0 0 1-9.56 9.56 9.56 9.56 0 0 1-5.355-17.481 1.107 1.107 0 1 0-1.242-1.832A11.762 11.762 0 0 0 4.893 16c0 6.502 5.271 11.773 11.773 11.773S28.439 22.502 28.439 16c0-5.774-4.156-10.577-9.64-11.581V3.198z"/><path d="M17.025 20.183c-1.312 0-2.458-.613-2.87-1.49a1.292 1.292 0 0 1-.138-.567c0-.441.275-.705.722-.705.344 0 .561.12.756.43.298.596.785.957 1.53.957.899 0 1.547-.647 1.547-1.541 0-.871-.642-1.49-1.541-1.49a1.72 1.72 0 0 0-1.197.493c-.338.315-.51.401-.894.401-.567 0-.836-.395-.813-.859 0-.023 0-.04.006-.069l.241-3.031c.057-.699.418-.98 1.089-.98h3.627c.43 0 .71.269.71.688s-.275.688-.71.688h-3.266l-.195 2.297h.034c.338-.533 1.014-.865 1.856-.865 1.581 0 2.704 1.111 2.704 2.687 0 1.765-1.312 2.956-3.197 2.956z"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 33 32"><path d="M19.4.9c0-.5-.4-.9-.9-.9-.2 0-.4 0-.5.2l-4.3 3c-.4.3-.5.8-.2 1.2 0 0 .1.2.2.2l4.3 3c.4.3.9.2 1.2-.2.1-.1.2-.3.2-.5V5.2c5.4 1.2 9.4 6 9.4 11.8s-5.4 12.1-12.1 12.1S4.6 23.7 4.6 17c0-4 2-7.8 5.3-10 .7-.4.8-1.3.4-1.9-.4-.7-1.3-.8-1.9-.4-4.2 2.8-6.6 7.4-6.6 12.4C1.8 25.3 8.5 32 16.7 32s14.9-6.7 14.9-14.9S26.3 3.7 19.4 2.4z"/><path d="M17.1 22.4c-1.7 0-3.1-.8-3.6-1.9-.1-.2-.2-.5-.2-.7q0-.9.9-.9c.9 0 .7.2 1 .5.4.8 1 1.2 1.9 1.2s2-.8 2-2-.8-1.9-2-1.9q-.9 0-1.5.6c-.4.4-.6.5-1.1.5-.7 0-1.1-.5-1-1.1l.3-3.8c0-.9.5-1.2 1.4-1.2h4.6c.5 0 .9.3.9.9s-.3.9-.9.9h-4.1l-.2 2.9c.4-.7 1.3-1.1 2.4-1.1 2 0 3.4 1.4 3.4 3.4s-1.7 3.7-4 3.7Z"/></svg>
|
||||||
|
Before Width: | Height: | Size: 964 B After Width: | Height: | Size: 697 B |
@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" x="0" y="0" version="1.1" viewBox="0 0 32 32"><path d="M11.9 17.7c-6.2 0-8.4 3.6-9.2 5.7-.3.8-.2 1.7.3 2.5.6.8 1.6 1.3 2.6 1.3h12.5c1.1 0 2.1-.5 2.6-1.3.5-.7.6-1.6.3-2.5-.7-2.1-2.9-5.7-9.1-5.7m7.2 7c-.2.3-.6.5-1 .5H5.6c-.4 0-.8-.2-1-.5-.1-.2-.2-.4-.1-.6.7-2 2.6-4.4 7.3-4.4s6.6 2.4 7.3 4.4q.3.3 0 .6M29.3 22.7c-.6-1.9-2.6-5.2-8.1-5.2h-.7c-.6 0-1 .5-1 1 0 .6.5 1 1 1h.6c4.1 0 5.6 2.1 6.2 3.8v.4c-.1.2-.4.3-.6.3h-3.6c-.6 0-1 .4-1 1s.4 1 1 1h3.6c.9 0 1.8-.4 2.3-1.1s.6-1.5.3-2.2M6.4 12l.8.6c.1.1.2.1.3.2L7.1 14c-.2.7-.1 1.3.3 1.9.7 1.1 2.2 1.5 3.3.8l1.2-.7 1.3.7q.6.3 1.2.3c.2 0 .4 0 .6-.1.6-.1 1.2-.6 1.5-1.1q.45-.9.3-1.8l-.3-1.3.6-.5c.1.3.4.6.6.9l.4.3-.1.4c-.2.6-.1 1.3.3 1.8.7 1 2 1.4 3.1.7l.5-.3.5.3q.6.3 1.2.3c.2 0 .3 0 .5-.1.6-.1 1.1-.5 1.4-1s.4-1.1.3-1.7l-.1-.4.4-.3c.5-.4.8-1 .8-1.6s-.1-1.2-.5-1.7-1-.8-1.6-.8h-.6l-.2-.6c-.3-.5-.7-.8-1.2-1-1.1-.4-2.3 0-2.9 1l-.3.6H19c-.3 0-.5.1-.8.2-.1-.3-.2-.5-.4-.8-.4-.5-1-.8-1.7-.9l-1.5-.1-.5-1.2c-.3-.6-.7-1.1-1.3-1.3-1.2-.5-2.6.1-3.2 1.3l-.4 1.3-1.5.1c-.6 0-1.1.3-1.5.7l-.1.2q-.75.75-.6 1.8c0 .6.4 1.2.9 1.7m12.6-.8c.1-.1.2-.1.2-.1L21 11l.7-1.6c.1-.1.2-.2.4-.1.1 0 .1.1.1.1l.7 1.6 1.8.1c.1 0 .2 0 .2.1s.1.1.1.2-.1.2-.1.2l-1.4 1.1.4 1.7v.2c0 .1-.1.1-.2.1h-.2l-1.5-.9-1.5.9c-.1.1-.3.1-.4-.1 0-.1-.1-.1 0-.2l.3-1.1h.1l1.8-1c.1 0 0-.2-.1-.2l-2.1.1H20c-.1 0-.1-.1-.2-.1l-.5-.4c-.3-.2-.3-.3-.3-.3zM7.5 9.8c.1-.1.2-.2.3-.2l2.6-.2 1-2.4c.1-.2.4-.3.6-.2.1 0 .2.1.2.2l1 2.4 2.8.2c.1 0 .2.1.3.2s.1.2.1.3-.1.2-.2.3l-2 1.7.6 2.5v.3c-.1.1-.2.2-.3.2s-.2 0-.3-.1l-2.3-1.3L9.7 15c-.2.1-.5.1-.6-.1-.1-.1-.1-.3-.1-.4l.3-1.2c0-.2.1-.3.2-.5l3.3-1.7c.1-.1.1-.2-.1-.2l-3.7.4-.6-.3-.8-.6c-.1-.1-.2-.2-.2-.3.1-.1.1-.2.1-.3"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" x="0" y="0" version="1.1" viewBox="0 0 32 32"><style>.st3{fill:#4e8ee5}</style><path d="M11.1 18c-7.4 0-10 4.3-10.9 6.8-.4 1-.2 2.1.4 2.9.7 1 1.9 1.6 3.1 1.6h14.8c1.3 0 2.4-.6 3.1-1.6.6-.9.7-1.9.4-2.9-.9-2.5-3.5-6.8-10.9-6.8m8.6 8.4c-.2.3-.7.5-1.2.5H3.7c-.5 0-1-.2-1.2-.5-.2-.2-.2-.5-.1-.8.9-2.4 3.1-5.2 8.7-5.2s7.8 2.8 8.7 5.2c.1.3.1.5-.1.8M31.8 23.9c-.8-2.3-3-6.1-9.6-6.1h-.8c-.7 0-1.2.6-1.1 1.2 0 .7.6 1.2 1.2 1.1h.7c4.8 0 6.6 2.4 7.3 4.5.1.2 0 .3-.1.4-.1.2-.4.3-.8.3h-4.3c-.7 0-1.2.5-1.2 1.2s.5 1.2 1.2 1.2h4.3c1.1 0 2.1-.5 2.7-1.3.7-.7.8-1.6.5-2.5M4.6 11.2l.9.7c.1.1.2.2.3.2v.1l-.4 1.4c-.2.8-.1 1.6.4 2.3.8 1.3 2.6 1.7 3.9.9l1.5-.9 1.5.9c.5.3 1 .4 1.5.4.2 0 .4 0 .7-.1.8-.2 1.4-.7 1.8-1.3.4-.7.5-1.4.3-2.2l-.4-1.5.8-.6c.2.4.4.8.8 1l.4.3-.1.5c-.2.7-.1 1.5.3 2.1.8 1.2 2.4 1.6 3.7.9l.6-.3.6.4c.4.2.9.4 1.4.4.2 0 .4 0 .6-.1.7-.2 1.3-.6 1.7-1.2s.5-1.4.3-2.1l-.1-.5.4-.4c.6-.5.9-1.1 1-1.9.1-.7-.2-1.4-.6-2-.5-.6-1.2-.9-1.9-1l-.7-.1-.4-.8c-.3-.5-.8-1-1.4-1.2-1.3-.5-2.7 0-3.4 1.2l-.4.8h-.7c-.3 0-.6.1-.9.2-.1-.3-.3-.6-.5-.9-.5-.6-1.2-1-2-1l-1.6.2-.6-1.5c-.3-.7-.9-1.3-1.6-1.5-1.5-.7-3.2 0-3.8 1.5L7.9 6l-1.7.1c-.7 0-1.3.3-1.8.8l-.2.2c-.5.6-.8 1.3-.7 2.1s.5 1.5 1.1 2m14.9-.9c.1-.1.2-.2.3-.2l2.1-.2.8-1.9c.1-.2.3-.2.4-.1.2.1.2.1.3.1l.8 1.9 2.1.2c.1 0 .2.1.3.1.1.1.1.1.1.2s-.1.2-.1.2L25 11.9l.5 2v.2l-.2.2H25l-1.8-1.1-1.8 1c-.1.1-.4.1-.5-.1 0-.1-.1-.2 0-.3l.3-1.3.1-.1 2.1-1.2c.1-.1 0-.2-.1-.2l-2.5.1h-.1c-.1 0-.2-.1-.2-.2l-.6-.5c-.1-.1-.1-.2-.1-.2-.3.3-.3.2-.3.1M5.9 8.7c.2-.2.3-.2.4-.2l3.1-.2 1.2-2.8c.1-.3.5-.4.7-.3l.3.3 1.2 2.8 3.2.2c.1 0 .3.1.4.2s.1.2.1.4c0 .1-.1.3-.2.3l-2.4 2 .7 2.9c0 .1 0 .3-.1.4s-.2.2-.3.2-.3 0-.4-.1l-2.7-1.6-2.7 1.6c-.2.1-.6.1-.7-.2-.1-.1-.1-.3-.1-.4l.4-1.4c.1-.2.1-.4.3-.6l3.9-2c.1-.1.1-.3-.1-.2l-4.5.4c-.3-.1-.5-.2-.7-.4L6 9.3c-.1-.1-.1-.2-.1-.3z"/></svg>
|
||||||
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.8 KiB |
@ -2108,6 +2108,7 @@
|
|||||||
"StarGiftPurchaseTransaction" = "Gift Sale";
|
"StarGiftPurchaseTransaction" = "Gift Sale";
|
||||||
"GiftBuyConfirmDescription" = "Do you want to buy **{gift}** for **{stars}**?";
|
"GiftBuyConfirmDescription" = "Do you want to buy **{gift}** for **{stars}**?";
|
||||||
"GiftBuyForPeerConfirmDescription" = "Do you want to buy **{gift}** for **{stars}** and gift it to **{peer}**?";
|
"GiftBuyForPeerConfirmDescription" = "Do you want to buy **{gift}** for **{stars}** and gift it to **{peer}**?";
|
||||||
|
"GiftBuyEqualsTo" = "Equals to {stars}";
|
||||||
"ComposerTitleForwardFrom" = "From: **{users}**";
|
"ComposerTitleForwardFrom" = "From: **{users}**";
|
||||||
"ContextMenuItemMention" = "Mention";
|
"ContextMenuItemMention" = "Mention";
|
||||||
"GiftRibbonResale" = "resale";
|
"GiftRibbonResale" = "resale";
|
||||||
|
|||||||
@ -8,7 +8,7 @@ import type { UiLoaderPage } from './common/UiLoader';
|
|||||||
|
|
||||||
import { DARK_THEME_BG_COLOR, INACTIVE_MARKER, LIGHT_THEME_BG_COLOR, PAGE_TITLE, PAGE_TITLE_TAURI } from '../config';
|
import { DARK_THEME_BG_COLOR, INACTIVE_MARKER, LIGHT_THEME_BG_COLOR, PAGE_TITLE, PAGE_TITLE_TAURI } from '../config';
|
||||||
import { forceMutation } from '../lib/fasterdom/stricterdom.ts';
|
import { forceMutation } from '../lib/fasterdom/stricterdom.ts';
|
||||||
import { selectTabState, selectTheme } from '../global/selectors';
|
import { selectActionMessageBg, selectTabState, selectTheme } from '../global/selectors';
|
||||||
import { IS_TAURI } from '../util/browser/globalEnvironment';
|
import { IS_TAURI } from '../util/browser/globalEnvironment';
|
||||||
import { IS_INSTALL_PROMPT_SUPPORTED, PLATFORM_ENV } from '../util/browser/windowEnvironment';
|
import { IS_INSTALL_PROMPT_SUPPORTED, PLATFORM_ENV } from '../util/browser/windowEnvironment';
|
||||||
import buildClassName from '../util/buildClassName';
|
import buildClassName from '../util/buildClassName';
|
||||||
@ -43,6 +43,7 @@ type StateProps = {
|
|||||||
hasWebAuthTokenFailed?: boolean;
|
hasWebAuthTokenFailed?: boolean;
|
||||||
isTestServer?: boolean;
|
isTestServer?: boolean;
|
||||||
theme: ThemeKey;
|
theme: ThemeKey;
|
||||||
|
actionMessageBg?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum AppScreens {
|
enum AppScreens {
|
||||||
@ -64,6 +65,7 @@ const App: FC<StateProps> = ({
|
|||||||
hasWebAuthTokenFailed,
|
hasWebAuthTokenFailed,
|
||||||
isTestServer,
|
isTestServer,
|
||||||
theme,
|
theme,
|
||||||
|
actionMessageBg,
|
||||||
}) => {
|
}) => {
|
||||||
const { isMobile } = useAppLayout();
|
const { isMobile } = useAppLayout();
|
||||||
const isMobileOs = PLATFORM_ENV === 'iOS' || PLATFORM_ENV === 'Android';
|
const isMobileOs = PLATFORM_ENV === 'iOS' || PLATFORM_ENV === 'Android';
|
||||||
@ -226,6 +228,12 @@ const App: FC<StateProps> = ({
|
|||||||
);
|
);
|
||||||
}, [theme]);
|
}, [theme]);
|
||||||
|
|
||||||
|
useLayoutEffect(() => {
|
||||||
|
if (actionMessageBg) {
|
||||||
|
document.body.style.setProperty('--action-message-bg', actionMessageBg);
|
||||||
|
}
|
||||||
|
}, [actionMessageBg]);
|
||||||
|
|
||||||
const getIsInBackgroundLocal = getIsInBackground;
|
const getIsInBackgroundLocal = getIsInBackground;
|
||||||
useSignalEffect(() => {
|
useSignalEffect(() => {
|
||||||
// Mutation forced to avoid RAF throttling in background
|
// Mutation forced to avoid RAF throttling in background
|
||||||
@ -263,6 +271,7 @@ export default withGlobal(
|
|||||||
hasWebAuthTokenFailed: global.hasWebAuthTokenFailed || global.hasWebAuthTokenPasswordRequired,
|
hasWebAuthTokenFailed: global.hasWebAuthTokenFailed || global.hasWebAuthTokenPasswordRequired,
|
||||||
theme: selectTheme(global),
|
theme: selectTheme(global),
|
||||||
isTestServer: global.config?.isTestServer,
|
isTestServer: global.config?.isTestServer,
|
||||||
|
actionMessageBg: selectActionMessageBg(global),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
)(App);
|
)(App);
|
||||||
|
|||||||
@ -70,13 +70,17 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
margin-top: 0.1875rem;
|
||||||
|
}
|
||||||
|
|
||||||
.month-selector {
|
.month-selector {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
h4 {
|
h4 {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
margin: 0 0 0 1.25rem;
|
margin: 0 0 0 2.25rem;
|
||||||
font-size: 1.25rem;
|
font-size: 1.25rem;
|
||||||
|
|
||||||
& ~ .Button {
|
& ~ .Button {
|
||||||
|
|||||||
@ -370,16 +370,10 @@ const CalendarModal: FC<OwnProps & StateProps> = ({
|
|||||||
className="CalendarModal"
|
className="CalendarModal"
|
||||||
onEnter={handleSubmit}
|
onEnter={handleSubmit}
|
||||||
dialogRef={dialogRef}
|
dialogRef={dialogRef}
|
||||||
|
hasAbsoluteCloseButton
|
||||||
>
|
>
|
||||||
<div className="container">
|
<div className="container">
|
||||||
<div className="month-selector">
|
<div className="month-selector">
|
||||||
<Button
|
|
||||||
round
|
|
||||||
size="smaller"
|
|
||||||
color="translucent"
|
|
||||||
iconName="close"
|
|
||||||
onClick={onClose}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<h4>
|
<h4>
|
||||||
{oldLang(`lng_month${currentMonth + 1}`)}
|
{oldLang(`lng_month${currentMonth + 1}`)}
|
||||||
|
|||||||
@ -9,8 +9,9 @@
|
|||||||
|
|
||||||
.pickerTitle {
|
.pickerTitle {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
margin: 0 0 0 1.25rem;
|
margin: 0 0 0 2.25rem;
|
||||||
font-size: 1.25rem;
|
font-size: 1.25rem;
|
||||||
|
line-height: 1.25;
|
||||||
|
|
||||||
@media (max-width: 600px) {
|
@media (max-width: 600px) {
|
||||||
margin-left: 0.75rem;
|
margin-left: 0.75rem;
|
||||||
|
|||||||
@ -76,16 +76,10 @@ const CountryPickerModal: FC<OwnProps> = ({
|
|||||||
isOpen={isOpen}
|
isOpen={isOpen}
|
||||||
onClose={onClose}
|
onClose={onClose}
|
||||||
onEnter={handleSubmit}
|
onEnter={handleSubmit}
|
||||||
|
hasAbsoluteCloseButton
|
||||||
>
|
>
|
||||||
<div className={styles.container}>
|
<div className={styles.container}>
|
||||||
<div className={styles.pickerSelector}>
|
<div className={styles.pickerSelector}>
|
||||||
<Button
|
|
||||||
round
|
|
||||||
size="smaller"
|
|
||||||
color="translucent"
|
|
||||||
onClick={onClose}
|
|
||||||
iconName="close"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<h4 className={styles.pickerTitle}>
|
<h4 className={styles.pickerTitle}>
|
||||||
{lang('BoostingSelectCountry')}
|
{lang('BoostingSelectCountry')}
|
||||||
|
|||||||
@ -38,6 +38,6 @@
|
|||||||
|
|
||||||
.closeButton {
|
.closeButton {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0.5rem;
|
top: 0.875rem;
|
||||||
right: 0.5rem;
|
right: 0.875rem;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -87,7 +87,7 @@ const PrivacySettingsNoticeModal = ({ isOpen, isReadDate, user }: OwnProps & Sta
|
|||||||
className={styles.closeButton}
|
className={styles.closeButton}
|
||||||
color="translucent"
|
color="translucent"
|
||||||
round
|
round
|
||||||
size="smaller"
|
size="tiny"
|
||||||
onClick={handleClose}
|
onClick={handleClose}
|
||||||
ariaLabel="Close"
|
ariaLabel="Close"
|
||||||
iconName="close"
|
iconName="close"
|
||||||
|
|||||||
@ -195,7 +195,7 @@ const StickerSetModal: FC<OwnProps & StateProps> = ({
|
|||||||
<Button
|
<Button
|
||||||
round
|
round
|
||||||
color="translucent"
|
color="translucent"
|
||||||
size="smaller"
|
size="tiny"
|
||||||
ariaLabel={lang('Close')}
|
ariaLabel={lang('Close')}
|
||||||
onClick={onClose}
|
onClick={onClose}
|
||||||
iconName="close"
|
iconName="close"
|
||||||
|
|||||||
@ -249,7 +249,7 @@ const ChatOrUserPicker: FC<OwnProps> = ({
|
|||||||
<Button
|
<Button
|
||||||
round
|
round
|
||||||
color="translucent"
|
color="translucent"
|
||||||
size="smaller"
|
size="tiny"
|
||||||
ariaLabel={oldLang('Back')}
|
ariaLabel={oldLang('Back')}
|
||||||
onClick={handleHeaderBackClick}
|
onClick={handleHeaderBackClick}
|
||||||
iconName="arrow-left"
|
iconName="arrow-left"
|
||||||
@ -301,7 +301,7 @@ const ChatOrUserPicker: FC<OwnProps> = ({
|
|||||||
<Button
|
<Button
|
||||||
round
|
round
|
||||||
color="translucent"
|
color="translucent"
|
||||||
size="smaller"
|
size="tiny"
|
||||||
ariaLabel={oldLang('Close')}
|
ariaLabel={oldLang('Close')}
|
||||||
onClick={onClose}
|
onClick={onClose}
|
||||||
iconName="close"
|
iconName="close"
|
||||||
|
|||||||
@ -22,5 +22,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.buttonWrapper {
|
.buttonWrapper {
|
||||||
padding: 0.25rem;
|
position: relative;
|
||||||
|
padding-top: 0.25rem;
|
||||||
|
padding-bottom: 1rem;
|
||||||
|
padding-inline: 1rem;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,13 +1,15 @@
|
|||||||
import { memo } from '../../../lib/teact/teact';
|
import { memo, useRef } from '../../../lib/teact/teact';
|
||||||
|
|
||||||
import buildClassName from '../../../util/buildClassName';
|
import buildClassName from '../../../util/buildClassName';
|
||||||
|
|
||||||
import useOldLang from '../../../hooks/useOldLang';
|
import useOldLang from '../../../hooks/useOldLang';
|
||||||
|
import useScrollNotch from '../../../hooks/useScrollNotch';
|
||||||
|
|
||||||
import Button from '../../ui/Button';
|
import Button from '../../ui/Button';
|
||||||
import Modal, { type OwnProps as ModalProps } from '../../ui/Modal';
|
import Modal, { type OwnProps as ModalProps } from '../../ui/Modal';
|
||||||
|
|
||||||
import styles from './PickerModal.module.scss';
|
import styles from './PickerModal.module.scss';
|
||||||
|
import pickerStyles from './PickerStyles.module.scss';
|
||||||
|
|
||||||
type OwnProps = {
|
type OwnProps = {
|
||||||
confirmButtonText?: string;
|
confirmButtonText?: string;
|
||||||
@ -15,9 +17,12 @@ type OwnProps = {
|
|||||||
shouldAdaptToSearch?: boolean;
|
shouldAdaptToSearch?: boolean;
|
||||||
withFixedHeight?: boolean;
|
withFixedHeight?: boolean;
|
||||||
withPremiumGradient?: boolean;
|
withPremiumGradient?: boolean;
|
||||||
|
itemsContainerSelector?: string;
|
||||||
onConfirm?: NoneToVoidFunction;
|
onConfirm?: NoneToVoidFunction;
|
||||||
} & ModalProps;
|
} & ModalProps;
|
||||||
|
|
||||||
|
const DEFAULT_ITEMS_CONTAINER_SELECTOR = `.${pickerStyles.pickerList}`;
|
||||||
|
|
||||||
const PickerModal = ({
|
const PickerModal = ({
|
||||||
confirmButtonText,
|
confirmButtonText,
|
||||||
isConfirmDisabled,
|
isConfirmDisabled,
|
||||||
@ -25,14 +30,24 @@ const PickerModal = ({
|
|||||||
withFixedHeight,
|
withFixedHeight,
|
||||||
onConfirm,
|
onConfirm,
|
||||||
withPremiumGradient,
|
withPremiumGradient,
|
||||||
|
itemsContainerSelector = DEFAULT_ITEMS_CONTAINER_SELECTOR,
|
||||||
...modalProps
|
...modalProps
|
||||||
}: OwnProps) => {
|
}: OwnProps) => {
|
||||||
const lang = useOldLang();
|
const lang = useOldLang();
|
||||||
const hasButton = Boolean(confirmButtonText || onConfirm);
|
const hasButton = Boolean(confirmButtonText || onConfirm);
|
||||||
|
|
||||||
|
const dialogRef = useRef<HTMLDivElement>();
|
||||||
|
|
||||||
|
useScrollNotch({
|
||||||
|
containerRef: dialogRef,
|
||||||
|
selector: `.modal-content ${itemsContainerSelector}`,
|
||||||
|
isBottomNotch: true,
|
||||||
|
}, [modalProps.isOpen]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
{...modalProps}
|
{...modalProps}
|
||||||
|
dialogRef={dialogRef}
|
||||||
isSlim
|
isSlim
|
||||||
className={buildClassName(
|
className={buildClassName(
|
||||||
shouldAdaptToSearch && styles.withSearch,
|
shouldAdaptToSearch && styles.withSearch,
|
||||||
|
|||||||
@ -51,6 +51,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.pickerList {
|
.pickerList {
|
||||||
|
position: relative;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
|
|||||||
@ -22,11 +22,13 @@ type OwnProps = {
|
|||||||
patternIcon?: ApiSticker;
|
patternIcon?: ApiSticker;
|
||||||
patternColor?: number;
|
patternColor?: number;
|
||||||
patternSize?: number;
|
patternSize?: number;
|
||||||
|
maxRadius?: number;
|
||||||
centerEmptiness?: number;
|
centerEmptiness?: number;
|
||||||
ringsCount?: number;
|
ringsCount?: number;
|
||||||
ovalFactor?: number;
|
ovalFactor?: number;
|
||||||
withLinearGradient?: boolean;
|
withLinearGradient?: boolean;
|
||||||
className?: string;
|
className?: string;
|
||||||
|
canvasClassName?: string;
|
||||||
clearBottomSector?: boolean;
|
clearBottomSector?: boolean;
|
||||||
yPosition?: number;
|
yPosition?: number;
|
||||||
withAdaptiveHeight?: boolean;
|
withAdaptiveHeight?: boolean;
|
||||||
@ -35,7 +37,7 @@ type OwnProps = {
|
|||||||
const BASE_RING_ITEM_COUNT = 8;
|
const BASE_RING_ITEM_COUNT = 8;
|
||||||
const RING_INCREMENT = 0.5;
|
const RING_INCREMENT = 0.5;
|
||||||
const DEFAULT_CENTER_EMPTINESS = 0.1;
|
const DEFAULT_CENTER_EMPTINESS = 0.1;
|
||||||
const MAX_RADIUS = 0.42;
|
const DEFAULT_MAX_RADIUS = 0.42;
|
||||||
const MIN_SIZE = 4 * REM;
|
const MIN_SIZE = 4 * REM;
|
||||||
const DARK_LUMA_THRESHOLD = 255 * 0.2;
|
const DARK_LUMA_THRESHOLD = 255 * 0.2;
|
||||||
|
|
||||||
@ -50,9 +52,11 @@ const RadialPatternBackground = ({
|
|||||||
centerEmptiness = DEFAULT_CENTER_EMPTINESS,
|
centerEmptiness = DEFAULT_CENTER_EMPTINESS,
|
||||||
ringsCount = DEFAULT_RINGS_COUNT,
|
ringsCount = DEFAULT_RINGS_COUNT,
|
||||||
ovalFactor = DEFAULT_OVAL_FACTOR,
|
ovalFactor = DEFAULT_OVAL_FACTOR,
|
||||||
|
maxRadius = DEFAULT_MAX_RADIUS,
|
||||||
withLinearGradient,
|
withLinearGradient,
|
||||||
clearBottomSector,
|
clearBottomSector,
|
||||||
className,
|
className,
|
||||||
|
canvasClassName,
|
||||||
yPosition,
|
yPosition,
|
||||||
withAdaptiveHeight,
|
withAdaptiveHeight,
|
||||||
}: OwnProps) => {
|
}: OwnProps) => {
|
||||||
@ -78,7 +82,7 @@ const RadialPatternBackground = ({
|
|||||||
for (let ring = 1; ring <= ringsCount; ring++) {
|
for (let ring = 1; ring <= ringsCount; ring++) {
|
||||||
const ringItemCount = Math.floor(BASE_RING_ITEM_COUNT * (1 + (ring - 1) * RING_INCREMENT));
|
const ringItemCount = Math.floor(BASE_RING_ITEM_COUNT * (1 + (ring - 1) * RING_INCREMENT));
|
||||||
const ringProgress = ring / ringsCount;
|
const ringProgress = ring / ringsCount;
|
||||||
const ringRadius = centerEmptiness + (MAX_RADIUS - centerEmptiness) * ringProgress;
|
const ringRadius = centerEmptiness + (maxRadius - centerEmptiness) * ringProgress;
|
||||||
const angleShift = ring % 2 === 0 ? Math.PI / ringItemCount : 0;
|
const angleShift = ring % 2 === 0 ? Math.PI / ringItemCount : 0;
|
||||||
|
|
||||||
for (let i = 0; i < ringItemCount; i++) {
|
for (let i = 0; i < ringItemCount; i++) {
|
||||||
@ -100,7 +104,7 @@ const RadialPatternBackground = ({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return coordinates;
|
return coordinates;
|
||||||
}, [centerEmptiness, clearBottomSector, ovalFactor, ringsCount]);
|
}, [centerEmptiness, clearBottomSector, maxRadius, ovalFactor, ringsCount]);
|
||||||
|
|
||||||
useResizeObserver(containerRef, (entry) => {
|
useResizeObserver(containerRef, (entry) => {
|
||||||
setContainerSize({
|
setContainerSize({
|
||||||
@ -148,7 +152,7 @@ const RadialPatternBackground = ({
|
|||||||
ctx.globalCompositeOperation = 'source-in';
|
ctx.globalCompositeOperation = 'source-in';
|
||||||
ctx.fillRect(0, 0, width, height);
|
ctx.fillRect(0, 0, width, height);
|
||||||
|
|
||||||
const radialGradient = ctx.createRadialGradient(centerX, centerY, 0, centerX, centerY, width / 2);
|
const radialGradient = ctx.createRadialGradient(centerX, centerY, 0, centerX, centerY, width * maxRadius);
|
||||||
radialGradient.addColorStop(0, 'rgb(255 255 255 / 0.4)');
|
radialGradient.addColorStop(0, 'rgb(255 255 255 / 0.4)');
|
||||||
radialGradient.addColorStop(1, 'rgb(255 255 255 / 0.9)');
|
radialGradient.addColorStop(1, 'rgb(255 255 255 / 0.9)');
|
||||||
|
|
||||||
@ -200,7 +204,7 @@ const RadialPatternBackground = ({
|
|||||||
>
|
>
|
||||||
<canvas
|
<canvas
|
||||||
ref={canvasRef}
|
ref={canvasRef}
|
||||||
className={buildClassName(styles.canvas, emojiImage && styles.showing)}
|
className={buildClassName(styles.canvas, emojiImage && styles.showing, canvasClassName)}
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -62,7 +62,14 @@ const SettingsActiveSession: FC<OwnProps & StateProps> = ({
|
|||||||
function renderHeader() {
|
function renderHeader() {
|
||||||
return (
|
return (
|
||||||
<div className="modal-header-condensed" dir={lang.isRtl ? 'rtl' : undefined}>
|
<div className="modal-header-condensed" dir={lang.isRtl ? 'rtl' : undefined}>
|
||||||
<Button round color="translucent" size="smaller" ariaLabel={lang('Close')} onClick={onClose} iconName="close" />
|
<Button
|
||||||
|
round
|
||||||
|
color="translucent"
|
||||||
|
size="tiny"
|
||||||
|
ariaLabel={lang('Close')}
|
||||||
|
onClick={onClose}
|
||||||
|
iconName="close"
|
||||||
|
/>
|
||||||
<div className="modal-title">{lang('SessionPreviewTitle')}</div>
|
<div className="modal-title">{lang('SessionPreviewTitle')}</div>
|
||||||
<Button
|
<Button
|
||||||
color="danger"
|
color="danger"
|
||||||
|
|||||||
@ -51,7 +51,14 @@ const SettingsActiveWebsite: FC<OwnProps & StateProps> = ({
|
|||||||
function renderHeader() {
|
function renderHeader() {
|
||||||
return (
|
return (
|
||||||
<div className="modal-header-condensed" dir={lang.isRtl ? 'rtl' : undefined}>
|
<div className="modal-header-condensed" dir={lang.isRtl ? 'rtl' : undefined}>
|
||||||
<Button round color="translucent" size="smaller" ariaLabel={lang('Close')} onClick={onClose} iconName="close" />
|
<Button
|
||||||
|
round
|
||||||
|
color="translucent"
|
||||||
|
size="tiny"
|
||||||
|
ariaLabel={lang('Close')}
|
||||||
|
onClick={onClose}
|
||||||
|
iconName="close"
|
||||||
|
/>
|
||||||
<div className="modal-title">{lang('WebSessionsTitle')}</div>
|
<div className="modal-title">{lang('WebSessionsTitle')}</div>
|
||||||
<Button
|
<Button
|
||||||
color="danger"
|
color="danger"
|
||||||
|
|||||||
@ -689,17 +689,9 @@ const GiveawayModal: FC<OwnProps & StateProps> = ({
|
|||||||
isOpen={isOpen}
|
isOpen={isOpen}
|
||||||
dialogRef={dialogRef}
|
dialogRef={dialogRef}
|
||||||
onEnter={(dataPrepaidGiveaway || dataStarsPrepaidGiveaway) ? openConfirmModal : handleClick}
|
onEnter={(dataPrepaidGiveaway || dataStarsPrepaidGiveaway) ? openConfirmModal : handleClick}
|
||||||
|
hasAbsoluteCloseButton
|
||||||
>
|
>
|
||||||
<div className={buildClassName(styles.main, 'custom-scroll')} onScroll={handleScroll}>
|
<div className={buildClassName(styles.main, 'custom-scroll')} onScroll={handleScroll}>
|
||||||
<Button
|
|
||||||
round
|
|
||||||
size="smaller"
|
|
||||||
className={styles.closeButton}
|
|
||||||
color="translucent"
|
|
||||||
onClick={handleClose}
|
|
||||||
ariaLabel={lang('Close')}
|
|
||||||
iconName="close"
|
|
||||||
/>
|
|
||||||
<img className={styles.logo} src={PremiumLogo} alt="" draggable={false} />
|
<img className={styles.logo} src={PremiumLogo} alt="" draggable={false} />
|
||||||
<h2 className={styles.headerText}>
|
<h2 className={styles.headerText}>
|
||||||
{renderText(lang('BoostingBoostsViaGifts'))}
|
{renderText(lang('BoostingBoostsViaGifts'))}
|
||||||
|
|||||||
@ -17,8 +17,9 @@
|
|||||||
|
|
||||||
.back-button {
|
.back-button {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 2;
|
z-index: 3;
|
||||||
margin: -0.5rem;
|
top: 0.875rem;
|
||||||
|
left: 0.875rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.white-back-button {
|
.white-back-button {
|
||||||
|
|||||||
@ -227,7 +227,7 @@ const PremiumFeatureModal: FC<OwnProps> = ({
|
|||||||
<div className={styles.root}>
|
<div className={styles.root}>
|
||||||
<Button
|
<Button
|
||||||
round
|
round
|
||||||
size="smaller"
|
size="tiny"
|
||||||
className={buildClassName(styles.backButton, hasHeaderBackdrop && styles.whiteBackButton)}
|
className={buildClassName(styles.backButton, hasHeaderBackdrop && styles.whiteBackButton)}
|
||||||
color={hasHeaderBackdrop ? 'translucent-white' : 'translucent'}
|
color={hasHeaderBackdrop ? 'translucent-white' : 'translucent'}
|
||||||
onClick={onBack}
|
onClick={onBack}
|
||||||
|
|||||||
@ -103,8 +103,8 @@
|
|||||||
.close-button {
|
.close-button {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 3;
|
z-index: 3;
|
||||||
top: 0.5rem;
|
top: 0.875rem;
|
||||||
left: 0.5rem;
|
left: 0.875rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.premium-header-text {
|
.premium-header-text {
|
||||||
|
|||||||
@ -428,19 +428,11 @@ const PremiumMainModal: FC<OwnProps & StateProps> = ({
|
|||||||
onClose={closePremiumModal}
|
onClose={closePremiumModal}
|
||||||
isOpen={isOpen}
|
isOpen={isOpen}
|
||||||
dialogRef={dialogRef}
|
dialogRef={dialogRef}
|
||||||
|
hasAbsoluteCloseButton
|
||||||
>
|
>
|
||||||
<Transition name="slide" activeKey={currentSection ? 1 : 0} className={styles.transition}>
|
<Transition name="slide" activeKey={currentSection ? 1 : 0} className={styles.transition}>
|
||||||
{!currentSection ? (
|
{!currentSection ? (
|
||||||
<div className={buildClassName(styles.main, 'custom-scroll')} onScroll={handleScroll}>
|
<div className={buildClassName(styles.main, 'custom-scroll')} onScroll={handleScroll}>
|
||||||
<Button
|
|
||||||
round
|
|
||||||
size="smaller"
|
|
||||||
className={styles.closeButton}
|
|
||||||
color="translucent"
|
|
||||||
onClick={() => closePremiumModal()}
|
|
||||||
ariaLabel={oldLang('Close')}
|
|
||||||
iconName="close"
|
|
||||||
/>
|
|
||||||
{renderHeader()}
|
{renderHeader()}
|
||||||
{!isPremium && !isGift && renderSubscriptionOptions()}
|
{!isPremium && !isGift && renderSubscriptionOptions()}
|
||||||
<div className={buildClassName(styles.header, isHeaderHidden && styles.hiddenHeader)}>
|
<div className={buildClassName(styles.header, isHeaderHidden && styles.hiddenHeader)}>
|
||||||
|
|||||||
@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
color: #fff;
|
color: #fff;
|
||||||
|
|
||||||
background: var(--pattern-color);
|
background: var(--action-message-bg);
|
||||||
}
|
}
|
||||||
|
|
||||||
.explainer {
|
.explainer {
|
||||||
@ -33,7 +33,7 @@
|
|||||||
color: #fff;
|
color: #fff;
|
||||||
text-wrap: balance;
|
text-wrap: balance;
|
||||||
|
|
||||||
background: var(--pattern-color);
|
background: var(--action-message-bg);
|
||||||
}
|
}
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
|
|||||||
@ -1,6 +1,4 @@
|
|||||||
.MessageList {
|
.MessageList {
|
||||||
--action-message-bg: var(--pattern-color);
|
|
||||||
|
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
|||||||
@ -218,18 +218,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
&.with-notch::before {
|
&.with-notch::before {
|
||||||
opacity: 1;
|
opacity: 0.75;
|
||||||
}
|
}
|
||||||
|
|
||||||
html.theme-dark &::before {
|
html.theme-dark &::before {
|
||||||
background:
|
background: var(--action-message-bg);
|
||||||
linear-gradient(
|
|
||||||
90deg,
|
|
||||||
rgba(127, 127, 127, 0) 0%,
|
|
||||||
rgba(127, 127, 127, 0.4) 2%,
|
|
||||||
rgba(127, 127, 127, 0.4) 98%,
|
|
||||||
rgba(127, 127, 127, 0) 100%
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 1276px) {
|
@media (min-width: 1276px) {
|
||||||
|
|||||||
@ -30,6 +30,7 @@ import {
|
|||||||
isUserRightBanned,
|
isUserRightBanned,
|
||||||
} from '../../global/helpers';
|
} from '../../global/helpers';
|
||||||
import {
|
import {
|
||||||
|
selectActionMessageBg,
|
||||||
selectBot,
|
selectBot,
|
||||||
selectCanAnimateInterface, selectCanAnimateRightColumn,
|
selectCanAnimateInterface, selectCanAnimateRightColumn,
|
||||||
selectChat,
|
selectChat,
|
||||||
@ -125,6 +126,7 @@ type StateProps = {
|
|||||||
customBackground?: string;
|
customBackground?: string;
|
||||||
backgroundColor?: string;
|
backgroundColor?: string;
|
||||||
patternColor?: string;
|
patternColor?: string;
|
||||||
|
actionMessageBg?: string;
|
||||||
isLeftColumnShown?: boolean;
|
isLeftColumnShown?: boolean;
|
||||||
isRightColumnShown?: boolean;
|
isRightColumnShown?: boolean;
|
||||||
isBackgroundBlurred?: boolean;
|
isBackgroundBlurred?: boolean;
|
||||||
@ -191,6 +193,7 @@ function MiddleColumn({
|
|||||||
theme,
|
theme,
|
||||||
backgroundColor,
|
backgroundColor,
|
||||||
patternColor,
|
patternColor,
|
||||||
|
actionMessageBg,
|
||||||
isLeftColumnShown,
|
isLeftColumnShown,
|
||||||
isRightColumnShown,
|
isRightColumnShown,
|
||||||
isBackgroundBlurred,
|
isBackgroundBlurred,
|
||||||
@ -486,7 +489,7 @@ function MiddleColumn({
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Prepare filter beforehand to avoid flickering
|
// Prepare filter beforehand to avoid flickering
|
||||||
useFluidBackgroundFilter(patternColor);
|
useFluidBackgroundFilter(actionMessageBg);
|
||||||
|
|
||||||
const isMessagingDisabled = Boolean(
|
const isMessagingDisabled = Boolean(
|
||||||
!isPinnedMessageList && !isSavedDialog && !renderingCanPost && !renderingCanRestartBot && !renderingCanStartBot
|
!isPinnedMessageList && !isSavedDialog && !renderingCanPost && !renderingCanRestartBot && !renderingCanStartBot
|
||||||
@ -760,6 +763,7 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
customBackground,
|
customBackground,
|
||||||
backgroundColor,
|
backgroundColor,
|
||||||
patternColor,
|
patternColor,
|
||||||
|
actionMessageBg: selectActionMessageBg(global),
|
||||||
isLeftColumnShown,
|
isLeftColumnShown,
|
||||||
isRightColumnShown: selectIsRightColumnShown(global, isMobile),
|
isRightColumnShown: selectIsRightColumnShown(global, isMobile),
|
||||||
isBackgroundBlurred,
|
isBackgroundBlurred,
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
color: #fff;
|
color: #fff;
|
||||||
|
|
||||||
background: var(--pattern-color);
|
background: var(--action-message-bg);
|
||||||
|
|
||||||
&[dir="rtl"] {
|
&[dir="rtl"] {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
|
|||||||
@ -5,15 +5,6 @@
|
|||||||
--hover-color-reaction: var(--color-message-reaction-hover);
|
--hover-color-reaction: var(--color-message-reaction-hover);
|
||||||
--accent-color: var(--color-primary);
|
--accent-color: var(--color-primary);
|
||||||
|
|
||||||
.modal-header {
|
|
||||||
padding-top: 0.5rem;
|
|
||||||
padding-inline: 0.5rem;
|
|
||||||
|
|
||||||
.modal-title {
|
|
||||||
margin-inline: 1.3125rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.modal-dialog {
|
.modal-dialog {
|
||||||
overflow: clip;
|
overflow: clip;
|
||||||
}
|
}
|
||||||
@ -46,20 +37,27 @@
|
|||||||
gap: 0.4375rem;
|
gap: 0.4375rem;
|
||||||
|
|
||||||
width: auto;
|
width: auto;
|
||||||
min-height: 2.25rem;
|
min-height: 2rem;
|
||||||
padding-inline: 0.4375rem;
|
margin-top: 0;
|
||||||
|
padding-inline: 0.75rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.reaction-filter-emoji {
|
.reaction-filter-emoji {
|
||||||
margin-inline-end: 0.25rem;
|
margin-inline-end: 0.25rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.not-chosen-button {
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--hover-color-reaction) !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.reactor-list {
|
.reactor-list {
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
|
|
||||||
max-height: 100%;
|
max-height: 100%;
|
||||||
padding-top: 0.5rem;
|
padding-top: 0.25rem;
|
||||||
padding-inline: 0.5rem;
|
padding-inline: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import {
|
|||||||
import { getActions, getGlobal, withGlobal } from '../../global';
|
import { getActions, getGlobal, withGlobal } from '../../global';
|
||||||
|
|
||||||
import type { ApiAvailableReaction, ApiMessage, ApiReaction } from '../../api/types';
|
import type { ApiAvailableReaction, ApiMessage, ApiReaction } from '../../api/types';
|
||||||
|
import type { AnimationLevel } from '../../types';
|
||||||
import { LoadMoreDirection } from '../../types';
|
import { LoadMoreDirection } from '../../types';
|
||||||
|
|
||||||
import { getReactionKey, isSameReaction } from '../../global/helpers';
|
import { getReactionKey, isSameReaction } from '../../global/helpers';
|
||||||
@ -14,9 +15,11 @@ import {
|
|||||||
selectChatMessage,
|
selectChatMessage,
|
||||||
selectTabState,
|
selectTabState,
|
||||||
} from '../../global/selectors';
|
} from '../../global/selectors';
|
||||||
|
import { selectSharedSettings } from '../../global/selectors/sharedState';
|
||||||
import buildClassName from '../../util/buildClassName';
|
import buildClassName from '../../util/buildClassName';
|
||||||
import { formatDateAtTime } from '../../util/dates/dateFormat';
|
import { formatDateAtTime } from '../../util/dates/dateFormat';
|
||||||
import { unique } from '../../util/iteratees';
|
import { unique } from '../../util/iteratees';
|
||||||
|
import { resolveTransitionName } from '../../util/resolveTransitionName';
|
||||||
import { formatIntegerCompact } from '../../util/textFormat';
|
import { formatIntegerCompact } from '../../util/textFormat';
|
||||||
import { REM } from '../common/helpers/mediaDimensions';
|
import { REM } from '../common/helpers/mediaDimensions';
|
||||||
|
|
||||||
@ -52,6 +55,7 @@ export type StateProps = Pick<ApiMessage, 'reactors' | 'reactions' | 'seenByDate
|
|||||||
chatId?: string;
|
chatId?: string;
|
||||||
messageId?: number;
|
messageId?: number;
|
||||||
availableReactions?: ApiAvailableReaction[];
|
availableReactions?: ApiAvailableReaction[];
|
||||||
|
animationLevel: AnimationLevel;
|
||||||
};
|
};
|
||||||
|
|
||||||
const DEFAULT_REACTION_SIZE = 1.5 * REM;
|
const DEFAULT_REACTION_SIZE = 1.5 * REM;
|
||||||
@ -64,6 +68,7 @@ const ReactorListModal: FC<OwnProps & StateProps> = ({
|
|||||||
messageId,
|
messageId,
|
||||||
seenByDates,
|
seenByDates,
|
||||||
availableReactions,
|
availableReactions,
|
||||||
|
animationLevel,
|
||||||
}) => {
|
}) => {
|
||||||
const {
|
const {
|
||||||
loadReactors,
|
loadReactors,
|
||||||
@ -169,6 +174,7 @@ const ReactorListModal: FC<OwnProps & StateProps> = ({
|
|||||||
className="ReactorListModal narrow"
|
className="ReactorListModal narrow"
|
||||||
title={oldLang('Reactions')}
|
title={oldLang('Reactions')}
|
||||||
onCloseAnimationEnd={handleCloseAnimationEnd}
|
onCloseAnimationEnd={handleCloseAnimationEnd}
|
||||||
|
isCondensedHeader
|
||||||
hasCloseButton
|
hasCloseButton
|
||||||
>
|
>
|
||||||
{canShowFilters && (
|
{canShowFilters && (
|
||||||
@ -182,6 +188,7 @@ const ReactorListModal: FC<OwnProps & StateProps> = ({
|
|||||||
size="tiny"
|
size="tiny"
|
||||||
ripple
|
ripple
|
||||||
iconName="heart"
|
iconName="heart"
|
||||||
|
className={chosenTab ? 'not-chosen-button' : undefined}
|
||||||
pill
|
pill
|
||||||
fluid
|
fluid
|
||||||
onClick={() => setChosenTab(undefined)}
|
onClick={() => setChosenTab(undefined)}
|
||||||
@ -191,10 +198,12 @@ const ReactorListModal: FC<OwnProps & StateProps> = ({
|
|||||||
{allReactions.map((reaction) => {
|
{allReactions.map((reaction) => {
|
||||||
const count = reactions?.results
|
const count = reactions?.results
|
||||||
.find((reactionsCount) => isSameReaction(reactionsCount.reaction, reaction))?.count;
|
.find((reactionsCount) => isSameReaction(reactionsCount.reaction, reaction))?.count;
|
||||||
|
const isChosen = isSameReaction(chosenTab, reaction);
|
||||||
return (
|
return (
|
||||||
<Button
|
<Button
|
||||||
key={getReactionKey(reaction)}
|
key={getReactionKey(reaction)}
|
||||||
color={isSameReaction(chosenTab, reaction) ? 'primary' : 'adaptive'}
|
className={!isChosen ? 'not-chosen-button' : undefined}
|
||||||
|
color={isChosen ? 'primary' : 'adaptive'}
|
||||||
size="tiny"
|
size="tiny"
|
||||||
pill
|
pill
|
||||||
fluid
|
fluid
|
||||||
@ -219,7 +228,10 @@ const ReactorListModal: FC<OwnProps & StateProps> = ({
|
|||||||
dir={lang.isRtl ? 'rtl' : undefined}
|
dir={lang.isRtl ? 'rtl' : undefined}
|
||||||
className="reactor-list-wrapper"
|
className="reactor-list-wrapper"
|
||||||
>
|
>
|
||||||
<Transition activeKey={contentActiveKey} name="slide">
|
<Transition
|
||||||
|
activeKey={contentActiveKey}
|
||||||
|
name={resolveTransitionName('slide', animationLevel, undefined, lang.isRtl)}
|
||||||
|
>
|
||||||
{viewportIds?.length ? (
|
{viewportIds?.length ? (
|
||||||
<InfiniteScroll
|
<InfiniteScroll
|
||||||
className="reactor-list custom-scroll"
|
className="reactor-list custom-scroll"
|
||||||
@ -305,6 +317,7 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
reactors: message?.reactors,
|
reactors: message?.reactors,
|
||||||
seenByDates: message?.seenByDates,
|
seenByDates: message?.seenByDates,
|
||||||
availableReactions: global.reactions.availableReactions,
|
availableReactions: global.reactions.availableReactions,
|
||||||
|
animationLevel: selectSharedSettings(global).animationLevel,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
)(ReactorListModal));
|
)(ReactorListModal));
|
||||||
|
|||||||
@ -17,12 +17,12 @@
|
|||||||
color: var(--color-white);
|
color: var(--color-white);
|
||||||
text-transform: none;
|
text-transform: none;
|
||||||
|
|
||||||
background: var(--pattern-color);
|
background: var(--action-message-bg);
|
||||||
|
|
||||||
transition: filter 150ms ease-in-out;
|
transition: filter 150ms ease-in-out;
|
||||||
|
|
||||||
&:not(.disabled):not(:disabled):hover {
|
&:not(.disabled):not(:disabled):hover {
|
||||||
background-color: var(--pattern-color);
|
background-color: var(--action-message-bg);
|
||||||
filter: brightness(1.05);
|
filter: brightness(1.05);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -37,7 +37,7 @@
|
|||||||
padding: 1.0625rem 0;
|
padding: 1.0625rem 0;
|
||||||
border-radius: 1.5rem;
|
border-radius: 1.5rem;
|
||||||
|
|
||||||
background: var(--pattern-color);
|
background: var(--action-message-bg);
|
||||||
|
|
||||||
&[dir="rtl"] {
|
&[dir="rtl"] {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
|
|||||||
@ -451,7 +451,7 @@ const AttachmentModal: FC<OwnProps & StateProps> = ({
|
|||||||
<Button
|
<Button
|
||||||
round
|
round
|
||||||
ripple={!isMobile}
|
ripple={!isMobile}
|
||||||
size="smaller"
|
size="tiny"
|
||||||
color="translucent"
|
color="translucent"
|
||||||
className={isMenuOpen ? 'active' : ''}
|
className={isMenuOpen ? 'active' : ''}
|
||||||
onClick={onTrigger}
|
onClick={onTrigger}
|
||||||
@ -534,7 +534,7 @@ const AttachmentModal: FC<OwnProps & StateProps> = ({
|
|||||||
<Button
|
<Button
|
||||||
round
|
round
|
||||||
color="translucent"
|
color="translucent"
|
||||||
size="smaller"
|
size="tiny"
|
||||||
ariaLabel="Cancel attachments"
|
ariaLabel="Cancel attachments"
|
||||||
onClick={onClear}
|
onClick={onClear}
|
||||||
iconName="close"
|
iconName="close"
|
||||||
|
|||||||
@ -251,7 +251,7 @@ const PollModal = ({
|
|||||||
<Button
|
<Button
|
||||||
round
|
round
|
||||||
color="translucent"
|
color="translucent"
|
||||||
size="smaller"
|
size="tiny"
|
||||||
ariaLabel="Cancel poll creation"
|
ariaLabel="Cancel poll creation"
|
||||||
onClick={onClear}
|
onClick={onClear}
|
||||||
iconName="close"
|
iconName="close"
|
||||||
|
|||||||
@ -293,7 +293,7 @@ const ToDoListModal = ({
|
|||||||
<Button
|
<Button
|
||||||
round
|
round
|
||||||
color="translucent"
|
color="translucent"
|
||||||
size="smaller"
|
size="tiny"
|
||||||
ariaLabel={lang('AriaToDoCancel')}
|
ariaLabel={lang('AriaToDoCancel')}
|
||||||
onClick={onClear}
|
onClick={onClear}
|
||||||
iconName="close"
|
iconName="close"
|
||||||
@ -301,7 +301,7 @@ const ToDoListModal = ({
|
|||||||
<div className="modal-title">{lang(modalTitle)}</div>
|
<div className="modal-title">{lang(modalTitle)}</div>
|
||||||
<Button
|
<Button
|
||||||
color="primary"
|
color="primary"
|
||||||
size="smaller"
|
size="tiny"
|
||||||
className="modal-action-button"
|
className="modal-action-button"
|
||||||
onClick={handleCreate}
|
onClick={handleCreate}
|
||||||
>
|
>
|
||||||
|
|||||||
@ -17,6 +17,7 @@ import { MESSAGE_APPEARANCE_DELAY } from '../../../config';
|
|||||||
import { getMessageHtmlId } from '../../../global/helpers';
|
import { getMessageHtmlId } from '../../../global/helpers';
|
||||||
import { getMessageReplyInfo } from '../../../global/helpers/replies';
|
import { getMessageReplyInfo } from '../../../global/helpers/replies';
|
||||||
import {
|
import {
|
||||||
|
selectActionMessageBg,
|
||||||
selectChat,
|
selectChat,
|
||||||
selectChatMessage,
|
selectChatMessage,
|
||||||
selectIsCurrentUserFrozen,
|
selectIsCurrentUserFrozen,
|
||||||
@ -25,7 +26,6 @@ import {
|
|||||||
selectIsMessageFocused,
|
selectIsMessageFocused,
|
||||||
selectSender,
|
selectSender,
|
||||||
selectTabState,
|
selectTabState,
|
||||||
selectTheme,
|
|
||||||
} from '../../../global/selectors';
|
} from '../../../global/selectors';
|
||||||
import { IS_TAURI } from '../../../util/browser/globalEnvironment';
|
import { IS_TAURI } from '../../../util/browser/globalEnvironment';
|
||||||
import { IS_ANDROID, IS_FLUID_BACKGROUND_SUPPORTED } from '../../../util/browser/windowEnvironment';
|
import { IS_ANDROID, IS_FLUID_BACKGROUND_SUPPORTED } from '../../../util/browser/windowEnvironment';
|
||||||
@ -83,7 +83,7 @@ type StateProps = {
|
|||||||
focusDirection?: FocusDirection;
|
focusDirection?: FocusDirection;
|
||||||
noFocusHighlight?: boolean;
|
noFocusHighlight?: boolean;
|
||||||
replyMessage?: ApiMessage;
|
replyMessage?: ApiMessage;
|
||||||
patternColor?: string;
|
actionMessageBg?: string;
|
||||||
isCurrentUserPremium?: boolean;
|
isCurrentUserPremium?: boolean;
|
||||||
isInSelectMode?: boolean;
|
isInSelectMode?: boolean;
|
||||||
hasUnreadReaction?: boolean;
|
hasUnreadReaction?: boolean;
|
||||||
@ -118,7 +118,7 @@ const ActionMessage = ({
|
|||||||
focusDirection,
|
focusDirection,
|
||||||
noFocusHighlight,
|
noFocusHighlight,
|
||||||
replyMessage,
|
replyMessage,
|
||||||
patternColor,
|
actionMessageBg,
|
||||||
isCurrentUserPremium,
|
isCurrentUserPremium,
|
||||||
isInSelectMode,
|
isInSelectMode,
|
||||||
hasUnreadReaction,
|
hasUnreadReaction,
|
||||||
@ -245,7 +245,7 @@ const ActionMessage = ({
|
|||||||
}
|
}
|
||||||
}, [action.type, id, isLocal, memoFirstUnreadIdRef]);
|
}, [action.type, id, isLocal, memoFirstUnreadIdRef]);
|
||||||
|
|
||||||
const fluidBackgroundStyle = useFluidBackgroundFilter(isFluidMultiline ? patternColor : undefined);
|
const fluidBackgroundStyle = useFluidBackgroundFilter(isFluidMultiline ? actionMessageBg : undefined);
|
||||||
|
|
||||||
const handleClick = useLastCallback(() => {
|
const handleClick = useLastCallback(() => {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
@ -515,7 +515,6 @@ const ActionMessage = ({
|
|||||||
export default memo(withGlobal<OwnProps>(
|
export default memo(withGlobal<OwnProps>(
|
||||||
(global, { message, threadId }): Complete<StateProps> => {
|
(global, { message, threadId }): Complete<StateProps> => {
|
||||||
const tabState = selectTabState(global);
|
const tabState = selectTabState(global);
|
||||||
const { themes } = global.settings;
|
|
||||||
|
|
||||||
const chat = selectChat(global, message.chatId);
|
const chat = selectChat(global, message.chatId);
|
||||||
|
|
||||||
@ -549,7 +548,7 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
isInsideTopic,
|
isInsideTopic,
|
||||||
replyMessage,
|
replyMessage,
|
||||||
isInSelectMode: selectIsInSelectMode(global),
|
isInSelectMode: selectIsInSelectMode(global),
|
||||||
patternColor: themes[selectTheme(global)]?.patternColor,
|
actionMessageBg: selectActionMessageBg(global),
|
||||||
hasUnreadReaction,
|
hasUnreadReaction,
|
||||||
isResizingContainer,
|
isResizingContainer,
|
||||||
scrollTargetPosition,
|
scrollTargetPosition,
|
||||||
|
|||||||
@ -19,13 +19,13 @@
|
|||||||
font-weight: var(--font-weight-medium);
|
font-weight: var(--font-weight-medium);
|
||||||
text-transform: none;
|
text-transform: none;
|
||||||
|
|
||||||
background: var(--pattern-color);
|
background: var(--action-message-bg);
|
||||||
|
|
||||||
transition: background-color 150ms, color 150ms, backdrop-filter 150ms, filter 150ms;
|
transition: background-color 150ms, color 150ms, backdrop-filter 150ms, filter 150ms;
|
||||||
|
|
||||||
&:hover,
|
&:hover,
|
||||||
&:focus {
|
&:focus {
|
||||||
background: var(--pattern-color) !important;
|
background: var(--action-message-bg) !important;
|
||||||
backdrop-filter: brightness(115%);
|
backdrop-filter: brightness(115%);
|
||||||
|
|
||||||
@supports not (backdrop-filter: brightness(115%)) {
|
@supports not (backdrop-filter: brightness(115%)) {
|
||||||
|
|||||||
@ -719,7 +719,7 @@
|
|||||||
border-radius: 1.125rem;
|
border-radius: 1.125rem;
|
||||||
|
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
background-color: var(--pattern-color);
|
background-color: var(--action-message-bg);
|
||||||
|
|
||||||
transition: opacity 150ms;
|
transition: opacity 150ms;
|
||||||
|
|
||||||
@ -729,6 +729,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.message-action-button {
|
.message-action-button {
|
||||||
|
width: 2.25rem;
|
||||||
|
height: 2.25rem;
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1820,7 +1820,6 @@ const Message = ({
|
|||||||
className="message-action-button"
|
className="message-action-button"
|
||||||
color="translucent-white"
|
color="translucent-white"
|
||||||
round
|
round
|
||||||
size="tiny"
|
|
||||||
ariaLabel={oldLang('lng_context_forward_msg')}
|
ariaLabel={oldLang('lng_context_forward_msg')}
|
||||||
onClick={isLastInDocumentGroup ? handleGroupForward : handleForward}
|
onClick={isLastInDocumentGroup ? handleGroupForward : handleForward}
|
||||||
iconName="share-filled"
|
iconName="share-filled"
|
||||||
@ -1831,7 +1830,6 @@ const Message = ({
|
|||||||
className="message-action-button"
|
className="message-action-button"
|
||||||
color="translucent-white"
|
color="translucent-white"
|
||||||
round
|
round
|
||||||
size="tiny"
|
|
||||||
ariaLabel={lang('FocusMessage')}
|
ariaLabel={lang('FocusMessage')}
|
||||||
onClick={isPinnedList ? handleFocus : handleFocusForwarded}
|
onClick={isPinnedList ? handleFocus : handleFocusForwarded}
|
||||||
iconName="arrow-right"
|
iconName="arrow-right"
|
||||||
|
|||||||
@ -137,7 +137,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.Message .custom-shape & {
|
.Message .custom-shape & {
|
||||||
background: var(--pattern-color);
|
background: var(--action-message-bg);
|
||||||
}
|
}
|
||||||
|
|
||||||
.voice &[dir="rtl"] {
|
.voice &[dir="rtl"] {
|
||||||
|
|||||||
@ -98,10 +98,10 @@
|
|||||||
height: 1.3125rem;
|
height: 1.3125rem;
|
||||||
border-radius: 0.5rem;
|
border-radius: 0.5rem;
|
||||||
|
|
||||||
background: var(--pattern-color);
|
background: var(--action-message-bg);
|
||||||
&:hover {
|
&:hover {
|
||||||
opacity: 0.8;
|
opacity: 0.8;
|
||||||
background: var(--pattern-color) !important;
|
background: var(--action-message-bg) !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -298,7 +298,6 @@ const SponsoredMessage: FC<OwnProps & StateProps> = ({
|
|||||||
className="message-action-button"
|
className="message-action-button"
|
||||||
color="translucent-white"
|
color="translucent-white"
|
||||||
round
|
round
|
||||||
size="tiny"
|
|
||||||
iconName="close"
|
iconName="close"
|
||||||
iconClassName="sponsored-action-icon"
|
iconClassName="sponsored-action-icon"
|
||||||
ariaLabel={lang('Close')}
|
ariaLabel={lang('Close')}
|
||||||
@ -309,7 +308,6 @@ const SponsoredMessage: FC<OwnProps & StateProps> = ({
|
|||||||
className="message-action-button"
|
className="message-action-button"
|
||||||
color="translucent-white"
|
color="translucent-white"
|
||||||
round
|
round
|
||||||
size="tiny"
|
|
||||||
iconName="more"
|
iconName="more"
|
||||||
iconClassName="sponsored-action-icon"
|
iconClassName="sponsored-action-icon"
|
||||||
ariaLabel={lang('More')}
|
ariaLabel={lang('More')}
|
||||||
|
|||||||
@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
font-size: calc(var(--message-text-size, 1rem) - 0.125rem);
|
font-size: calc(var(--message-text-size, 1rem) - 0.125rem);
|
||||||
|
|
||||||
background-color: var(--pattern-color);
|
background-color: var(--action-message-bg);
|
||||||
box-shadow: 0 1px 2px var(--color-default-shadow);
|
box-shadow: 0 1px 2px var(--color-default-shadow);
|
||||||
|
|
||||||
@media (max-width: 600px) {
|
@media (max-width: 600px) {
|
||||||
|
|||||||
@ -101,16 +101,8 @@ const CollectibleInfoModal: FC<OwnProps & StateProps> = ({
|
|||||||
isSlim
|
isSlim
|
||||||
contentClassName={styles.content}
|
contentClassName={styles.content}
|
||||||
onClose={closeCollectibleInfoModal}
|
onClose={closeCollectibleInfoModal}
|
||||||
|
hasAbsoluteCloseButton
|
||||||
>
|
>
|
||||||
<Button
|
|
||||||
round
|
|
||||||
color="translucent"
|
|
||||||
size="smaller"
|
|
||||||
className={styles.closeButton}
|
|
||||||
ariaLabel={lang('Close')}
|
|
||||||
onClick={handleClose}
|
|
||||||
iconName="close"
|
|
||||||
/>
|
|
||||||
<div className={styles.icon}>
|
<div className={styles.icon}>
|
||||||
<AnimatedIconWithPreview
|
<AnimatedIconWithPreview
|
||||||
tgsUrl={isUsername ? LOCAL_TGS_URLS.Mention : LOCAL_TGS_URLS.Fragment}
|
tgsUrl={isUsername ? LOCAL_TGS_URLS.Mention : LOCAL_TGS_URLS.Fragment}
|
||||||
|
|||||||
@ -1,10 +1,45 @@
|
|||||||
.root :global(.modal-dialog) {
|
.root {
|
||||||
overflow: hidden;
|
|
||||||
width: 26.25rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.title {
|
:global(.modal-dialog) {
|
||||||
font-weight: var(--font-weight-medium);
|
overflow: hidden;
|
||||||
|
width: 26.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(.modal-content) {
|
||||||
|
padding-bottom: 1rem;
|
||||||
|
padding-inline: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(.ListItem) {
|
||||||
|
:global(.ListItem-button) {
|
||||||
|
align-items: flex-start;
|
||||||
|
padding-inline: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(.ListItem-main-icon) {
|
||||||
|
margin-top: 0.875rem;
|
||||||
|
margin-right: 0.875rem;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
color: var(--accent-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(.multiline-item .subtitle) {
|
||||||
|
margin-top: 0.125rem;
|
||||||
|
font-size: 1rem;
|
||||||
|
line-height: 1.375rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(.Checkbox-main) {
|
||||||
|
&::before,
|
||||||
|
&::after {
|
||||||
|
left: 2.25rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(.Checkbox) {
|
||||||
|
padding-inline-start: 4.5rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.secondary {
|
.secondary {
|
||||||
@ -32,11 +67,6 @@
|
|||||||
background: var(--premium-gradient);
|
background: var(--premium-gradient);
|
||||||
}
|
}
|
||||||
|
|
||||||
.listItemIcon {
|
|
||||||
font-size: 1.875rem !important;
|
|
||||||
color: var(--accent-color) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -45,6 +75,15 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.listItem {
|
||||||
|
padding-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.listItemTitle {
|
||||||
|
font-size: 1rem;
|
||||||
|
font-weight: var(--font-weight-medium);
|
||||||
|
}
|
||||||
|
|
||||||
.separator {
|
.separator {
|
||||||
width: calc(100% + 2rem); // Hack to cover modal paddings
|
width: calc(100% + 2rem); // Hack to cover modal paddings
|
||||||
margin-block: 1rem;
|
margin-block: 1rem;
|
||||||
|
|||||||
@ -67,9 +67,9 @@ const TableAboutModal = ({
|
|||||||
isStatic
|
isStatic
|
||||||
multiline
|
multiline
|
||||||
icon={icon}
|
icon={icon}
|
||||||
iconClassName={styles.listItemIcon}
|
className={styles.listItem}
|
||||||
>
|
>
|
||||||
<span className={buildClassName('title', styles.title)}>{title}</span>
|
<span className={buildClassName('title', styles.listItemTitle)}>{title}</span>
|
||||||
<span className="subtitle">{subtitle}</span>
|
<span className="subtitle">{subtitle}</span>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -28,7 +28,7 @@
|
|||||||
gap: 1px;
|
gap: 1px;
|
||||||
|
|
||||||
border: 1px solid var(--color-borders);
|
border: 1px solid var(--color-borders);
|
||||||
border-radius: 0.3125rem;
|
border-radius: 1rem;
|
||||||
|
|
||||||
background-color: var(--color-borders);
|
background-color: var(--color-borders);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,13 +4,13 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin-top: 0.5rem;
|
margin-top: 0.125rem;
|
||||||
margin-bottom: 0.75rem;
|
margin-bottom: 0.25rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
padding-top: 0.5rem;
|
padding-top: 0.25rem;
|
||||||
font-size: 1.25rem;
|
font-size: 1.5rem;
|
||||||
font-weight: var(--font-weight-medium);
|
font-weight: var(--font-weight-medium);
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,6 +29,8 @@ type StateProps = {
|
|||||||
freezeUntilDate?: number;
|
freezeUntilDate?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const ICON_SIZE = 130;
|
||||||
|
|
||||||
const FrozenAccountModal = ({
|
const FrozenAccountModal = ({
|
||||||
modal,
|
modal,
|
||||||
freezeUntilDate,
|
freezeUntilDate,
|
||||||
@ -58,7 +60,7 @@ const FrozenAccountModal = ({
|
|||||||
return (
|
return (
|
||||||
<div className={styles.header}>
|
<div className={styles.header}>
|
||||||
<AnimatedIconWithPreview
|
<AnimatedIconWithPreview
|
||||||
size={160}
|
size={ICON_SIZE}
|
||||||
tgsUrl={LOCAL_TGS_URLS.BannedDuck}
|
tgsUrl={LOCAL_TGS_URLS.BannedDuck}
|
||||||
noLoop
|
noLoop
|
||||||
/>
|
/>
|
||||||
@ -76,14 +78,12 @@ const FrozenAccountModal = ({
|
|||||||
<Button
|
<Button
|
||||||
className={styles.buttonAppeal}
|
className={styles.buttonAppeal}
|
||||||
onClick={handleAppeal}
|
onClick={handleAppeal}
|
||||||
noForcedUpperCase
|
|
||||||
>
|
>
|
||||||
{lang('ButtonAppeal')}
|
{lang('ButtonAppeal')}
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
isText
|
isText
|
||||||
onClick={handleClose}
|
onClick={handleClose}
|
||||||
noForcedUpperCase
|
|
||||||
>
|
>
|
||||||
{lang('ButtonUnderstood')}
|
{lang('ButtonUnderstood')}
|
||||||
</Button>
|
</Button>
|
||||||
@ -123,7 +123,6 @@ const FrozenAccountModal = ({
|
|||||||
header={header}
|
header={header}
|
||||||
listItemData={listItemData}
|
listItemData={listItemData}
|
||||||
footer={footer}
|
footer={footer}
|
||||||
hasBackdrop
|
|
||||||
onClose={handleClose}
|
onClose={handleClose}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -83,7 +83,7 @@ function GiftItemPremium({
|
|||||||
<div className={styles.description}>
|
<div className={styles.description}>
|
||||||
{lang('PremiumGiftDescription')}
|
{lang('PremiumGiftDescription')}
|
||||||
</div>
|
</div>
|
||||||
<Button className={styles.buy} nonInteractive size="tiny" pill fluid>
|
<Button className={styles.buy} color="adaptive" nonInteractive size="tiny" pill fluid>
|
||||||
{formatCurrencyAsString(amount, currency)}
|
{formatCurrencyAsString(amount, currency)}
|
||||||
</Button>
|
</Button>
|
||||||
{optionByStars && (
|
{optionByStars && (
|
||||||
|
|||||||
@ -119,7 +119,11 @@
|
|||||||
|
|
||||||
background: var(--color-background);
|
background: var(--color-background);
|
||||||
/* stylelint-disable-next-line plugin/no-low-performance-animation-properties */
|
/* stylelint-disable-next-line plugin/no-low-performance-animation-properties */
|
||||||
transition: height 0.25s ease-out, transform 0.25s ease-out;
|
transition: height 0.25s ease-out, transform 0.25s ease-out, border-color 0.2s ease;
|
||||||
|
|
||||||
|
&.noBorder {
|
||||||
|
border-bottom-color: transparent;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.resaleHeader {
|
.resaleHeader {
|
||||||
@ -174,8 +178,8 @@
|
|||||||
.closeButton {
|
.closeButton {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 3;
|
z-index: 3;
|
||||||
top: 0.375rem;
|
top: 0.875rem;
|
||||||
left: 0.375rem;
|
left: 0.875rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.balance {
|
.balance {
|
||||||
@ -209,9 +213,12 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.logoBackground {
|
.logoBackground {
|
||||||
|
pointer-events: none;
|
||||||
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
transform: translateX(-50%);
|
transform: translateX(-50%);
|
||||||
|
|
||||||
height: 7rem;
|
height: 7rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import type { FC } from '@teact';
|
import type { FC } from '@teact';
|
||||||
import {
|
import {
|
||||||
memo, useEffect, useMemo, useRef, useState,
|
memo, useEffect,
|
||||||
} from '@teact';
|
useMemo, useRef, useState } from '@teact';
|
||||||
import type React from '../../../lib/teact/teact';
|
import type React from '../../../lib/teact/teact';
|
||||||
import { getActions, withGlobal } from '../../../global';
|
import { getActions, withGlobal } from '../../../global';
|
||||||
|
|
||||||
@ -24,8 +24,10 @@ import { selectTabState } from '../../../global/selectors';
|
|||||||
import { selectPeer, selectUserFullInfo } from '../../../global/selectors';
|
import { selectPeer, selectUserFullInfo } from '../../../global/selectors';
|
||||||
import buildClassName from '../../../util/buildClassName';
|
import buildClassName from '../../../util/buildClassName';
|
||||||
import { throttle } from '../../../util/schedulers';
|
import { throttle } from '../../../util/schedulers';
|
||||||
|
import { REM } from '../../common/helpers/mediaDimensions';
|
||||||
|
|
||||||
import useCurrentOrPrev from '../../../hooks/useCurrentOrPrev';
|
import useCurrentOrPrev from '../../../hooks/useCurrentOrPrev';
|
||||||
|
import useFlag from '../../../hooks/useFlag';
|
||||||
import { useIntersectionObserver } from '../../../hooks/useIntersectionObserver';
|
import { useIntersectionObserver } from '../../../hooks/useIntersectionObserver';
|
||||||
import useLang from '../../../hooks/useLang';
|
import useLang from '../../../hooks/useLang';
|
||||||
import useLastCallback from '../../../hooks/useLastCallback';
|
import useLastCallback from '../../../hooks/useLastCallback';
|
||||||
@ -74,6 +76,7 @@ const AVATAR_SIZE = 100;
|
|||||||
const INTERSECTION_THROTTLE = 200;
|
const INTERSECTION_THROTTLE = 200;
|
||||||
const SCROLL_THROTTLE = 200;
|
const SCROLL_THROTTLE = 200;
|
||||||
const AVATAR_SPARKLES_CENTER_SHIFT = [0, -50] as const;
|
const AVATAR_SPARKLES_CENTER_SHIFT = [0, -50] as const;
|
||||||
|
const CATEGORY_LIST_STICKY_TOP = 3.5 * REM;
|
||||||
|
|
||||||
const runThrottledForScroll = throttle((cb) => cb(), SCROLL_THROTTLE, true);
|
const runThrottledForScroll = throttle((cb) => cb(), SCROLL_THROTTLE, true);
|
||||||
|
|
||||||
@ -105,6 +108,7 @@ const GiftModal: FC<OwnProps & StateProps> = ({
|
|||||||
const dialogRef = useRef<HTMLDivElement>();
|
const dialogRef = useRef<HTMLDivElement>();
|
||||||
const transitionRef = useRef<HTMLDivElement>();
|
const transitionRef = useRef<HTMLDivElement>();
|
||||||
const giftHeaderRef = useRef<HTMLHeadingElement>();
|
const giftHeaderRef = useRef<HTMLHeadingElement>();
|
||||||
|
const categoryListRef = useRef<HTMLDivElement>();
|
||||||
|
|
||||||
const scrollerRef = useRef<HTMLDivElement>();
|
const scrollerRef = useRef<HTMLDivElement>();
|
||||||
|
|
||||||
@ -118,8 +122,8 @@ const GiftModal: FC<OwnProps & StateProps> = ({
|
|||||||
const [shouldShowMainScreenHeader, setShouldShowMainScreenHeader] = useState(false);
|
const [shouldShowMainScreenHeader, setShouldShowMainScreenHeader] = useState(false);
|
||||||
const [isMainScreenHeaderForStarGifts, setIsMainScreenHeaderForStarGifts] = useState(false);
|
const [isMainScreenHeaderForStarGifts, setIsMainScreenHeaderForStarGifts] = useState(false);
|
||||||
const [isGiftScreenHeaderForStarGifts, setIsGiftScreenHeaderForStarGifts] = useState(false);
|
const [isGiftScreenHeaderForStarGifts, setIsGiftScreenHeaderForStarGifts] = useState(false);
|
||||||
|
|
||||||
const [selectedCategory, setSelectedCategory] = useState<StarGiftCategory>('all');
|
const [selectedCategory, setSelectedCategory] = useState<StarGiftCategory>('all');
|
||||||
|
const [isCategoryListPinned, pinCategoryList, unpinCategoryList] = useFlag(false);
|
||||||
const triggerSparklesRef = useRef<(() => void) | undefined>();
|
const triggerSparklesRef = useRef<(() => void) | undefined>();
|
||||||
|
|
||||||
const areAllGiftsDisallowed = useMemo(() => {
|
const areAllGiftsDisallowed = useMemo(() => {
|
||||||
@ -207,6 +211,17 @@ const GiftModal: FC<OwnProps & StateProps> = ({
|
|||||||
const { top: transitionTop } = transitionRef.current.getBoundingClientRect();
|
const { top: transitionTop } = transitionRef.current.getBoundingClientRect();
|
||||||
setIsMainScreenHeaderForStarGifts(headerTop - transitionTop <= 0);
|
setIsMainScreenHeaderForStarGifts(headerTop - transitionTop <= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (categoryListRef.current && scrollerRef.current) {
|
||||||
|
const { top: listTop } = categoryListRef.current.getBoundingClientRect();
|
||||||
|
const { top: scrollerTop } = scrollerRef.current.getBoundingClientRect();
|
||||||
|
const isPinned = listTop - scrollerTop <= CATEGORY_LIST_STICKY_TOP;
|
||||||
|
if (isPinned) {
|
||||||
|
pinCategoryList();
|
||||||
|
} else {
|
||||||
|
unpinCategoryList();
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -463,10 +478,12 @@ const GiftModal: FC<OwnProps & StateProps> = ({
|
|||||||
{renderStarGiftsHeader()}
|
{renderStarGiftsHeader()}
|
||||||
{renderStarGiftsDescription()}
|
{renderStarGiftsDescription()}
|
||||||
<StarGiftCategoryList
|
<StarGiftCategoryList
|
||||||
|
ref={categoryListRef}
|
||||||
areUniqueStarGiftsDisallowed={areUniqueStarGiftsDisallowed}
|
areUniqueStarGiftsDisallowed={areUniqueStarGiftsDisallowed}
|
||||||
areLimitedStarGiftsDisallowed={areLimitedStarGiftsDisallowed}
|
areLimitedStarGiftsDisallowed={areLimitedStarGiftsDisallowed}
|
||||||
isSelf={isSelf}
|
isSelf={isSelf}
|
||||||
hasMyUnique={Boolean(myUniqueGiftIds?.length)}
|
hasMyUnique={Boolean(myUniqueGiftIds?.length)}
|
||||||
|
isPinned={isCategoryListPinned}
|
||||||
onCategoryChanged={onCategoryChanged}
|
onCategoryChanged={onCategoryChanged}
|
||||||
/>
|
/>
|
||||||
<Transition
|
<Transition
|
||||||
@ -537,7 +554,7 @@ const GiftModal: FC<OwnProps & StateProps> = ({
|
|||||||
className={styles.closeButton}
|
className={styles.closeButton}
|
||||||
round
|
round
|
||||||
color="translucent"
|
color="translucent"
|
||||||
size="smaller"
|
size="tiny"
|
||||||
onClick={handleCloseButtonClick}
|
onClick={handleCloseButtonClick}
|
||||||
ariaLabel={isBackButton ? oldLang('Common.Back') : oldLang('Common.Close')}
|
ariaLabel={isBackButton ? oldLang('Common.Back') : oldLang('Common.Close')}
|
||||||
>
|
>
|
||||||
@ -547,7 +564,8 @@ const GiftModal: FC<OwnProps & StateProps> = ({
|
|||||||
<div className={buildClassName(
|
<div className={buildClassName(
|
||||||
styles.header,
|
styles.header,
|
||||||
isResaleScreen && styles.resaleHeader,
|
isResaleScreen && styles.resaleHeader,
|
||||||
!shouldShowHeader && styles.hiddenHeader)}
|
!shouldShowHeader && styles.hiddenHeader,
|
||||||
|
isCategoryListPinned && styles.noBorder)}
|
||||||
>
|
>
|
||||||
<Transition
|
<Transition
|
||||||
name="slideVerticalFade"
|
name="slideVerticalFade"
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
@use '../../../styles/mixins';
|
|
||||||
|
|
||||||
.list {
|
.list {
|
||||||
|
position: sticky;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
|
top: 3.5rem;
|
||||||
|
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
overflow-y: hidden;
|
overflow-y: hidden;
|
||||||
@ -16,16 +16,21 @@
|
|||||||
margin-left: -0.5rem;
|
margin-left: -0.5rem;
|
||||||
padding-left: 0.5rem;
|
padding-left: 0.5rem;
|
||||||
padding-block: 0.25rem;
|
padding-block: 0.25rem;
|
||||||
|
border-bottom: 0.0625rem solid transparent;
|
||||||
|
|
||||||
font-size: 0.875rem;
|
font-size: 0.875rem;
|
||||||
|
|
||||||
background-color: var(--color-background);
|
background-color: var(--color-background);
|
||||||
|
|
||||||
|
transition: border-color 0.2s ease;
|
||||||
|
|
||||||
:global(html.theme-dark) & {
|
:global(html.theme-dark) & {
|
||||||
background-color: #181818;
|
background-color: #181818;
|
||||||
}
|
}
|
||||||
|
|
||||||
@include mixins.gradient-border-horizontal(0.5rem, 0.5rem);
|
&.pinned {
|
||||||
|
border-bottom-color: var(--color-borders);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.item-selected,
|
.item-selected,
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import type { ElementRef } from '../../../lib/teact/teact';
|
||||||
import {
|
import {
|
||||||
memo, useRef, useState,
|
memo, useRef, useState,
|
||||||
} from '../../../lib/teact/teact';
|
} from '../../../lib/teact/teact';
|
||||||
@ -13,10 +14,12 @@ import useLang from '../../../hooks/useLang';
|
|||||||
import styles from './StarGiftCategoryList.module.scss';
|
import styles from './StarGiftCategoryList.module.scss';
|
||||||
|
|
||||||
type OwnProps = {
|
type OwnProps = {
|
||||||
|
ref?: ElementRef<HTMLDivElement>;
|
||||||
areUniqueStarGiftsDisallowed?: boolean;
|
areUniqueStarGiftsDisallowed?: boolean;
|
||||||
areLimitedStarGiftsDisallowed?: boolean;
|
areLimitedStarGiftsDisallowed?: boolean;
|
||||||
isSelf?: boolean;
|
isSelf?: boolean;
|
||||||
hasMyUnique?: boolean;
|
hasMyUnique?: boolean;
|
||||||
|
isPinned?: boolean;
|
||||||
onCategoryChanged: (category: StarGiftCategory) => void;
|
onCategoryChanged: (category: StarGiftCategory) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -25,14 +28,19 @@ type StateProps = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const StarGiftCategoryList = ({
|
const StarGiftCategoryList = ({
|
||||||
|
ref: externalRef,
|
||||||
idsByCategory,
|
idsByCategory,
|
||||||
onCategoryChanged,
|
onCategoryChanged,
|
||||||
areUniqueStarGiftsDisallowed,
|
areUniqueStarGiftsDisallowed,
|
||||||
areLimitedStarGiftsDisallowed,
|
areLimitedStarGiftsDisallowed,
|
||||||
isSelf,
|
isSelf,
|
||||||
hasMyUnique,
|
hasMyUnique,
|
||||||
|
isPinned,
|
||||||
}: StateProps & OwnProps) => {
|
}: StateProps & OwnProps) => {
|
||||||
const ref = useRef<HTMLDivElement>();
|
let ref = useRef<HTMLDivElement>();
|
||||||
|
if (externalRef) {
|
||||||
|
ref = externalRef;
|
||||||
|
}
|
||||||
|
|
||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
|
|
||||||
@ -42,9 +50,7 @@ const StarGiftCategoryList = ({
|
|||||||
|
|
||||||
function handleItemClick(category: StarGiftCategory) {
|
function handleItemClick(category: StarGiftCategory) {
|
||||||
setSelectedCategory(category);
|
setSelectedCategory(category);
|
||||||
onCategoryChanged(
|
onCategoryChanged(category);
|
||||||
category,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderCategoryName(category: StarGiftCategory) {
|
function renderCategoryName(category: StarGiftCategory) {
|
||||||
@ -71,7 +77,7 @@ const StarGiftCategoryList = ({
|
|||||||
useHorizontalScroll(ref, undefined, true);
|
useHorizontalScroll(ref, undefined, true);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div ref={ref} className={buildClassName(styles.list, 'no-scrollbar')}>
|
<div ref={ref} className={buildClassName(styles.list, isPinned && styles.pinned, 'no-scrollbar')}>
|
||||||
{renderCategoryItem('all')}
|
{renderCategoryItem('all')}
|
||||||
{!areUniqueStarGiftsDisallowed && !isSelf && hasMyUnique && renderCategoryItem('myUnique')}
|
{!areUniqueStarGiftsDisallowed && !isSelf && hasMyUnique && renderCategoryItem('myUnique')}
|
||||||
{(!areUniqueStarGiftsDisallowed || !areLimitedStarGiftsDisallowed)
|
{(!areUniqueStarGiftsDisallowed || !areLimitedStarGiftsDisallowed)
|
||||||
|
|||||||
@ -12,15 +12,22 @@
|
|||||||
padding-bottom: 1rem;
|
padding-bottom: 1rem;
|
||||||
|
|
||||||
&.withManageButtons {
|
&.withManageButtons {
|
||||||
--_height: 18.5rem;
|
--_height: 19.25rem;
|
||||||
|
|
||||||
.sticker {
|
.sticker {
|
||||||
margin-top: 2.5rem;
|
margin-top: 2.625rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
:global {
|
||||||
|
canvas {
|
||||||
|
transform-origin: center 32%;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
:global {
|
:global {
|
||||||
canvas {
|
canvas {
|
||||||
|
transform-origin: center 45%;
|
||||||
transition: 250ms transform;
|
transition: 250ms transform;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -48,7 +55,7 @@
|
|||||||
.radialPattern {
|
.radialPattern {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: -1;
|
z-index: -1;
|
||||||
inset: 0;
|
inset: -5%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.amount {
|
.amount {
|
||||||
@ -65,7 +72,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.sticker {
|
.sticker {
|
||||||
margin-top: 2rem;
|
margin-top: 2.875rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.transition {
|
.transition {
|
||||||
@ -83,14 +90,16 @@
|
|||||||
|
|
||||||
.title {
|
.title {
|
||||||
margin-top: auto;
|
margin-top: auto;
|
||||||
font-size: 1.25rem;
|
|
||||||
|
font-size: 1.5rem;
|
||||||
|
font-weight: var(--font-weight-semibold);
|
||||||
|
line-height: 1.75rem;
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.subtitle {
|
.subtitle {
|
||||||
max-width: 85%;
|
font-size: 1rem;
|
||||||
|
line-height: 1.375rem;
|
||||||
font-size: 0.875rem;
|
|
||||||
text-align: center;
|
text-align: center;
|
||||||
text-wrap: balance;
|
text-wrap: balance;
|
||||||
|
|
||||||
|
|||||||
@ -17,6 +17,7 @@ import buildStyle from '../../../util/buildStyle';
|
|||||||
import { REM } from '../../common/helpers/mediaDimensions.ts';
|
import { REM } from '../../common/helpers/mediaDimensions.ts';
|
||||||
|
|
||||||
import { useTransitionActiveKey } from '../../../hooks/animations/useTransitionActiveKey';
|
import { useTransitionActiveKey } from '../../../hooks/animations/useTransitionActiveKey';
|
||||||
|
import useAppLayout from '../../../hooks/useAppLayout';
|
||||||
import useFlag from '../../../hooks/useFlag';
|
import useFlag from '../../../hooks/useFlag';
|
||||||
import useLang from '../../../hooks/useLang';
|
import useLang from '../../../hooks/useLang';
|
||||||
|
|
||||||
@ -60,6 +61,8 @@ const UniqueGiftHeader = ({
|
|||||||
openChat,
|
openChat,
|
||||||
} = getActions();
|
} = getActions();
|
||||||
|
|
||||||
|
const { isMobile } = useAppLayout();
|
||||||
|
|
||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
const [isGiftHover, markGiftHover, unmarkGiftHover] = useFlag(false);
|
const [isGiftHover, markGiftHover, unmarkGiftHover] = useFlag(false);
|
||||||
const activeKey = useTransitionActiveKey([modelAttribute, backdropAttribute, patternAttribute]);
|
const activeKey = useTransitionActiveKey([modelAttribute, backdropAttribute, patternAttribute]);
|
||||||
@ -71,16 +74,20 @@ const UniqueGiftHeader = ({
|
|||||||
return (
|
return (
|
||||||
<RadialPatternBackground
|
<RadialPatternBackground
|
||||||
className={styles.radialPattern}
|
className={styles.radialPattern}
|
||||||
|
canvasClassName={styles.radialPatternCanvas}
|
||||||
backgroundColors={backdropColors}
|
backgroundColors={backdropColors}
|
||||||
patternIcon={patternAttribute.sticker}
|
patternIcon={patternAttribute.sticker}
|
||||||
yPosition={6.5 * REM}
|
yPosition={7.5 * REM}
|
||||||
|
maxRadius={0.26}
|
||||||
|
patternSize={isMobile ? 14 : 16}
|
||||||
|
ovalFactor={1.2}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}, [backdropAttribute, patternAttribute]);
|
}, [backdropAttribute, patternAttribute, isMobile]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={buildClassName(styles.root,
|
<div className={buildClassName(styles.root,
|
||||||
isGiftHover && 'interactive-gift',
|
'interactive-gift',
|
||||||
showManageButtons && styles.withManageButtons,
|
showManageButtons && styles.withManageButtons,
|
||||||
className)}
|
className)}
|
||||||
>
|
>
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
gap: 0.5rem;
|
gap: 0.5rem;
|
||||||
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin-top: 1rem;
|
margin-top: 0.375rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.manageButton {
|
.manageButton {
|
||||||
|
|||||||
@ -63,31 +63,44 @@
|
|||||||
backdrop-filter: blur(0.5rem);
|
backdrop-filter: blur(0.5rem);
|
||||||
}
|
}
|
||||||
|
|
||||||
.headerButton,
|
.moreMenuButton {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 1;
|
||||||
|
top: 0.875rem;
|
||||||
|
right: 0.875rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.closeButton {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 1;
|
||||||
|
top: 0.875rem;
|
||||||
|
left: 0.875rem;
|
||||||
|
}
|
||||||
|
|
||||||
.giftResalePriceContainer {
|
.giftResalePriceContainer {
|
||||||
pointer-events: auto;
|
pointer-events: auto;
|
||||||
|
|
||||||
|
position: absolute;
|
||||||
|
top: 0.875rem;
|
||||||
|
right: 3.25rem;
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|
||||||
width: fit-content;
|
width: fit-content;
|
||||||
height: 1.75rem;
|
height: 1.875rem;
|
||||||
padding: 0.25rem;
|
padding: 0.25rem;
|
||||||
padding-inline: 0.625rem;
|
padding-inline: 0.625rem;
|
||||||
border-radius: 1rem;
|
border-radius: 1rem;
|
||||||
|
|
||||||
font-size: 1rem;
|
font-size: 0.875rem;
|
||||||
font-weight: var(--font-weight-medium);
|
font-weight: var(--font-weight-medium);
|
||||||
color: white;
|
color: white;
|
||||||
|
|
||||||
background-color: rgba(0, 0, 0, 0.2);
|
background-color: rgba(255, 255, 255, 0.1);
|
||||||
outline: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.giftResalePriceContainer {
|
|
||||||
font-size: 0.75rem;
|
|
||||||
backdrop-filter: blur(25px);
|
backdrop-filter: blur(25px);
|
||||||
|
outline: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.starAmountIcon,
|
.starAmountIcon,
|
||||||
@ -137,6 +150,24 @@
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.footerHint {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
font-size: 0.75rem;
|
||||||
|
line-height: 1.125rem;
|
||||||
|
color: var(--color-white);
|
||||||
|
text-align: center;
|
||||||
|
text-transform: none;
|
||||||
|
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.buyButton {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
.unknown {
|
.unknown {
|
||||||
margin-inline-start: 0.25rem;
|
margin-inline-start: 0.25rem;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -108,7 +108,7 @@ const GiftInfoModal = ({
|
|||||||
const [isConfirmModalOpen, setIsConfirmModalOpen] = useState<boolean>(false);
|
const [isConfirmModalOpen, setIsConfirmModalOpen] = useState<boolean>(false);
|
||||||
const [shouldPayInTon, setShouldPayInTon] = useState<boolean>(false);
|
const [shouldPayInTon, setShouldPayInTon] = useState<boolean>(false);
|
||||||
|
|
||||||
const splitButtonRef = useRef<HTMLDivElement>();
|
const moreButtonRef = useRef<HTMLButtonElement>();
|
||||||
const menuRef = useRef<HTMLDivElement>();
|
const menuRef = useRef<HTMLDivElement>();
|
||||||
const uniqueGiftHeaderRef = useRef<HTMLDivElement>();
|
const uniqueGiftHeaderRef = useRef<HTMLDivElement>();
|
||||||
const {
|
const {
|
||||||
@ -117,7 +117,7 @@ const GiftInfoModal = ({
|
|||||||
handleContextMenu,
|
handleContextMenu,
|
||||||
handleContextMenuClose,
|
handleContextMenuClose,
|
||||||
handleContextMenuHide,
|
handleContextMenuHide,
|
||||||
} = useContextMenuHandlers(splitButtonRef);
|
} = useContextMenuHandlers(moreButtonRef);
|
||||||
|
|
||||||
const handleSymbolClick = useLastCallback(() => {
|
const handleSymbolClick = useLastCallback(() => {
|
||||||
if (!gift || !giftAttributes?.pattern) return;
|
if (!gift || !giftAttributes?.pattern) return;
|
||||||
@ -245,6 +245,9 @@ const GiftInfoModal = ({
|
|||||||
|
|
||||||
const resellPrice = getResalePrice();
|
const resellPrice = getResalePrice();
|
||||||
const confirmPrice = getResalePrice(shouldPayInTon);
|
const confirmPrice = getResalePrice(shouldPayInTon);
|
||||||
|
const resellPriceInStars = resellPrice?.currency === TON_CURRENCY_CODE && isGiftUnique
|
||||||
|
? gift.resellPrice?.find((amount) => amount.currency === STARS_CURRENCY_CODE)
|
||||||
|
: undefined;
|
||||||
const canBuyGift = !isSelfUnique && gift?.type === 'starGiftUnique'
|
const canBuyGift = !isSelfUnique && gift?.type === 'starGiftUnique'
|
||||||
&& gift.ownerId !== currentUserId && Boolean(resellPrice);
|
&& gift.ownerId !== currentUserId && Boolean(resellPrice);
|
||||||
|
|
||||||
@ -330,37 +333,24 @@ const GiftInfoModal = ({
|
|||||||
return gift && getGiftAttributes(gift);
|
return gift && getGiftAttributes(gift);
|
||||||
}, [gift]);
|
}, [gift]);
|
||||||
|
|
||||||
const SettingsMenuButton = useMemo(() => {
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
className={buildClassName(
|
|
||||||
styles.headerButton,
|
|
||||||
styles.left,
|
|
||||||
)}
|
|
||||||
tabIndex={0}
|
|
||||||
role="button"
|
|
||||||
aria-haspopup="menu"
|
|
||||||
aria-label={lang('AriaMoreButton')}
|
|
||||||
onContextMenu={handleContextMenu}
|
|
||||||
onClick={handleContextMenu}
|
|
||||||
>
|
|
||||||
<Icon
|
|
||||||
name="more"
|
|
||||||
className={styles.icon}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}, [lang, handleContextMenu]);
|
|
||||||
|
|
||||||
const renderFooterButton = useLastCallback(() => {
|
const renderFooterButton = useLastCallback(() => {
|
||||||
if (canBuyGift) {
|
if (canBuyGift) {
|
||||||
return (
|
return (
|
||||||
<Button noForcedUpperCase onClick={handleBuyGift}>
|
<Button className={styles.buyButton} onClick={handleBuyGift}>
|
||||||
{lang('ButtonBuyGift', {
|
<div>
|
||||||
stars: resellPrice?.currency === TON_CURRENCY_CODE
|
{lang('ButtonBuyGift', {
|
||||||
? formatTonAsIcon(lang, resellPrice.amount, { shouldConvertFromNanos: true })
|
stars: resellPrice?.currency === TON_CURRENCY_CODE
|
||||||
: formatStarsAsIcon(lang, resellPrice?.amount, { asFont: true }),
|
? formatTonAsIcon(lang, resellPrice.amount, { shouldConvertFromNanos: true })
|
||||||
}, { withNodes: true })}
|
: formatStarsAsIcon(lang, resellPrice?.amount, { asFont: true }),
|
||||||
|
}, { withNodes: true })}
|
||||||
|
</div>
|
||||||
|
{resellPrice?.currency === TON_CURRENCY_CODE && Boolean(resellPriceInStars) && (
|
||||||
|
<div className={styles.footerHint}>
|
||||||
|
{lang('GiftBuyEqualsTo', {
|
||||||
|
stars: formatStarsAsIcon(lang, resellPriceInStars.amount, { asFont: true }),
|
||||||
|
}, { withNodes: true })}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</Button>
|
</Button>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -536,6 +526,30 @@ const GiftInfoModal = ({
|
|||||||
<div
|
<div
|
||||||
className={styles.modalHeader}
|
className={styles.modalHeader}
|
||||||
>
|
>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
className={styles.closeButton}
|
||||||
|
round
|
||||||
|
color="translucent-white"
|
||||||
|
size="tiny"
|
||||||
|
iconName="close"
|
||||||
|
ariaLabel={lang('Close')}
|
||||||
|
onClick={handleClose}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
ref={moreButtonRef}
|
||||||
|
className={styles.moreMenuButton}
|
||||||
|
round
|
||||||
|
color="translucent-white"
|
||||||
|
size="tiny"
|
||||||
|
iconName="more"
|
||||||
|
aria-haspopup="menu"
|
||||||
|
aria-label={lang('AriaMoreButton')}
|
||||||
|
onContextMenu={handleContextMenu}
|
||||||
|
onClick={handleContextMenu}
|
||||||
|
/>
|
||||||
|
|
||||||
{Boolean(resellPrice?.amount) && (
|
{Boolean(resellPrice?.amount) && (
|
||||||
<div className={styles.giftResalePriceContainer}>
|
<div className={styles.giftResalePriceContainer}>
|
||||||
{resellPrice.currency === TON_CURRENCY_CODE
|
{resellPrice.currency === TON_CURRENCY_CODE
|
||||||
@ -549,28 +563,6 @@ const GiftInfoModal = ({
|
|||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<div className={styles.headerSplitButton} ref={splitButtonRef}>
|
|
||||||
{SettingsMenuButton}
|
|
||||||
<div
|
|
||||||
className={buildClassName(
|
|
||||||
styles.headerButton,
|
|
||||||
styles.right,
|
|
||||||
)}
|
|
||||||
tabIndex={0}
|
|
||||||
role="button"
|
|
||||||
aria-haspopup="menu"
|
|
||||||
aria-label={lang('Close')}
|
|
||||||
onClick={handleClose}
|
|
||||||
>
|
|
||||||
<Icon
|
|
||||||
name="close"
|
|
||||||
className={buildClassName(
|
|
||||||
styles.icon,
|
|
||||||
styles.moreIcon,
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -883,13 +875,14 @@ const GiftInfoModal = ({
|
|||||||
typeGift, savedGift, renderingTargetPeer, giftSticker, lang,
|
typeGift, savedGift, renderingTargetPeer, giftSticker, lang,
|
||||||
canManage, hasConvertOption, isSender, oldLang, tonExplorerUrl,
|
canManage, hasConvertOption, isSender, oldLang, tonExplorerUrl,
|
||||||
gift, giftAttributes, renderFooterButton, isTargetChat,
|
gift, giftAttributes, renderFooterButton, isTargetChat,
|
||||||
SettingsMenuButton, isGiftUnique, saleDateInfo,
|
isGiftUnique, saleDateInfo,
|
||||||
canBuyGift, giftOwnerTitle, resellPrice, giftSubtitle,
|
canBuyGift, giftOwnerTitle, resellPrice, giftSubtitle,
|
||||||
releasedByPeer, handleSymbolClick, handleBackdropClick, handleModelClick,
|
releasedByPeer, handleSymbolClick, handleBackdropClick, handleModelClick,
|
||||||
|
handleContextMenu,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const getRootElement = useLastCallback(() => uniqueGiftHeaderRef.current);
|
const getRootElement = useLastCallback(() => uniqueGiftHeaderRef.current);
|
||||||
const getTriggerElement = useLastCallback(() => splitButtonRef.current);
|
const getTriggerElement = useLastCallback(() => moreButtonRef.current);
|
||||||
const getMenuElement = useLastCallback(() => menuRef.current);
|
const getMenuElement = useLastCallback(() => menuRef.current);
|
||||||
const getLayout = useLastCallback(() => ({ withPortal: true }));
|
const getLayout = useLastCallback(() => ({ withPortal: true }));
|
||||||
|
|
||||||
|
|||||||
@ -28,7 +28,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.avatar {
|
.avatar {
|
||||||
margin-top: 2rem;
|
margin-top: 2.375rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.userTitle {
|
.userTitle {
|
||||||
@ -36,7 +36,7 @@
|
|||||||
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin-top: auto;
|
margin-top: auto;
|
||||||
padding-top: 1rem;
|
padding-top: 1.75rem;
|
||||||
|
|
||||||
font-size: 1.25rem;
|
font-size: 1.25rem;
|
||||||
color: white;
|
color: white;
|
||||||
|
|||||||
@ -11,6 +11,7 @@ import buildClassName from '../../../../util/buildClassName';
|
|||||||
import buildStyle from '../../../../util/buildStyle';
|
import buildStyle from '../../../../util/buildStyle';
|
||||||
import { REM } from '../../../common/helpers/mediaDimensions';
|
import { REM } from '../../../common/helpers/mediaDimensions';
|
||||||
|
|
||||||
|
import useAppLayout from '../../../../hooks/useAppLayout';
|
||||||
import useCurrentOrPrev from '../../../../hooks/useCurrentOrPrev';
|
import useCurrentOrPrev from '../../../../hooks/useCurrentOrPrev';
|
||||||
import useLang from '../../../../hooks/useLang';
|
import useLang from '../../../../hooks/useLang';
|
||||||
import useLastCallback from '../../../../hooks/useLastCallback';
|
import useLastCallback from '../../../../hooks/useLastCallback';
|
||||||
@ -34,6 +35,8 @@ type StateProps = {
|
|||||||
isCurrentUserPremium?: boolean;
|
isCurrentUserPremium?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const AVATAR_SIZE = 7 * REM;
|
||||||
|
|
||||||
const GiftStatusInfoModal = ({
|
const GiftStatusInfoModal = ({
|
||||||
modal,
|
modal,
|
||||||
currentUser,
|
currentUser,
|
||||||
@ -44,6 +47,8 @@ const GiftStatusInfoModal = ({
|
|||||||
setEmojiStatus,
|
setEmojiStatus,
|
||||||
} = getActions();
|
} = getActions();
|
||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
|
const { isMobile } = useAppLayout();
|
||||||
|
|
||||||
const isOpen = Boolean(modal);
|
const isOpen = Boolean(modal);
|
||||||
const renderingModal = useCurrentOrPrev(modal);
|
const renderingModal = useCurrentOrPrev(modal);
|
||||||
|
|
||||||
@ -74,10 +79,13 @@ const GiftStatusInfoModal = ({
|
|||||||
className={styles.radialPattern}
|
className={styles.radialPattern}
|
||||||
backgroundColors={backdropColors}
|
backgroundColors={backdropColors}
|
||||||
patternIcon={patternIcon.customEmoji}
|
patternIcon={patternIcon.customEmoji}
|
||||||
yPosition={6.5 * REM}
|
yPosition={6.875 * REM}
|
||||||
|
maxRadius={0.31}
|
||||||
|
patternSize={isMobile ? 13 : 15}
|
||||||
|
ovalFactor={1}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}, [emojiStatus, isOpen, patternIcon]);
|
}, [emojiStatus, isOpen, isMobile, patternIcon]);
|
||||||
|
|
||||||
const mockPeerWithStatus = useMemo(() => {
|
const mockPeerWithStatus = useMemo(() => {
|
||||||
return {
|
return {
|
||||||
@ -95,7 +103,7 @@ const GiftStatusInfoModal = ({
|
|||||||
>
|
>
|
||||||
|
|
||||||
{radialPatternBackdrop}
|
{radialPatternBackdrop}
|
||||||
<Avatar peer={mockPeerWithStatus} size="jumbo" className={styles.avatar} />
|
<Avatar peer={mockPeerWithStatus} size={AVATAR_SIZE} className={styles.avatar} />
|
||||||
<FullNameTitle
|
<FullNameTitle
|
||||||
peer={mockPeerWithStatus}
|
peer={mockPeerWithStatus}
|
||||||
className={styles.userTitle}
|
className={styles.userTitle}
|
||||||
|
|||||||
@ -1,33 +1,3 @@
|
|||||||
.content {
|
|
||||||
:global(.ListItem-main-icon) {
|
|
||||||
margin-top: 0.6875rem !important;
|
|
||||||
margin-right: 0.625rem !important;
|
|
||||||
font-size: 1.875rem !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
:global(.ListItem-button) {
|
|
||||||
align-items: flex-start;
|
|
||||||
padding-inline: 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
:global(.modal-content) {
|
|
||||||
padding-bottom: 1rem;
|
|
||||||
padding-inline: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
:global(.ListItem) {
|
|
||||||
padding-bottom: 0.5rem;
|
|
||||||
|
|
||||||
:global(.title) {
|
|
||||||
font-size: 0.9375rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
:global(.subtitle) {
|
|
||||||
margin-top: 0.125rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.header {
|
.header {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding-top: 0;
|
padding-top: 0;
|
||||||
@ -77,17 +47,13 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.ratingProgress {
|
.ratingProgress {
|
||||||
margin: 4.5rem auto 1.5rem;
|
margin: 4.75rem auto 1.5rem;
|
||||||
|
|
||||||
&.withPreview {
|
&.withPreview {
|
||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.subtitle {
|
|
||||||
line-height: 1.375rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.footer {
|
.footer {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-self: stretch;
|
align-self: stretch;
|
||||||
|
|||||||
@ -193,19 +193,19 @@ const ProfileRatingModal = ({
|
|||||||
|
|
||||||
const listItemData = [
|
const listItemData = [
|
||||||
['closed-gift', lang('RatingGiftsFromTelegram'), (
|
['closed-gift', lang('RatingGiftsFromTelegram'), (
|
||||||
<span className={styles.subtitle}>
|
<span>
|
||||||
{renderBadge('added')}
|
{renderBadge('added')}
|
||||||
{lang('RatingGiftsFromTelegramDesc')}
|
{lang('RatingGiftsFromTelegramDesc')}
|
||||||
</span>
|
</span>
|
||||||
)],
|
)],
|
||||||
['user-stars', lang('RatingGiftsAndPostsFromUsers'), (
|
['user-stars', lang('RatingGiftsAndPostsFromUsers'), (
|
||||||
<span className={styles.subtitle}>
|
<span>
|
||||||
{renderBadge('added')}
|
{renderBadge('added')}
|
||||||
{lang('RatingGiftsAndPostsFromUsersDesc')}
|
{lang('RatingGiftsAndPostsFromUsersDesc')}
|
||||||
</span>
|
</span>
|
||||||
)],
|
)],
|
||||||
['stars-refund', lang('RatingRefundsAndConversions'), (
|
['stars-refund', lang('RatingRefundsAndConversions'), (
|
||||||
<span className={styles.subtitle}>
|
<span>
|
||||||
{renderBadge('deducted')}
|
{renderBadge('deducted')}
|
||||||
{lang('RatingRefundsAndConversionsDesc')}
|
{lang('RatingRefundsAndConversionsDesc')}
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@ -21,8 +21,8 @@
|
|||||||
|
|
||||||
.closeButton {
|
.closeButton {
|
||||||
position: absolute !important;
|
position: absolute !important;
|
||||||
top: 0.5rem;
|
top: 0.875rem;
|
||||||
right: 0.5rem;
|
right: 0.875rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.markAsReadButton {
|
.markAsReadButton {
|
||||||
|
|||||||
@ -84,7 +84,7 @@ const QuickPreviewModalHeader: FC<OwnProps & StateProps> = ({
|
|||||||
<Button
|
<Button
|
||||||
round
|
round
|
||||||
color="translucent"
|
color="translucent"
|
||||||
size="smaller"
|
size="tiny"
|
||||||
ariaLabel={lang('Close')}
|
ariaLabel={lang('Close')}
|
||||||
onClick={onClose}
|
onClick={onClose}
|
||||||
className={styles.closeButton}
|
className={styles.closeButton}
|
||||||
|
|||||||
@ -82,7 +82,7 @@ const ReportAdModal = ({
|
|||||||
<Button
|
<Button
|
||||||
round
|
round
|
||||||
color="translucent"
|
color="translucent"
|
||||||
size="smaller"
|
size="tiny"
|
||||||
ariaLabel={lang(renderingDepth ? 'Back' : 'Close')}
|
ariaLabel={lang(renderingDepth ? 'Back' : 'Close')}
|
||||||
onClick={handleBackClick}
|
onClick={handleBackClick}
|
||||||
iconName={renderingDepth ? 'arrow-left' : 'close'}
|
iconName={renderingDepth ? 'arrow-left' : 'close'}
|
||||||
|
|||||||
@ -86,7 +86,7 @@ const ReportModal = ({
|
|||||||
<Button
|
<Button
|
||||||
round
|
round
|
||||||
color="translucent"
|
color="translucent"
|
||||||
size="smaller"
|
size="tiny"
|
||||||
ariaLabel={lang('Back')}
|
ariaLabel={lang('Back')}
|
||||||
onClick={handleBackClick}
|
onClick={handleBackClick}
|
||||||
iconName="arrow-left"
|
iconName="arrow-left"
|
||||||
@ -95,7 +95,7 @@ const ReportModal = ({
|
|||||||
<Button
|
<Button
|
||||||
round
|
round
|
||||||
color="translucent"
|
color="translucent"
|
||||||
size="smaller"
|
size="tiny"
|
||||||
ariaLabel={lang('Close')}
|
ariaLabel={lang('Close')}
|
||||||
onClick={handleCloseClick}
|
onClick={handleCloseClick}
|
||||||
iconName="close"
|
iconName="close"
|
||||||
|
|||||||
@ -60,7 +60,6 @@
|
|||||||
color: var(--color-primary);
|
color: var(--color-primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
.hint,
|
|
||||||
.tos {
|
.tos {
|
||||||
padding: 0.5rem 1rem;
|
padding: 0.5rem 1rem;
|
||||||
padding-top: 0;
|
padding-top: 0;
|
||||||
@ -72,8 +71,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.hint {
|
.hint {
|
||||||
padding-block: 0.5rem;
|
margin-block: 0.25rem;
|
||||||
padding-inline: 1.5rem;
|
font-size: 0.9375rem;
|
||||||
|
color: var(--color-text-secondary);
|
||||||
}
|
}
|
||||||
|
|
||||||
.topUpButton,
|
.topUpButton,
|
||||||
@ -140,7 +140,7 @@
|
|||||||
|
|
||||||
background: var(--color-background);
|
background: var(--color-background);
|
||||||
|
|
||||||
transition: 0.25s ease-out transform;
|
transition: 0.25s ease-out transform, 0.25s ease-out border-bottom-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
.starHeaderText {
|
.starHeaderText {
|
||||||
@ -158,11 +158,15 @@
|
|||||||
transform: translateY(-100%);
|
transform: translateY(-100%);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.noSeparator {
|
||||||
|
border-bottom-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
.closeButton {
|
.closeButton {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 3;
|
z-index: 3;
|
||||||
top: 0.5rem;
|
top: 0.875rem;
|
||||||
left: 0.5rem;
|
left: 0.875rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.addStarsButton {
|
.addStarsButton {
|
||||||
@ -294,6 +298,7 @@
|
|||||||
// Disable tabs rounded corners
|
// Disable tabs rounded corners
|
||||||
--border-radius-messages-small: 0;
|
--border-radius-messages-small: 0;
|
||||||
|
|
||||||
|
z-index: 1;
|
||||||
top: 3.5rem;
|
top: 3.5rem;
|
||||||
padding-inline: 0;
|
padding-inline: 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { memo, useEffect, useMemo, useState } from '@teact';
|
import { memo, useEffect, useMemo, useRef, useState } from '@teact';
|
||||||
import { getActions, getGlobal, withGlobal } from '../../../global';
|
import { getActions, getGlobal, withGlobal } from '../../../global';
|
||||||
|
|
||||||
import type { ApiStarTopupOption } from '../../../api/types';
|
import type { ApiStarTopupOption } from '../../../api/types';
|
||||||
@ -18,6 +18,7 @@ import { selectSharedSettings } from '../../../global/selectors/sharedState.ts';
|
|||||||
import buildClassName from '../../../util/buildClassName';
|
import buildClassName from '../../../util/buildClassName';
|
||||||
import { convertCurrencyFromBaseUnit, convertTonToUsd, formatCurrencyAsString } from '../../../util/formatCurrency';
|
import { convertCurrencyFromBaseUnit, convertTonToUsd, formatCurrencyAsString } from '../../../util/formatCurrency';
|
||||||
import { resolveTransitionName } from '../../../util/resolveTransitionName.ts';
|
import { resolveTransitionName } from '../../../util/resolveTransitionName.ts';
|
||||||
|
import { REM } from '../../common/helpers/mediaDimensions';
|
||||||
import renderText from '../../common/helpers/renderText';
|
import renderText from '../../common/helpers/renderText';
|
||||||
|
|
||||||
import useFlag from '../../../hooks/useFlag';
|
import useFlag from '../../../hooks/useFlag';
|
||||||
@ -40,6 +41,7 @@ import StarsTransactionItem from './transaction/StarsTransactionItem';
|
|||||||
|
|
||||||
import styles from './StarsBalanceModal.module.scss';
|
import styles from './StarsBalanceModal.module.scss';
|
||||||
|
|
||||||
|
const HEADER_HEIGHT = 3.5 * REM;
|
||||||
const TRANSACTION_TYPES = ['all', 'inbound', 'outbound'] as const;
|
const TRANSACTION_TYPES = ['all', 'inbound', 'outbound'] as const;
|
||||||
const TRANSACTION_TABS_KEYS: RegularLangKey[] = [
|
const TRANSACTION_TABS_KEYS: RegularLangKey[] = [
|
||||||
'StarsTransactionsAll',
|
'StarsTransactionsAll',
|
||||||
@ -80,9 +82,12 @@ const StarsBalanceModal = ({
|
|||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
|
|
||||||
const [isHeaderHidden, setHeaderHidden] = useState(true);
|
const [isHeaderHidden, setHeaderHidden] = useState(true);
|
||||||
|
const [areTabsPinned, pinTabs, unpinTabs] = useFlag(false);
|
||||||
const [selectedTabIndex, setSelectedTabIndex] = useState(0);
|
const [selectedTabIndex, setSelectedTabIndex] = useState(0);
|
||||||
const [areBuyOptionsShown, showBuyOptions, hideBuyOptions] = useFlag();
|
const [areBuyOptionsShown, showBuyOptions, hideBuyOptions] = useFlag();
|
||||||
|
|
||||||
|
const tabsRef = useRef<HTMLDivElement>();
|
||||||
|
|
||||||
const isOpen = Boolean(modal && (starsBalanceState || tonBalanceState));
|
const isOpen = Boolean(modal && (starsBalanceState || tonBalanceState));
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@ -160,6 +165,7 @@ const StarsBalanceModal = ({
|
|||||||
setHeaderHidden(true);
|
setHeaderHidden(true);
|
||||||
setSelectedTabIndex(0);
|
setSelectedTabIndex(0);
|
||||||
hideBuyOptions();
|
hideBuyOptions();
|
||||||
|
unpinTabs();
|
||||||
}
|
}
|
||||||
}, [isOpen]);
|
}, [isOpen]);
|
||||||
|
|
||||||
@ -261,6 +267,12 @@ const StarsBalanceModal = ({
|
|||||||
>
|
>
|
||||||
{lang('ButtonTopUpViaFragment')}
|
{lang('ButtonTopUpViaFragment')}
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
|
{currency === TON_CURRENCY_CODE && (
|
||||||
|
<div className={styles.hint}>
|
||||||
|
{lang('TonModalHint')}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@ -269,6 +281,17 @@ const StarsBalanceModal = ({
|
|||||||
const { scrollTop } = e.currentTarget;
|
const { scrollTop } = e.currentTarget;
|
||||||
|
|
||||||
setHeaderHidden(scrollTop <= 150);
|
setHeaderHidden(scrollTop <= 150);
|
||||||
|
|
||||||
|
if (tabsRef.current) {
|
||||||
|
const { top: tabsTop } = tabsRef.current.getBoundingClientRect();
|
||||||
|
const { top: scrollerTop } = e.currentTarget.getBoundingClientRect();
|
||||||
|
const isPinned = tabsTop - scrollerTop <= HEADER_HEIGHT;
|
||||||
|
if (isPinned) {
|
||||||
|
pinTabs();
|
||||||
|
} else {
|
||||||
|
unpinTabs();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleLoadMoreTransactions = useLastCallback(() => {
|
const handleLoadMoreTransactions = useLastCallback(() => {
|
||||||
@ -305,19 +328,15 @@ const StarsBalanceModal = ({
|
|||||||
isOpen={isOpen}
|
isOpen={isOpen}
|
||||||
onClose={closeStarsBalanceModal}
|
onClose={closeStarsBalanceModal}
|
||||||
dialogStyle={`--modal-height: ${modalHeight}`}
|
dialogStyle={`--modal-height: ${modalHeight}`}
|
||||||
|
hasAbsoluteCloseButton
|
||||||
>
|
>
|
||||||
<div className={buildClassName(styles.main, 'custom-scroll')} onScroll={handleScroll}>
|
<div className={buildClassName(styles.main, 'custom-scroll')} onScroll={handleScroll}>
|
||||||
<Button
|
|
||||||
round
|
|
||||||
size="smaller"
|
|
||||||
className={styles.closeButton}
|
|
||||||
color="translucent"
|
|
||||||
onClick={() => closeStarsBalanceModal()}
|
|
||||||
ariaLabel={lang('Close')}
|
|
||||||
iconName="close"
|
|
||||||
/>
|
|
||||||
{currency !== TON_CURRENCY_CODE && <BalanceBlock balance={balance} className={styles.modalBalance} />}
|
{currency !== TON_CURRENCY_CODE && <BalanceBlock balance={balance} className={styles.modalBalance} />}
|
||||||
<div className={buildClassName(styles.header, isHeaderHidden && styles.hiddenHeader)}>
|
<div
|
||||||
|
className={buildClassName(
|
||||||
|
styles.header, isHeaderHidden && styles.hiddenHeader, areTabsPinned && styles.noSeparator,
|
||||||
|
)}
|
||||||
|
>
|
||||||
<h2 className={styles.starHeaderText}>
|
<h2 className={styles.starHeaderText}>
|
||||||
{oldLang('TelegramStars')}
|
{oldLang('TelegramStars')}
|
||||||
</h2>
|
</h2>
|
||||||
@ -330,11 +349,6 @@ const StarsBalanceModal = ({
|
|||||||
{tosText}
|
{tosText}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{currency === TON_CURRENCY_CODE && (
|
|
||||||
<div className={styles.hint}>
|
|
||||||
{lang('TonModalHint')}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{shouldShowItems && Boolean(subscriptions?.list.length) && (
|
{shouldShowItems && Boolean(subscriptions?.list.length) && (
|
||||||
<div className={styles.section}>
|
<div className={styles.section}>
|
||||||
<h3 className={styles.sectionTitle}>{oldLang('StarMySubscriptions')}</h3>
|
<h3 className={styles.sectionTitle}>{oldLang('StarMySubscriptions')}</h3>
|
||||||
@ -391,6 +405,7 @@ const StarsBalanceModal = ({
|
|||||||
</Transition>
|
</Transition>
|
||||||
</div>
|
</div>
|
||||||
<TabList
|
<TabList
|
||||||
|
ref={tabsRef}
|
||||||
className={styles.tabs}
|
className={styles.tabs}
|
||||||
tabClassName={styles.tab}
|
tabClassName={styles.tab}
|
||||||
activeTab={selectedTabIndex}
|
activeTab={selectedTabIndex}
|
||||||
|
|||||||
@ -92,8 +92,8 @@
|
|||||||
.closeButton {
|
.closeButton {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 3;
|
z-index: 3;
|
||||||
top: 0.5rem;
|
top: 0.875rem;
|
||||||
left: 0.5rem;
|
left: 0.875rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.avatar {
|
.avatar {
|
||||||
|
|||||||
@ -25,7 +25,6 @@ import useOldLang from '../../../../hooks/useOldLang';
|
|||||||
|
|
||||||
import Avatar from '../../../common/Avatar';
|
import Avatar from '../../../common/Avatar';
|
||||||
import SafeLink from '../../../common/SafeLink';
|
import SafeLink from '../../../common/SafeLink';
|
||||||
import Button from '../../../ui/Button';
|
|
||||||
import Modal from '../../../ui/Modal';
|
import Modal from '../../../ui/Modal';
|
||||||
import StarTopupOptionList from '../StarTopupOptionList';
|
import StarTopupOptionList from '../StarTopupOptionList';
|
||||||
|
|
||||||
@ -154,17 +153,9 @@ const StarsGiftModal: FC<OwnProps & StateProps> = ({
|
|||||||
isSlim
|
isSlim
|
||||||
onClose={handleClose}
|
onClose={handleClose}
|
||||||
isOpen={isOpen}
|
isOpen={isOpen}
|
||||||
|
hasAbsoluteCloseButton
|
||||||
>
|
>
|
||||||
<div className={buildClassName(styles.main, 'custom-scroll')} onScroll={handleScroll}>
|
<div className={buildClassName(styles.main, 'custom-scroll')} onScroll={handleScroll}>
|
||||||
<Button
|
|
||||||
round
|
|
||||||
size="smaller"
|
|
||||||
className={styles.closeButton}
|
|
||||||
color="translucent"
|
|
||||||
onClick={() => closeStarsGiftModal()}
|
|
||||||
ariaLabel={oldLang('Close')}
|
|
||||||
iconName="close"
|
|
||||||
/>
|
|
||||||
<div className={buildClassName(styles.header, isHeaderHidden && styles.hiddenHeader)}>
|
<div className={buildClassName(styles.header, isHeaderHidden && styles.hiddenHeader)}>
|
||||||
<h2 className={styles.starHeaderText}>
|
<h2 className={styles.starHeaderText}>
|
||||||
{user ? oldLang('GiftStarsTitle') : oldLang('Star.List.GetStars')}
|
{user ? oldLang('GiftStarsTitle') : oldLang('Star.List.GetStars')}
|
||||||
|
|||||||
@ -157,7 +157,7 @@
|
|||||||
|
|
||||||
.modal-header {
|
.modal-header {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
padding-inline: 0.5rem;
|
padding-inline: 0.875rem;
|
||||||
border-bottom: 0;
|
border-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -378,7 +378,7 @@ function StorySettings({
|
|||||||
className={buildClassName(styles.closeButton, 'close-button')}
|
className={buildClassName(styles.closeButton, 'close-button')}
|
||||||
round
|
round
|
||||||
color="translucent"
|
color="translucent"
|
||||||
size="smaller"
|
size="tiny"
|
||||||
onClick={handleCloseButtonClick}
|
onClick={handleCloseButtonClick}
|
||||||
ariaLabel={isBackButton ? lang('Common.Back') : lang('Common.Close')}
|
ariaLabel={isBackButton ? lang('Common.Back') : lang('Common.Close')}
|
||||||
>
|
>
|
||||||
|
|||||||
@ -151,7 +151,7 @@ function StoryViewer({
|
|||||||
<Button
|
<Button
|
||||||
className={styles.close}
|
className={styles.close}
|
||||||
round
|
round
|
||||||
size="smaller"
|
size="tiny"
|
||||||
color="translucent-white"
|
color="translucent-white"
|
||||||
ariaLabel={lang('Close')}
|
ariaLabel={lang('Close')}
|
||||||
onClick={handleClose}
|
onClick={handleClose}
|
||||||
|
|||||||
@ -41,7 +41,7 @@
|
|||||||
height: 3rem;
|
height: 3rem;
|
||||||
padding: 0.625rem;
|
padding: 0.625rem;
|
||||||
border: 0;
|
border: 0;
|
||||||
border-radius: var(--border-radius-default);
|
border-radius: var(--border-radius-button);
|
||||||
|
|
||||||
font-weight: var(--font-weight-medium);
|
font-weight: var(--font-weight-medium);
|
||||||
line-height: 1.2;
|
line-height: 1.2;
|
||||||
@ -53,7 +53,7 @@
|
|||||||
background-size: cover;
|
background-size: cover;
|
||||||
outline: none !important;
|
outline: none !important;
|
||||||
|
|
||||||
transition: background-color 0.15s, color 0.15s, opacity 0.15s;
|
transition: background-color 0.2s, color 0.2s, opacity 0.2s;
|
||||||
|
|
||||||
white-space-collapse: preserve;
|
white-space-collapse: preserve;
|
||||||
|
|
||||||
@ -91,7 +91,7 @@
|
|||||||
background-color: var(--color-primary);
|
background-color: var(--color-primary);
|
||||||
|
|
||||||
@include active-styles() {
|
@include active-styles() {
|
||||||
background-color: var(--color-primary-shade);
|
background-color: rgba(var(--color-primary-shade-rgb), 0.9);
|
||||||
}
|
}
|
||||||
|
|
||||||
@include no-ripple-styles() {
|
@include no-ripple-styles() {
|
||||||
@ -331,11 +331,11 @@
|
|||||||
|
|
||||||
&.transparentBlured {
|
&.transparentBlured {
|
||||||
color: white;
|
color: white;
|
||||||
background-color: rgba(0, 0, 0, 0.2);
|
background-color: rgba(255, 255, 255, 0.1);
|
||||||
backdrop-filter: blur(0.5rem);
|
backdrop-filter: blur(0.5rem);
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: rgba(0, 0, 0, 0.1);
|
background-color: rgba(255, 255, 255, 0.2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -366,12 +366,12 @@
|
|||||||
&.tiny {
|
&.tiny {
|
||||||
height: 2.25rem;
|
height: 2.25rem;
|
||||||
padding: 0.4375rem;
|
padding: 0.4375rem;
|
||||||
border-radius: var(--border-radius-default-small);
|
border-radius: var(--border-radius-button-tiny);
|
||||||
font-size: 0.875rem;
|
font-size: 0.875rem;
|
||||||
|
|
||||||
&.round {
|
&.round {
|
||||||
width: 2.25rem;
|
width: 1.875rem;
|
||||||
height: 2.25rem;
|
height: 1.875rem;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -140,7 +140,8 @@
|
|||||||
.modal-header-condensed {
|
.modal-header-condensed {
|
||||||
@extend %modal-header;
|
@extend %modal-header;
|
||||||
|
|
||||||
padding: 0.375rem 0.5rem !important;
|
min-height: 3.5rem;
|
||||||
|
padding: 0.375rem 0.75rem !important;
|
||||||
|
|
||||||
.modal-action-button {
|
.modal-action-button {
|
||||||
width: auto;
|
width: auto;
|
||||||
@ -242,8 +243,8 @@
|
|||||||
|
|
||||||
.modal-absolute-close-button {
|
.modal-absolute-close-button {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 1;
|
z-index: 3;
|
||||||
top: 0.375rem;
|
top: 0.875rem;
|
||||||
left: 0.375rem;
|
left: 0.875rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -149,7 +149,7 @@ const Modal: FC<OwnProps> = ({
|
|||||||
className={buildClassName(hasAbsoluteCloseButton && 'modal-absolute-close-button')}
|
className={buildClassName(hasAbsoluteCloseButton && 'modal-absolute-close-button')}
|
||||||
round
|
round
|
||||||
color={absoluteCloseButtonColor}
|
color={absoluteCloseButtonColor}
|
||||||
size="smaller"
|
size="tiny"
|
||||||
iconName="close"
|
iconName="close"
|
||||||
ariaLabel={lang('Close')}
|
ariaLabel={lang('Close')}
|
||||||
onClick={onClose}
|
onClick={onClose}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import type { TeactNode } from '../../lib/teact/teact';
|
import type { ElementRef, TeactNode } from '../../lib/teact/teact';
|
||||||
import { memo, useEffect, useRef } from '../../lib/teact/teact';
|
import { memo, useEffect, useRef } from '../../lib/teact/teact';
|
||||||
|
|
||||||
import type { ApiMessageEntityCustomEmoji } from '../../api/types';
|
import type { ApiMessageEntityCustomEmoji } from '../../api/types';
|
||||||
@ -33,6 +33,7 @@ type OwnProps = {
|
|||||||
className?: string;
|
className?: string;
|
||||||
tabClassName?: string;
|
tabClassName?: string;
|
||||||
contextRootElementSelector?: string;
|
contextRootElementSelector?: string;
|
||||||
|
ref?: ElementRef<HTMLDivElement>;
|
||||||
onSwitchTab: (index: number) => void;
|
onSwitchTab: (index: number) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -46,9 +47,13 @@ const TabList = ({
|
|||||||
className,
|
className,
|
||||||
tabClassName,
|
tabClassName,
|
||||||
contextRootElementSelector,
|
contextRootElementSelector,
|
||||||
|
ref,
|
||||||
onSwitchTab,
|
onSwitchTab,
|
||||||
}: OwnProps) => {
|
}: OwnProps) => {
|
||||||
const containerRef = useRef<HTMLDivElement>();
|
let containerRef = useRef<HTMLDivElement>();
|
||||||
|
if (ref) {
|
||||||
|
containerRef = ref;
|
||||||
|
}
|
||||||
const previousActiveTab = usePreviousDeprecated(activeTab);
|
const previousActiveTab = usePreviousDeprecated(activeTab);
|
||||||
|
|
||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
|
|||||||
@ -372,7 +372,7 @@ export const BOT_VERIFICATION_PEERS_LIMIT = 20;
|
|||||||
export const LIGHT_THEME_BG_COLOR = '#99BA92';
|
export const LIGHT_THEME_BG_COLOR = '#99BA92';
|
||||||
export const DARK_THEME_BG_COLOR = '#0F0F0F';
|
export const DARK_THEME_BG_COLOR = '#0F0F0F';
|
||||||
export const DEFAULT_PATTERN_COLOR = '#4A8E3A8C';
|
export const DEFAULT_PATTERN_COLOR = '#4A8E3A8C';
|
||||||
export const DARK_THEME_PATTERN_COLOR = '#0A0A0A8C';
|
export const DARK_THEME_PATTERN_COLOR = '#48576166';
|
||||||
export const PEER_COLOR_BG_OPACITY = '1a';
|
export const PEER_COLOR_BG_OPACITY = '1a';
|
||||||
export const PEER_COLOR_BG_ACTIVE_OPACITY = '2b';
|
export const PEER_COLOR_BG_ACTIVE_OPACITY = '2b';
|
||||||
export const PEER_COLOR_GRADIENT_STEP = 5; // px
|
export const PEER_COLOR_GRADIENT_STEP = 5; // px
|
||||||
|
|||||||
@ -80,6 +80,11 @@ export function selectThemeValues<T extends GlobalState>(global: T, themeKey: Th
|
|||||||
return global.settings.themes[themeKey];
|
return global.settings.themes[themeKey];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function selectActionMessageBg<T extends GlobalState>(global: T) {
|
||||||
|
const theme = selectTheme(global);
|
||||||
|
return global.settings.themes[theme]?.patternColor;
|
||||||
|
}
|
||||||
|
|
||||||
export function selectIsForumPanelOpen<T extends GlobalState>(
|
export function selectIsForumPanelOpen<T extends GlobalState>(
|
||||||
global: T,
|
global: T,
|
||||||
...[tabId = getCurrentTabId()]: TabArgs<T>
|
...[tabId = getCurrentTabId()]: TabArgs<T>
|
||||||
|
|||||||
@ -6,13 +6,16 @@ import { requestMutation } from '../lib/fasterdom/fasterdom.ts';
|
|||||||
import { throttle } from '../util/schedulers.ts';
|
import { throttle } from '../util/schedulers.ts';
|
||||||
|
|
||||||
const THROTTLE_DELAY = 100;
|
const THROTTLE_DELAY = 100;
|
||||||
|
const SCROLL_THRESHOLD = 5;
|
||||||
|
|
||||||
const useScrollNotch = ({
|
const useScrollNotch = ({
|
||||||
containerRef,
|
containerRef,
|
||||||
selector,
|
selector,
|
||||||
|
isBottomNotch,
|
||||||
}: {
|
}: {
|
||||||
containerRef: ElementRef<HTMLDivElement>;
|
containerRef: ElementRef<HTMLDivElement>;
|
||||||
selector: string;
|
selector: string;
|
||||||
|
isBottomNotch?: boolean;
|
||||||
}, deps: unknown[]) => {
|
}, deps: unknown[]) => {
|
||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
const elements = containerRef.current?.querySelectorAll<HTMLElement>(selector);
|
const elements = containerRef.current?.querySelectorAll<HTMLElement>(selector);
|
||||||
@ -21,14 +24,24 @@ const useScrollNotch = ({
|
|||||||
const handleScroll = throttle((event: Event) => {
|
const handleScroll = throttle((event: Event) => {
|
||||||
const target = event.target as HTMLElement;
|
const target = event.target as HTMLElement;
|
||||||
const isScrolled = target.scrollTop > 0;
|
const isScrolled = target.scrollTop > 0;
|
||||||
|
const { scrollHeight, scrollTop, clientHeight } = target;
|
||||||
|
const isAtEnd = scrollHeight - scrollTop - clientHeight < SCROLL_THRESHOLD;
|
||||||
|
|
||||||
requestMutation(() => {
|
requestMutation(() => {
|
||||||
toggleExtraClass(target, 'scrolled', isScrolled);
|
if (isBottomNotch) {
|
||||||
|
toggleExtraClass(target, 'scrolled-to-end', isAtEnd);
|
||||||
|
} else {
|
||||||
|
toggleExtraClass(target, 'scrolled', isScrolled);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}, THROTTLE_DELAY);
|
}, THROTTLE_DELAY);
|
||||||
|
|
||||||
elements.forEach((el) => {
|
elements.forEach((el) => {
|
||||||
addExtraClass(el, 'with-notch');
|
if (isBottomNotch) {
|
||||||
|
addExtraClass(el, 'with-bottom-notch');
|
||||||
|
} else {
|
||||||
|
addExtraClass(el, 'with-notch');
|
||||||
|
}
|
||||||
el.addEventListener('scroll', handleScroll, { passive: true });
|
el.addEventListener('scroll', handleScroll, { passive: true });
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -36,10 +49,13 @@ const useScrollNotch = ({
|
|||||||
elements.forEach((el) => {
|
elements.forEach((el) => {
|
||||||
el.removeEventListener('scroll', handleScroll);
|
el.removeEventListener('scroll', handleScroll);
|
||||||
removeExtraClass(el, 'with-notch');
|
removeExtraClass(el, 'with-notch');
|
||||||
|
removeExtraClass(el, 'with-bottom-notch');
|
||||||
|
removeExtraClass(el, 'scrolled');
|
||||||
|
removeExtraClass(el, 'scrolled-to-end');
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
// eslint-disable-next-line react-hooks-static-deps/exhaustive-deps
|
// eslint-disable-next-line react-hooks-static-deps/exhaustive-deps
|
||||||
}, [containerRef, selector, ...deps]);
|
}, [containerRef, selector, isBottomNotch, ...deps]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const elements = containerRef.current?.querySelectorAll<HTMLElement>(selector);
|
const elements = containerRef.current?.querySelectorAll<HTMLElement>(selector);
|
||||||
@ -47,12 +63,19 @@ const useScrollNotch = ({
|
|||||||
|
|
||||||
elements.forEach((el) => {
|
elements.forEach((el) => {
|
||||||
const isScrolled = el.scrollTop > 0;
|
const isScrolled = el.scrollTop > 0;
|
||||||
|
const { scrollHeight, scrollTop, clientHeight } = el;
|
||||||
|
const isAtEnd = scrollHeight - scrollTop - clientHeight < SCROLL_THRESHOLD;
|
||||||
|
|
||||||
requestMutation(() => {
|
requestMutation(() => {
|
||||||
toggleExtraClass(el, 'scrolled', isScrolled);
|
if (isBottomNotch) {
|
||||||
|
toggleExtraClass(el, 'scrolled-to-end', isAtEnd);
|
||||||
|
} else {
|
||||||
|
toggleExtraClass(el, 'scrolled', isScrolled);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
// eslint-disable-next-line react-hooks-static-deps/exhaustive-deps
|
// eslint-disable-next-line react-hooks-static-deps/exhaustive-deps
|
||||||
}, [containerRef, selector, ...deps]);
|
}, [containerRef, selector, isBottomNotch, ...deps]);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default useScrollNotch;
|
export default useScrollNotch;
|
||||||
|
|||||||
@ -212,7 +212,9 @@ $color-message-story-mention-to: #74bcff;
|
|||||||
|
|
||||||
--vh: 1vh;
|
--vh: 1vh;
|
||||||
|
|
||||||
--border-radius-modal: 1rem;
|
--border-radius-button: 1rem;
|
||||||
|
--border-radius-button-tiny: 0.875rem;
|
||||||
|
--border-radius-modal: 2rem;
|
||||||
--border-radius-default: 0.75rem;
|
--border-radius-default: 0.75rem;
|
||||||
--border-radius-default-small: 0.625rem;
|
--border-radius-default-small: 0.625rem;
|
||||||
--border-radius-default-tiny: 0.375rem;
|
--border-radius-default-tiny: 0.375rem;
|
||||||
|
|||||||
@ -3,8 +3,8 @@
|
|||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-display: block;
|
font-display: block;
|
||||||
src: url("./icons.woff2?cc3fadda4d577575d1b441ec5d6c8994") format("woff2"),
|
src: url("./icons.woff2?a07bab7d97a4c6540cca18b1d787228b") format("woff2"),
|
||||||
url("./icons.woff?cc3fadda4d577575d1b441ec5d6c8994") format("woff");
|
url("./icons.woff?a07bab7d97a4c6540cca18b1d787228b") format("woff");
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon-char::before {
|
.icon-char::before {
|
||||||
|
|||||||
@ -396,6 +396,15 @@ body:not(.is-ios) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.with-bottom-notch {
|
||||||
|
border-bottom: 1px solid var(--color-borders);
|
||||||
|
transition: border-color 0.2s ease-in-out;
|
||||||
|
|
||||||
|
&.scrolled-to-end {
|
||||||
|
border-bottom-color: transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@keyframes grow-icon {
|
@keyframes grow-icon {
|
||||||
0% {
|
0% {
|
||||||
transform: scale(0.5);
|
transform: scale(0.5);
|
||||||
|
|||||||
3
src/types/language.d.ts
vendored
@ -2830,6 +2830,9 @@ export interface LangPairWithVariables<V = LangVariable> {
|
|||||||
'stars': V;
|
'stars': V;
|
||||||
'peer': V;
|
'peer': V;
|
||||||
};
|
};
|
||||||
|
'GiftBuyEqualsTo': {
|
||||||
|
'stars': V;
|
||||||
|
};
|
||||||
'ComposerTitleForwardFrom': {
|
'ComposerTitleForwardFrom': {
|
||||||
'users': V;
|
'users': V;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -234,10 +234,9 @@ export function getPatternColor(rgb: Number3) {
|
|||||||
? Math.max(0, v * 0.65)
|
? Math.max(0, v * 0.65)
|
||||||
: Math.max(0, Math.min(1, 1 - v * 0.65));
|
: Math.max(0, Math.min(1, 1 - v * 0.65));
|
||||||
|
|
||||||
const newRgb = hsl2rgb([h * 360, s, v]);
|
const newRgb = hsv2rgb([h, s, v]);
|
||||||
const mappedRgb = newRgb.map((c) => Math.floor(c * 255)) as Number3;
|
|
||||||
|
|
||||||
return rgba2hex([...mappedRgb, 102]);
|
return rgba2hex([...newRgb, 102]);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function int2cssRgba(color: number): string {
|
export function int2cssRgba(color: number): string {
|
||||||
|
|||||||