mirror of
https://github.com/cheeaun/phanpy.git
synced 2024-12-18 11:12:34 +03:00
Upgrade react-menu and bug fixes
This commit is contained in:
parent
f6ef727cae
commit
a1ee5be54b
13 changed files with 120 additions and 75 deletions
49
package-lock.json
generated
49
package-lock.json
generated
|
@ -12,7 +12,8 @@
|
|||
"@github/text-expander-element": "~2.3.0",
|
||||
"@iconify-icons/mingcute": "~1.2.5",
|
||||
"@justinribeiro/lite-youtube": "~1.5.0",
|
||||
"@szhsin/react-menu": "~3.5.3",
|
||||
"@szhsin/react-menu": "~4.0.0",
|
||||
"@uidotdev/usehooks": "~2.0.1",
|
||||
"dayjs": "~1.11.8",
|
||||
"dayjs-twitter": "~0.5.0",
|
||||
"fast-blurhash": "~1.1.2",
|
||||
|
@ -3126,12 +3127,12 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@szhsin/react-menu": {
|
||||
"version": "3.5.3",
|
||||
"resolved": "https://registry.npmjs.org/@szhsin/react-menu/-/react-menu-3.5.3.tgz",
|
||||
"integrity": "sha512-jxo8oaRwxmVjUzkyOi/ZJiXaZiuFPMIxFzyJdUKfnhBLYiEOVTU9M2CiPuEkirILoareR2GJj2K3y8a81CBPlw==",
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@szhsin/react-menu/-/react-menu-4.0.0.tgz",
|
||||
"integrity": "sha512-DOl+IWddgHofcEzSTJfILGvpU67O/y8r07LOVUhfThke9VEZ5LAZNkp2Q3mEFaN7PkmnmJtjPBEdIK3oN1/ZfQ==",
|
||||
"dependencies": {
|
||||
"prop-types": "^15.7.2",
|
||||
"react-transition-state": "^1.1.5"
|
||||
"react-transition-state": "^2.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.14.0",
|
||||
|
@ -3271,6 +3272,18 @@
|
|||
"integrity": "sha512-NfQ4gyz38SL8sDNrSixxU2Os1a5xcdFxipAFxYEuLUlvU2uDwS4NUpsImcf1//SlWItCVMMLiylsxbmNMToV/g==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@uidotdev/usehooks": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@uidotdev/usehooks/-/usehooks-2.0.1.tgz",
|
||||
"integrity": "sha512-rJXxE3Y8g9utRbOS9Pj9tIvrnOdaakHIhLbMxBlErV8HydnGD0DveD82aLBfVTh1hBp5IXqpeHpMrPE9WIT7vQ==",
|
||||
"engines": {
|
||||
"node": ">=16"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=18.0.0",
|
||||
"react-dom": ">=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/compiler-core": {
|
||||
"version": "3.2.45",
|
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.45.tgz",
|
||||
|
@ -6334,9 +6347,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/react-transition-state": {
|
||||
"version": "1.1.5",
|
||||
"resolved": "https://registry.npmjs.org/react-transition-state/-/react-transition-state-1.1.5.tgz",
|
||||
"integrity": "sha512-ITY2mZqc2dWG2eitJkYNdcSFW8aKeOlkL2A/vowRrLL8GH3J6Re/SpD/BLvQzrVOTqjsP0b5S9N10vgNNzwMUQ==",
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/react-transition-state/-/react-transition-state-2.1.0.tgz",
|
||||
"integrity": "sha512-b8ldw2pbZk++XM43vcD4ETaFWlzTsjpUX33CmT8BBPPFYlQ2R50wxcY4ZeJ1TesJYziYZ9/rNPFnyA9tR0iKDw==",
|
||||
"peerDependencies": {
|
||||
"react": ">=16.8.0",
|
||||
"react-dom": ">=16.8.0"
|
||||
|
@ -9619,12 +9632,12 @@
|
|||
}
|
||||
},
|
||||
"@szhsin/react-menu": {
|
||||
"version": "3.5.3",
|
||||
"resolved": "https://registry.npmjs.org/@szhsin/react-menu/-/react-menu-3.5.3.tgz",
|
||||
"integrity": "sha512-jxo8oaRwxmVjUzkyOi/ZJiXaZiuFPMIxFzyJdUKfnhBLYiEOVTU9M2CiPuEkirILoareR2GJj2K3y8a81CBPlw==",
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@szhsin/react-menu/-/react-menu-4.0.0.tgz",
|
||||
"integrity": "sha512-DOl+IWddgHofcEzSTJfILGvpU67O/y8r07LOVUhfThke9VEZ5LAZNkp2Q3mEFaN7PkmnmJtjPBEdIK3oN1/ZfQ==",
|
||||
"requires": {
|
||||
"prop-types": "^15.7.2",
|
||||
"react-transition-state": "^1.1.5"
|
||||
"react-transition-state": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"@trivago/prettier-plugin-sort-imports": {
|
||||
|
@ -9740,6 +9753,12 @@
|
|||
"integrity": "sha512-NfQ4gyz38SL8sDNrSixxU2Os1a5xcdFxipAFxYEuLUlvU2uDwS4NUpsImcf1//SlWItCVMMLiylsxbmNMToV/g==",
|
||||
"dev": true
|
||||
},
|
||||
"@uidotdev/usehooks": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@uidotdev/usehooks/-/usehooks-2.0.1.tgz",
|
||||
"integrity": "sha512-rJXxE3Y8g9utRbOS9Pj9tIvrnOdaakHIhLbMxBlErV8HydnGD0DveD82aLBfVTh1hBp5IXqpeHpMrPE9WIT7vQ==",
|
||||
"requires": {}
|
||||
},
|
||||
"@vue/compiler-core": {
|
||||
"version": "3.2.45",
|
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.45.tgz",
|
||||
|
@ -11832,9 +11851,9 @@
|
|||
}
|
||||
},
|
||||
"react-transition-state": {
|
||||
"version": "1.1.5",
|
||||
"resolved": "https://registry.npmjs.org/react-transition-state/-/react-transition-state-1.1.5.tgz",
|
||||
"integrity": "sha512-ITY2mZqc2dWG2eitJkYNdcSFW8aKeOlkL2A/vowRrLL8GH3J6Re/SpD/BLvQzrVOTqjsP0b5S9N10vgNNzwMUQ==",
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/react-transition-state/-/react-transition-state-2.1.0.tgz",
|
||||
"integrity": "sha512-b8ldw2pbZk++XM43vcD4ETaFWlzTsjpUX33CmT8BBPPFYlQ2R50wxcY4ZeJ1TesJYziYZ9/rNPFnyA9tR0iKDw==",
|
||||
"requires": {}
|
||||
},
|
||||
"regenerate": {
|
||||
|
|
|
@ -14,7 +14,8 @@
|
|||
"@github/text-expander-element": "~2.3.0",
|
||||
"@iconify-icons/mingcute": "~1.2.5",
|
||||
"@justinribeiro/lite-youtube": "~1.5.0",
|
||||
"@szhsin/react-menu": "~3.5.3",
|
||||
"@szhsin/react-menu": "~4.0.0",
|
||||
"@uidotdev/usehooks": "~2.0.1",
|
||||
"dayjs": "~1.11.8",
|
||||
"dayjs-twitter": "~0.5.0",
|
||||
"fast-blurhash": "~1.1.2",
|
||||
|
|
|
@ -673,7 +673,7 @@ function RelatedActions({ info, instance, authenticated }) {
|
|||
openTrigger="clickOnly"
|
||||
direction="bottom"
|
||||
overflow="auto"
|
||||
offsetX={-16}
|
||||
shift={-16}
|
||||
label={
|
||||
<>
|
||||
<Icon icon="mute" />
|
||||
|
|
|
@ -191,7 +191,7 @@ function MediaModal({
|
|||
align="end"
|
||||
position="anchor"
|
||||
boundingBoxPadding="8 8 8 8"
|
||||
offsetY={4}
|
||||
gap={4}
|
||||
menuClassName="glass-menu"
|
||||
menuButton={
|
||||
<button type="button" class="carousel-button plain3">
|
||||
|
|
31
src/components/menu2.jsx
Normal file
31
src/components/menu2.jsx
Normal file
|
@ -0,0 +1,31 @@
|
|||
import { Menu } from '@szhsin/react-menu';
|
||||
import { useWindowSize } from '@uidotdev/usehooks';
|
||||
import { useRef } from 'preact/hooks';
|
||||
|
||||
import safeBoundingBoxPadding from '../utils/safe-bounding-box-padding';
|
||||
|
||||
// It's like Menu but with sensible defaults, bug fixes and improvements.
|
||||
function Menu2(props) {
|
||||
const { containerProps } = props;
|
||||
const size = useWindowSize();
|
||||
const instanceRef = useRef();
|
||||
return (
|
||||
<Menu
|
||||
boundingBoxPadding={safeBoundingBoxPadding()}
|
||||
repositionFlag={`${size.width}x${size.height}`}
|
||||
{...props}
|
||||
instanceRef={instanceRef}
|
||||
containerProps={{
|
||||
onClick: (e) => {
|
||||
if (e.target === e.currentTarget) {
|
||||
instanceRef.current?.closeMenu?.();
|
||||
}
|
||||
containerProps?.onClick?.(e);
|
||||
},
|
||||
...containerProps,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export default Menu2;
|
|
@ -132,7 +132,7 @@ function Shortcuts() {
|
|||
viewScroll="close"
|
||||
boundingBoxPadding="8 8 8 8"
|
||||
menuClassName="glass-menu shortcuts-menu"
|
||||
offsetY={8}
|
||||
gap={8}
|
||||
position="anchor"
|
||||
menuButton={
|
||||
<button
|
||||
|
|
|
@ -34,6 +34,7 @@ import htmlContentLength from '../utils/html-content-length';
|
|||
import isMastodonLinkMaybe from '../utils/isMastodonLinkMaybe';
|
||||
import localeMatch from '../utils/locale-match';
|
||||
import niceDateTime from '../utils/nice-date-time';
|
||||
import safeBoundingBoxPadding from '../utils/safe-bounding-box-padding';
|
||||
import shortenNumber from '../utils/shorten-number';
|
||||
import showToast from '../utils/show-toast';
|
||||
import states, { getStatus, saveStatus, statusKey } from '../utils/states';
|
||||
|
@ -824,7 +825,7 @@ function Status({
|
|||
},
|
||||
}}
|
||||
align="end"
|
||||
offsetY={4}
|
||||
gap={4}
|
||||
overflow="auto"
|
||||
viewScroll="close"
|
||||
boundingBoxPadding="8 8 8 8"
|
||||
|
@ -1182,7 +1183,7 @@ function Status({
|
|||
document.querySelector('.status-deck') || document.body,
|
||||
}}
|
||||
align="end"
|
||||
offsetY={4}
|
||||
gap={4}
|
||||
overflow="auto"
|
||||
viewScroll="close"
|
||||
boundingBoxPadding="8 8 8 8"
|
||||
|
@ -1817,30 +1818,6 @@ const unfurlMastodonLink = throttle(
|
|||
}),
|
||||
);
|
||||
|
||||
const root = document.documentElement;
|
||||
const defaultBoundingBoxPadding = 8;
|
||||
function _safeBoundingBoxPadding() {
|
||||
// Get safe area inset variables from root
|
||||
const style = getComputedStyle(root);
|
||||
const safeAreaInsetTop = style.getPropertyValue('--sai-top');
|
||||
const safeAreaInsetRight = style.getPropertyValue('--sai-right');
|
||||
const safeAreaInsetBottom = style.getPropertyValue('--sai-bottom');
|
||||
const safeAreaInsetLeft = style.getPropertyValue('--sai-left');
|
||||
const str = [
|
||||
safeAreaInsetTop,
|
||||
safeAreaInsetRight,
|
||||
safeAreaInsetBottom,
|
||||
safeAreaInsetLeft,
|
||||
]
|
||||
.map((v) => parseInt(v, 10) || defaultBoundingBoxPadding)
|
||||
.join(' ');
|
||||
// console.log(str);
|
||||
return str;
|
||||
}
|
||||
const safeBoundingBoxPadding = mem(_safeBoundingBoxPadding, {
|
||||
maxAge: 10_000, // 10 seconds
|
||||
});
|
||||
|
||||
function FilteredStatus({ status, filterInfo, instance, containerProps = {} }) {
|
||||
const {
|
||||
account: { avatar, avatarStatic, bot },
|
||||
|
|
|
@ -6,6 +6,7 @@ import { useSnapshot } from 'valtio';
|
|||
import AccountInfo from '../components/account-info';
|
||||
import Icon from '../components/icon';
|
||||
import Link from '../components/link';
|
||||
import Menu2 from '../components/menu2';
|
||||
import Timeline from '../components/timeline';
|
||||
import { api } from '../utils/api';
|
||||
import emojifyText from '../utils/emojify-text';
|
||||
|
@ -255,15 +256,12 @@ function AccountStatuses() {
|
|||
timelineStart={TimelineStart}
|
||||
refresh={excludeReplies + excludeBoosts + tagged + media}
|
||||
headerEnd={
|
||||
<Menu
|
||||
portal={{
|
||||
target: document.body,
|
||||
}}
|
||||
<Menu2
|
||||
portal
|
||||
// setDownOverflow
|
||||
overflow="auto"
|
||||
viewScroll="close"
|
||||
position="anchor"
|
||||
boundingBoxPadding="8 8 8 8"
|
||||
menuButton={
|
||||
<button type="button" class="plain">
|
||||
<Icon icon="more" size="l" />
|
||||
|
@ -295,7 +293,7 @@ function AccountStatuses() {
|
|||
Switch to account's instance (<b>{accountInstance}</b>)
|
||||
</small>
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
</Menu2>
|
||||
}
|
||||
/>
|
||||
);
|
||||
|
|
|
@ -9,6 +9,7 @@ import { useEffect, useRef, useState } from 'preact/hooks';
|
|||
import { useNavigate, useParams } from 'react-router-dom';
|
||||
|
||||
import Icon from '../components/icon';
|
||||
import Menu2 from '../components/menu2';
|
||||
import Timeline from '../components/timeline';
|
||||
import { api } from '../utils/api';
|
||||
import showToast from '../utils/show-toast';
|
||||
|
@ -122,15 +123,12 @@ function Hashtags(props) {
|
|||
checkForUpdates={checkForUpdates}
|
||||
useItemID
|
||||
headerEnd={
|
||||
<Menu
|
||||
portal={{
|
||||
target: document.body,
|
||||
}}
|
||||
<Menu2
|
||||
portal
|
||||
setDownOverflow
|
||||
overflow="auto"
|
||||
viewScroll="close"
|
||||
position="anchor"
|
||||
boundingBoxPadding="8 8 8 8"
|
||||
menuButton={
|
||||
<button type="button" class="plain">
|
||||
<Icon icon="more" size="l" />
|
||||
|
@ -306,7 +304,7 @@ function Hashtags(props) {
|
|||
>
|
||||
<Icon icon="bus" /> <span>Go to another instance…</span>
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
</Menu2>
|
||||
}
|
||||
/>
|
||||
);
|
||||
|
|
|
@ -10,6 +10,7 @@ import AccountBlock from '../components/account-block';
|
|||
import Icon from '../components/icon';
|
||||
import Link from '../components/link';
|
||||
import ListAddEdit from '../components/list-add-edit';
|
||||
import Menu2 from '../components/menu2';
|
||||
import Modal from '../components/modal';
|
||||
import Timeline from '../components/timeline';
|
||||
import { api } from '../utils/api';
|
||||
|
@ -108,15 +109,12 @@ function List(props) {
|
|||
</Link>
|
||||
}
|
||||
headerEnd={
|
||||
<Menu
|
||||
portal={{
|
||||
target: document.body,
|
||||
}}
|
||||
<Menu2
|
||||
portal
|
||||
setDownOverflow
|
||||
overflow="auto"
|
||||
viewScroll="close"
|
||||
position="anchor"
|
||||
boundingBoxPadding="8 8 8 8"
|
||||
menuButton={
|
||||
<button type="button" class="plain">
|
||||
<Icon icon="more" size="l" />
|
||||
|
@ -137,7 +135,7 @@ function List(props) {
|
|||
<Icon icon="group" size="l" />
|
||||
<span>Manage members</span>
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
</Menu2>
|
||||
}
|
||||
/>
|
||||
{showListAddEditModal && (
|
||||
|
|
|
@ -4,6 +4,7 @@ import { useNavigate, useParams } from 'react-router-dom';
|
|||
import { useSnapshot } from 'valtio';
|
||||
|
||||
import Icon from '../components/icon';
|
||||
import Menu2 from '../components/menu2';
|
||||
import Timeline from '../components/timeline';
|
||||
import { api } from '../utils/api';
|
||||
import { filteredItems } from '../utils/filters';
|
||||
|
@ -92,15 +93,12 @@ function Public({ local, ...props }) {
|
|||
boostsCarousel={snapStates.settings.boostsCarousel}
|
||||
allowFilters
|
||||
headerEnd={
|
||||
<Menu
|
||||
portal={{
|
||||
target: document.body,
|
||||
}}
|
||||
<Menu2
|
||||
portal
|
||||
// setDownOverflow
|
||||
overflow="auto"
|
||||
viewScroll="close"
|
||||
position="anchor"
|
||||
boundingBoxPadding="8 8 8 8"
|
||||
menuButton={
|
||||
<button type="button" class="plain">
|
||||
<Icon icon="more" size="l" />
|
||||
|
@ -136,7 +134,7 @@ function Public({ local, ...props }) {
|
|||
>
|
||||
<Icon icon="bus" /> <span>Go to another instance…</span>
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
</Menu2>
|
||||
}
|
||||
/>
|
||||
);
|
||||
|
|
|
@ -4,6 +4,7 @@ import { useNavigate, useParams } from 'react-router-dom';
|
|||
import { useSnapshot } from 'valtio';
|
||||
|
||||
import Icon from '../components/icon';
|
||||
import Menu2 from '../components/menu2';
|
||||
import Timeline from '../components/timeline';
|
||||
import { api } from '../utils/api';
|
||||
import { filteredItems } from '../utils/filters';
|
||||
|
@ -92,15 +93,12 @@ function Trending(props) {
|
|||
boostsCarousel={snapStates.settings.boostsCarousel}
|
||||
allowFilters
|
||||
headerEnd={
|
||||
<Menu
|
||||
portal={{
|
||||
target: document.body,
|
||||
}}
|
||||
<Menu2
|
||||
portal
|
||||
// setDownOverflow
|
||||
overflow="auto"
|
||||
viewScroll="close"
|
||||
position="anchor"
|
||||
boundingBoxPadding="8 8 8 8"
|
||||
menuButton={
|
||||
<button type="button" class="plain">
|
||||
<Icon icon="more" size="l" />
|
||||
|
@ -124,7 +122,7 @@ function Trending(props) {
|
|||
>
|
||||
<Icon icon="bus" /> <span>Go to another instance…</span>
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
</Menu2>
|
||||
}
|
||||
/>
|
||||
);
|
||||
|
|
27
src/utils/safe-bounding-box-padding.jsx
Normal file
27
src/utils/safe-bounding-box-padding.jsx
Normal file
|
@ -0,0 +1,27 @@
|
|||
import mem from 'mem';
|
||||
|
||||
const root = document.documentElement;
|
||||
const defaultBoundingBoxPadding = 8;
|
||||
function _safeBoundingBoxPadding() {
|
||||
// Get safe area inset variables from root
|
||||
const style = getComputedStyle(root);
|
||||
const safeAreaInsetTop = style.getPropertyValue('--sai-top');
|
||||
const safeAreaInsetRight = style.getPropertyValue('--sai-right');
|
||||
const safeAreaInsetBottom = style.getPropertyValue('--sai-bottom');
|
||||
const safeAreaInsetLeft = style.getPropertyValue('--sai-left');
|
||||
const str = [
|
||||
safeAreaInsetTop,
|
||||
safeAreaInsetRight,
|
||||
safeAreaInsetBottom,
|
||||
safeAreaInsetLeft,
|
||||
]
|
||||
.map((v) => parseInt(v, 10) || defaultBoundingBoxPadding)
|
||||
.join(' ');
|
||||
// console.log(str);
|
||||
return str;
|
||||
}
|
||||
const safeBoundingBoxPadding = mem(_safeBoundingBoxPadding, {
|
||||
maxAge: 10000, // 10 seconds
|
||||
});
|
||||
|
||||
export default safeBoundingBoxPadding;
|
Loading…
Reference in a new issue