this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Upgrade react-menu and bug fixes

+120 -75
+34 -15
package-lock.json
··· 12 12 "@github/text-expander-element": "~2.3.0", 13 13 "@iconify-icons/mingcute": "~1.2.5", 14 14 "@justinribeiro/lite-youtube": "~1.5.0", 15 - "@szhsin/react-menu": "~3.5.3", 15 + "@szhsin/react-menu": "~4.0.0", 16 + "@uidotdev/usehooks": "~2.0.1", 16 17 "dayjs": "~1.11.8", 17 18 "dayjs-twitter": "~0.5.0", 18 19 "fast-blurhash": "~1.1.2", ··· 3126 3127 } 3127 3128 }, 3128 3129 "node_modules/@szhsin/react-menu": { 3129 - "version": "3.5.3", 3130 - "resolved": "https://registry.npmjs.org/@szhsin/react-menu/-/react-menu-3.5.3.tgz", 3131 - "integrity": "sha512-jxo8oaRwxmVjUzkyOi/ZJiXaZiuFPMIxFzyJdUKfnhBLYiEOVTU9M2CiPuEkirILoareR2GJj2K3y8a81CBPlw==", 3130 + "version": "4.0.0", 3131 + "resolved": "https://registry.npmjs.org/@szhsin/react-menu/-/react-menu-4.0.0.tgz", 3132 + "integrity": "sha512-DOl+IWddgHofcEzSTJfILGvpU67O/y8r07LOVUhfThke9VEZ5LAZNkp2Q3mEFaN7PkmnmJtjPBEdIK3oN1/ZfQ==", 3132 3133 "dependencies": { 3133 3134 "prop-types": "^15.7.2", 3134 - "react-transition-state": "^1.1.5" 3135 + "react-transition-state": "^2.1.0" 3135 3136 }, 3136 3137 "peerDependencies": { 3137 3138 "react": ">=16.14.0", ··· 3271 3272 "integrity": "sha512-NfQ4gyz38SL8sDNrSixxU2Os1a5xcdFxipAFxYEuLUlvU2uDwS4NUpsImcf1//SlWItCVMMLiylsxbmNMToV/g==", 3272 3273 "dev": true 3273 3274 }, 3275 + "node_modules/@uidotdev/usehooks": { 3276 + "version": "2.0.1", 3277 + "resolved": "https://registry.npmjs.org/@uidotdev/usehooks/-/usehooks-2.0.1.tgz", 3278 + "integrity": "sha512-rJXxE3Y8g9utRbOS9Pj9tIvrnOdaakHIhLbMxBlErV8HydnGD0DveD82aLBfVTh1hBp5IXqpeHpMrPE9WIT7vQ==", 3279 + "engines": { 3280 + "node": ">=16" 3281 + }, 3282 + "peerDependencies": { 3283 + "react": ">=18.0.0", 3284 + "react-dom": ">=18.0.0" 3285 + } 3286 + }, 3274 3287 "node_modules/@vue/compiler-core": { 3275 3288 "version": "3.2.45", 3276 3289 "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.45.tgz", ··· 6334 6347 } 6335 6348 }, 6336 6349 "node_modules/react-transition-state": { 6337 - "version": "1.1.5", 6338 - "resolved": "https://registry.npmjs.org/react-transition-state/-/react-transition-state-1.1.5.tgz", 6339 - "integrity": "sha512-ITY2mZqc2dWG2eitJkYNdcSFW8aKeOlkL2A/vowRrLL8GH3J6Re/SpD/BLvQzrVOTqjsP0b5S9N10vgNNzwMUQ==", 6350 + "version": "2.1.0", 6351 + "resolved": "https://registry.npmjs.org/react-transition-state/-/react-transition-state-2.1.0.tgz", 6352 + "integrity": "sha512-b8ldw2pbZk++XM43vcD4ETaFWlzTsjpUX33CmT8BBPPFYlQ2R50wxcY4ZeJ1TesJYziYZ9/rNPFnyA9tR0iKDw==", 6340 6353 "peerDependencies": { 6341 6354 "react": ">=16.8.0", 6342 6355 "react-dom": ">=16.8.0" ··· 9619 9632 } 9620 9633 }, 9621 9634 "@szhsin/react-menu": { 9622 - "version": "3.5.3", 9623 - "resolved": "https://registry.npmjs.org/@szhsin/react-menu/-/react-menu-3.5.3.tgz", 9624 - "integrity": "sha512-jxo8oaRwxmVjUzkyOi/ZJiXaZiuFPMIxFzyJdUKfnhBLYiEOVTU9M2CiPuEkirILoareR2GJj2K3y8a81CBPlw==", 9635 + "version": "4.0.0", 9636 + "resolved": "https://registry.npmjs.org/@szhsin/react-menu/-/react-menu-4.0.0.tgz", 9637 + "integrity": "sha512-DOl+IWddgHofcEzSTJfILGvpU67O/y8r07LOVUhfThke9VEZ5LAZNkp2Q3mEFaN7PkmnmJtjPBEdIK3oN1/ZfQ==", 9625 9638 "requires": { 9626 9639 "prop-types": "^15.7.2", 9627 - "react-transition-state": "^1.1.5" 9640 + "react-transition-state": "^2.1.0" 9628 9641 } 9629 9642 }, 9630 9643 "@trivago/prettier-plugin-sort-imports": { ··· 9739 9752 "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.3.tgz", 9740 9753 "integrity": "sha512-NfQ4gyz38SL8sDNrSixxU2Os1a5xcdFxipAFxYEuLUlvU2uDwS4NUpsImcf1//SlWItCVMMLiylsxbmNMToV/g==", 9741 9754 "dev": true 9755 + }, 9756 + "@uidotdev/usehooks": { 9757 + "version": "2.0.1", 9758 + "resolved": "https://registry.npmjs.org/@uidotdev/usehooks/-/usehooks-2.0.1.tgz", 9759 + "integrity": "sha512-rJXxE3Y8g9utRbOS9Pj9tIvrnOdaakHIhLbMxBlErV8HydnGD0DveD82aLBfVTh1hBp5IXqpeHpMrPE9WIT7vQ==", 9760 + "requires": {} 9742 9761 }, 9743 9762 "@vue/compiler-core": { 9744 9763 "version": "3.2.45", ··· 11832 11851 } 11833 11852 }, 11834 11853 "react-transition-state": { 11835 - "version": "1.1.5", 11836 - "resolved": "https://registry.npmjs.org/react-transition-state/-/react-transition-state-1.1.5.tgz", 11837 - "integrity": "sha512-ITY2mZqc2dWG2eitJkYNdcSFW8aKeOlkL2A/vowRrLL8GH3J6Re/SpD/BLvQzrVOTqjsP0b5S9N10vgNNzwMUQ==", 11854 + "version": "2.1.0", 11855 + "resolved": "https://registry.npmjs.org/react-transition-state/-/react-transition-state-2.1.0.tgz", 11856 + "integrity": "sha512-b8ldw2pbZk++XM43vcD4ETaFWlzTsjpUX33CmT8BBPPFYlQ2R50wxcY4ZeJ1TesJYziYZ9/rNPFnyA9tR0iKDw==", 11838 11857 "requires": {} 11839 11858 }, 11840 11859 "regenerate": {
+2 -1
package.json
··· 14 14 "@github/text-expander-element": "~2.3.0", 15 15 "@iconify-icons/mingcute": "~1.2.5", 16 16 "@justinribeiro/lite-youtube": "~1.5.0", 17 - "@szhsin/react-menu": "~3.5.3", 17 + "@szhsin/react-menu": "~4.0.0", 18 + "@uidotdev/usehooks": "~2.0.1", 18 19 "dayjs": "~1.11.8", 19 20 "dayjs-twitter": "~0.5.0", 20 21 "fast-blurhash": "~1.1.2",
+1 -1
src/components/account-info.jsx
··· 673 673 openTrigger="clickOnly" 674 674 direction="bottom" 675 675 overflow="auto" 676 - offsetX={-16} 676 + shift={-16} 677 677 label={ 678 678 <> 679 679 <Icon icon="mute" />
+1 -1
src/components/media-modal.jsx
··· 191 191 align="end" 192 192 position="anchor" 193 193 boundingBoxPadding="8 8 8 8" 194 - offsetY={4} 194 + gap={4} 195 195 menuClassName="glass-menu" 196 196 menuButton={ 197 197 <button type="button" class="carousel-button plain3">
+31
src/components/menu2.jsx
··· 1 + import { Menu } from '@szhsin/react-menu'; 2 + import { useWindowSize } from '@uidotdev/usehooks'; 3 + import { useRef } from 'preact/hooks'; 4 + 5 + import safeBoundingBoxPadding from '../utils/safe-bounding-box-padding'; 6 + 7 + // It's like Menu but with sensible defaults, bug fixes and improvements. 8 + function Menu2(props) { 9 + const { containerProps } = props; 10 + const size = useWindowSize(); 11 + const instanceRef = useRef(); 12 + return ( 13 + <Menu 14 + boundingBoxPadding={safeBoundingBoxPadding()} 15 + repositionFlag={`${size.width}x${size.height}`} 16 + {...props} 17 + instanceRef={instanceRef} 18 + containerProps={{ 19 + onClick: (e) => { 20 + if (e.target === e.currentTarget) { 21 + instanceRef.current?.closeMenu?.(); 22 + } 23 + containerProps?.onClick?.(e); 24 + }, 25 + ...containerProps, 26 + }} 27 + /> 28 + ); 29 + } 30 + 31 + export default Menu2;
+1 -1
src/components/shortcuts.jsx
··· 132 132 viewScroll="close" 133 133 boundingBoxPadding="8 8 8 8" 134 134 menuClassName="glass-menu shortcuts-menu" 135 - offsetY={8} 135 + gap={8} 136 136 position="anchor" 137 137 menuButton={ 138 138 <button
+3 -26
src/components/status.jsx
··· 34 34 import isMastodonLinkMaybe from '../utils/isMastodonLinkMaybe'; 35 35 import localeMatch from '../utils/locale-match'; 36 36 import niceDateTime from '../utils/nice-date-time'; 37 + import safeBoundingBoxPadding from '../utils/safe-bounding-box-padding'; 37 38 import shortenNumber from '../utils/shorten-number'; 38 39 import showToast from '../utils/show-toast'; 39 40 import states, { getStatus, saveStatus, statusKey } from '../utils/states'; ··· 824 825 }, 825 826 }} 826 827 align="end" 827 - offsetY={4} 828 + gap={4} 828 829 overflow="auto" 829 830 viewScroll="close" 830 831 boundingBoxPadding="8 8 8 8" ··· 1182 1183 document.querySelector('.status-deck') || document.body, 1183 1184 }} 1184 1185 align="end" 1185 - offsetY={4} 1186 + gap={4} 1186 1187 overflow="auto" 1187 1188 viewScroll="close" 1188 1189 boundingBoxPadding="8 8 8 8" ··· 1816 1817 cacheKey: (instance, url) => `${instance}:${url}`, 1817 1818 }), 1818 1819 ); 1819 - 1820 - const root = document.documentElement; 1821 - const defaultBoundingBoxPadding = 8; 1822 - function _safeBoundingBoxPadding() { 1823 - // Get safe area inset variables from root 1824 - const style = getComputedStyle(root); 1825 - const safeAreaInsetTop = style.getPropertyValue('--sai-top'); 1826 - const safeAreaInsetRight = style.getPropertyValue('--sai-right'); 1827 - const safeAreaInsetBottom = style.getPropertyValue('--sai-bottom'); 1828 - const safeAreaInsetLeft = style.getPropertyValue('--sai-left'); 1829 - const str = [ 1830 - safeAreaInsetTop, 1831 - safeAreaInsetRight, 1832 - safeAreaInsetBottom, 1833 - safeAreaInsetLeft, 1834 - ] 1835 - .map((v) => parseInt(v, 10) || defaultBoundingBoxPadding) 1836 - .join(' '); 1837 - // console.log(str); 1838 - return str; 1839 - } 1840 - const safeBoundingBoxPadding = mem(_safeBoundingBoxPadding, { 1841 - maxAge: 10_000, // 10 seconds 1842 - }); 1843 1820 1844 1821 function FilteredStatus({ status, filterInfo, instance, containerProps = {} }) { 1845 1822 const {
+4 -6
src/pages/account-statuses.jsx
··· 6 6 import AccountInfo from '../components/account-info'; 7 7 import Icon from '../components/icon'; 8 8 import Link from '../components/link'; 9 + import Menu2 from '../components/menu2'; 9 10 import Timeline from '../components/timeline'; 10 11 import { api } from '../utils/api'; 11 12 import emojifyText from '../utils/emojify-text'; ··· 255 256 timelineStart={TimelineStart} 256 257 refresh={excludeReplies + excludeBoosts + tagged + media} 257 258 headerEnd={ 258 - <Menu 259 - portal={{ 260 - target: document.body, 261 - }} 259 + <Menu2 260 + portal 262 261 // setDownOverflow 263 262 overflow="auto" 264 263 viewScroll="close" 265 264 position="anchor" 266 - boundingBoxPadding="8 8 8 8" 267 265 menuButton={ 268 266 <button type="button" class="plain"> 269 267 <Icon icon="more" size="l" /> ··· 295 293 Switch to account's instance (<b>{accountInstance}</b>) 296 294 </small> 297 295 </MenuItem> 298 - </Menu> 296 + </Menu2> 299 297 } 300 298 /> 301 299 );
+4 -6
src/pages/hashtag.jsx
··· 9 9 import { useNavigate, useParams } from 'react-router-dom'; 10 10 11 11 import Icon from '../components/icon'; 12 + import Menu2 from '../components/menu2'; 12 13 import Timeline from '../components/timeline'; 13 14 import { api } from '../utils/api'; 14 15 import showToast from '../utils/show-toast'; ··· 122 123 checkForUpdates={checkForUpdates} 123 124 useItemID 124 125 headerEnd={ 125 - <Menu 126 - portal={{ 127 - target: document.body, 128 - }} 126 + <Menu2 127 + portal 129 128 setDownOverflow 130 129 overflow="auto" 131 130 viewScroll="close" 132 131 position="anchor" 133 - boundingBoxPadding="8 8 8 8" 134 132 menuButton={ 135 133 <button type="button" class="plain"> 136 134 <Icon icon="more" size="l" /> ··· 306 304 > 307 305 <Icon icon="bus" /> <span>Go to another instance…</span> 308 306 </MenuItem> 309 - </Menu> 307 + </Menu2> 310 308 } 311 309 /> 312 310 );
+4 -6
src/pages/list.jsx
··· 10 10 import Icon from '../components/icon'; 11 11 import Link from '../components/link'; 12 12 import ListAddEdit from '../components/list-add-edit'; 13 + import Menu2 from '../components/menu2'; 13 14 import Modal from '../components/modal'; 14 15 import Timeline from '../components/timeline'; 15 16 import { api } from '../utils/api'; ··· 108 109 </Link> 109 110 } 110 111 headerEnd={ 111 - <Menu 112 - portal={{ 113 - target: document.body, 114 - }} 112 + <Menu2 113 + portal 115 114 setDownOverflow 116 115 overflow="auto" 117 116 viewScroll="close" 118 117 position="anchor" 119 - boundingBoxPadding="8 8 8 8" 120 118 menuButton={ 121 119 <button type="button" class="plain"> 122 120 <Icon icon="more" size="l" /> ··· 137 135 <Icon icon="group" size="l" /> 138 136 <span>Manage members</span> 139 137 </MenuItem> 140 - </Menu> 138 + </Menu2> 141 139 } 142 140 /> 143 141 {showListAddEditModal && (
+4 -6
src/pages/public.jsx
··· 4 4 import { useSnapshot } from 'valtio'; 5 5 6 6 import Icon from '../components/icon'; 7 + import Menu2 from '../components/menu2'; 7 8 import Timeline from '../components/timeline'; 8 9 import { api } from '../utils/api'; 9 10 import { filteredItems } from '../utils/filters'; ··· 92 93 boostsCarousel={snapStates.settings.boostsCarousel} 93 94 allowFilters 94 95 headerEnd={ 95 - <Menu 96 - portal={{ 97 - target: document.body, 98 - }} 96 + <Menu2 97 + portal 99 98 // setDownOverflow 100 99 overflow="auto" 101 100 viewScroll="close" 102 101 position="anchor" 103 - boundingBoxPadding="8 8 8 8" 104 102 menuButton={ 105 103 <button type="button" class="plain"> 106 104 <Icon icon="more" size="l" /> ··· 136 134 > 137 135 <Icon icon="bus" /> <span>Go to another instance…</span> 138 136 </MenuItem> 139 - </Menu> 137 + </Menu2> 140 138 } 141 139 /> 142 140 );
+4 -6
src/pages/trending.jsx
··· 4 4 import { useSnapshot } from 'valtio'; 5 5 6 6 import Icon from '../components/icon'; 7 + import Menu2 from '../components/menu2'; 7 8 import Timeline from '../components/timeline'; 8 9 import { api } from '../utils/api'; 9 10 import { filteredItems } from '../utils/filters'; ··· 92 93 boostsCarousel={snapStates.settings.boostsCarousel} 93 94 allowFilters 94 95 headerEnd={ 95 - <Menu 96 - portal={{ 97 - target: document.body, 98 - }} 96 + <Menu2 97 + portal 99 98 // setDownOverflow 100 99 overflow="auto" 101 100 viewScroll="close" 102 101 position="anchor" 103 - boundingBoxPadding="8 8 8 8" 104 102 menuButton={ 105 103 <button type="button" class="plain"> 106 104 <Icon icon="more" size="l" /> ··· 124 122 > 125 123 <Icon icon="bus" /> <span>Go to another instance…</span> 126 124 </MenuItem> 127 - </Menu> 125 + </Menu2> 128 126 } 129 127 /> 130 128 );
+27
src/utils/safe-bounding-box-padding.jsx
··· 1 + import mem from 'mem'; 2 + 3 + const root = document.documentElement; 4 + const defaultBoundingBoxPadding = 8; 5 + function _safeBoundingBoxPadding() { 6 + // Get safe area inset variables from root 7 + const style = getComputedStyle(root); 8 + const safeAreaInsetTop = style.getPropertyValue('--sai-top'); 9 + const safeAreaInsetRight = style.getPropertyValue('--sai-right'); 10 + const safeAreaInsetBottom = style.getPropertyValue('--sai-bottom'); 11 + const safeAreaInsetLeft = style.getPropertyValue('--sai-left'); 12 + const str = [ 13 + safeAreaInsetTop, 14 + safeAreaInsetRight, 15 + safeAreaInsetBottom, 16 + safeAreaInsetLeft, 17 + ] 18 + .map((v) => parseInt(v, 10) || defaultBoundingBoxPadding) 19 + .join(' '); 20 + // console.log(str); 21 + return str; 22 + } 23 + const safeBoundingBoxPadding = mem(_safeBoundingBoxPadding, { 24 + maxAge: 10000, // 10 seconds 25 + }); 26 + 27 + export default safeBoundingBoxPadding;