Merge pull request #327 from cheeaun/main

Update from main
This commit is contained in:
Chee Aun 2023-11-20 13:29:33 +08:00 committed by GitHub
commit 0f537667d8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 36 additions and 36 deletions

View file

@ -1577,7 +1577,7 @@ body > .szh-menu-container {
position: fixed !important; position: fixed !important;
z-index: 10; z-index: 10;
} }
.szh-menu-container:has(.szh-menu--state-open) { .szh-menu-container:not(:empty) {
inset: 0; inset: 0;
inset: env(safe-area-inset-top) env(safe-area-inset-right) inset: env(safe-area-inset-top) env(safe-area-inset-right)
env(safe-area-inset-bottom) env(safe-area-inset-left); env(safe-area-inset-bottom) env(safe-area-inset-left);

View file

@ -29,6 +29,7 @@ import Icon from './icon';
import Link from './link'; import Link from './link';
import ListAddEdit from './list-add-edit'; import ListAddEdit from './list-add-edit';
import Loader from './loader'; import Loader from './loader';
import Menu2 from './menu2';
import MenuConfirm from './menu-confirm'; import MenuConfirm from './menu-confirm';
import Modal from './modal'; import Modal from './modal';
import TranslationBlock from './translation-block'; import TranslationBlock from './translation-block';
@ -906,7 +907,6 @@ function RelatedActions({
}, [info, isSelf]); }, [info, isSelf]);
const loading = relationshipUIState === 'loading'; const loading = relationshipUIState === 'loading';
const menuInstanceRef = useRef(null);
const [showTranslatedBio, setShowTranslatedBio] = useState(false); const [showTranslatedBio, setShowTranslatedBio] = useState(false);
const [showAddRemoveLists, setShowAddRemoveLists] = useState(false); const [showAddRemoveLists, setShowAddRemoveLists] = useState(false);
@ -947,8 +947,7 @@ function RelatedActions({
<span>{privateNote}</span> <span>{privateNote}</span>
</button> </button>
)} )}
<Menu <Menu2
instanceRef={menuInstanceRef}
portal={{ portal={{
target: document.body, target: document.body,
}} }}
@ -957,16 +956,10 @@ function RelatedActions({
// Higher than the backdrop // Higher than the backdrop
zIndex: 1001, zIndex: 1001,
}, },
onClick: (e) => {
if (e.target === e.currentTarget) {
menuInstanceRef.current?.closeMenu?.();
}
},
}} }}
align="center" align="center"
position="anchor" position="anchor"
overflow="auto" overflow="auto"
boundingBoxPadding="8 8 8 8"
menuButton={ menuButton={
<button <button
type="button" type="button"
@ -1215,7 +1208,7 @@ function RelatedActions({
</MenuItem> */} </MenuItem> */}
</> </>
)} )}
</Menu> </Menu2>
{!relationship && relationshipUIState === 'loading' && ( {!relationship && relationshipUIState === 'loading' && (
<Loader abrupt /> <Loader abrupt />
)} )}

View file

@ -107,20 +107,20 @@ function countableText(inputText) {
// https://github.com/mastodon/mastodon/blob/c03bd2a238741a012aa4b98dc4902d6cf948ab63/app/models/account.rb#L69 // https://github.com/mastodon/mastodon/blob/c03bd2a238741a012aa4b98dc4902d6cf948ab63/app/models/account.rb#L69
const USERNAME_RE = /[a-z0-9_]+([a-z0-9_.-]+[a-z0-9_]+)?/i; const USERNAME_RE = /[a-z0-9_]+([a-z0-9_.-]+[a-z0-9_]+)?/i;
const MENTION_RE = new RegExp( const MENTION_RE = new RegExp(
`(?<![=\\/\\w])@((${USERNAME_RE.source})(?:@[\\w.-]+[\\w]+)?)`, `(^|[^=\\/\\w])(@${USERNAME_RE.source}(?:@[\\w.-]+[\\w]+)?)`,
'ig', 'ig',
); );
// AI-generated, all other regexes are too complicated // AI-generated, all other regexes are too complicated
const HASHTAG_RE = new RegExp( const HASHTAG_RE = new RegExp(
`(?<![=\\/\\w])#([a-z0-9_]+([a-z0-9_.-]+[a-z0-9_]+)?)(?![\\/\\w])`, `(^|[^=\\/\\w])(#[a-z0-9_]+([a-z0-9_.-]+[a-z0-9_]+)?)(?![\\/\\w])`,
'ig', 'ig',
); );
// https://github.com/mastodon/mastodon/blob/23e32a4b3031d1da8b911e0145d61b4dd47c4f96/app/models/custom_emoji.rb#L31 // https://github.com/mastodon/mastodon/blob/23e32a4b3031d1da8b911e0145d61b4dd47c4f96/app/models/custom_emoji.rb#L31
const SHORTCODE_RE_FRAGMENT = '[a-zA-Z0-9_]{2,}'; const SHORTCODE_RE_FRAGMENT = '[a-zA-Z0-9_]{2,}';
const SCAN_RE = new RegExp( const SCAN_RE = new RegExp(
`(?<=[^A-Za-z0-9_:\\n]|^):(${SHORTCODE_RE_FRAGMENT}):(?=[^A-Za-z0-9_:]|$)`, `([^A-Za-z0-9_:\\n]|^)(:${SHORTCODE_RE_FRAGMENT}:)(?=[^A-Za-z0-9_:]|$)`,
'g', 'g',
); );
@ -142,11 +142,11 @@ function highlightText(text, { maxCharacters = Infinity }) {
html = html html = html
.replace(urlRegexObj, '$2<mark class="compose-highlight-url">$3</mark>') // URLs .replace(urlRegexObj, '$2<mark class="compose-highlight-url">$3</mark>') // URLs
.replace(MENTION_RE, '<mark class="compose-highlight-mention">$&</mark>') // Mentions .replace(MENTION_RE, '$1<mark class="compose-highlight-mention">$2</mark>') // Mentions
.replace(HASHTAG_RE, '<mark class="compose-highlight-hashtag">#$1</mark>') // Hashtags .replace(HASHTAG_RE, '$1<mark class="compose-highlight-hashtag">$2</mark>') // Hashtags
.replace( .replace(
SCAN_RE, SCAN_RE,
'<mark class="compose-highlight-emoji-shortcode">$&</mark>', '$1<mark class="compose-highlight-emoji-shortcode">$2</mark>',
); // Emoji shortcodes ); // Emoji shortcodes
return html + leftoverHTML; return html + leftoverHTML;
@ -1474,8 +1474,10 @@ const Textarea = forwardRef((props, ref) => {
if (!textarea) return; if (!textarea) return;
const resizeObserver = new ResizeObserver(() => { const resizeObserver = new ResizeObserver(() => {
// Get height of textarea, set height to textExpander // Get height of textarea, set height to textExpander
if (textExpanderRef.current) {
const { height } = textarea.getBoundingClientRect(); const { height } = textarea.getBoundingClientRect();
textExpanderRef.current.style.height = height + 'px'; textExpanderRef.current.style.height = height + 'px';
}
}); });
resizeObserver.observe(textarea); resizeObserver.observe(textarea);
}, []); }, []);

View file

@ -7,6 +7,7 @@ import localeMatch from '../utils/locale-match';
import states from '../utils/states'; import states from '../utils/states';
import Icon from './icon'; import Icon from './icon';
import Menu2 from './menu2';
import TranslationBlock from './translation-block'; import TranslationBlock from './translation-block';
export default function MediaAltModal({ alt, lang, onClose }) { export default function MediaAltModal({ alt, lang, onClose }) {
@ -33,7 +34,7 @@ export default function MediaAltModal({ alt, lang, onClose }) {
<header class="header-grid"> <header class="header-grid">
<h2>Media description</h2> <h2>Media description</h2>
<div class="header-side"> <div class="header-side">
<Menu <Menu2
align="end" align="end"
menuButton={ menuButton={
<button type="button" class="plain4"> <button type="button" class="plain4">
@ -50,7 +51,7 @@ export default function MediaAltModal({ alt, lang, onClose }) {
<Icon icon="translate" /> <Icon icon="translate" />
<span>Translate</span> <span>Translate</span>
</MenuItem> </MenuItem>
</Menu> </Menu2>
</div> </div>
</header> </header>
<main lang={lang} dir="auto"> <main lang={lang} dir="auto">

View file

@ -15,6 +15,7 @@ import states from '../utils/states';
import Icon from './icon'; import Icon from './icon';
import Link from './link'; import Link from './link';
import Media from './media'; import Media from './media';
import Menu2 from './menu2';
import MenuLink from './menu-link'; import MenuLink from './menu-link';
function MediaModal({ function MediaModal({
@ -259,11 +260,10 @@ function MediaModal({
<span /> <span />
)} )}
<span> <span>
<Menu <Menu2
overflow="auto" overflow="auto"
align="end" align="end"
position="anchor" position="anchor"
boundingBoxPadding="8 8 8 8"
gap={4} gap={4}
menuClassName="glass-menu" menuClassName="glass-menu"
menuButton={ menuButton={
@ -284,7 +284,7 @@ function MediaModal({
<Icon icon="popout" /> <Icon icon="popout" />
<span>Open original media</span> <span>Open original media</span>
</MenuLink> </MenuLink>
</Menu>{' '} </Menu2>{' '}
<Link <Link
to={`${instance ? `/${instance}` : ''}/s/${statusID}${ to={`${instance ? `/${instance}` : ''}/s/${statusID}${
window.matchMedia('(min-width: calc(40em + 350px))').matches window.matchMedia('(min-width: calc(40em + 350px))').matches

View file

@ -6,13 +6,15 @@ import safeBoundingBoxPadding from '../utils/safe-bounding-box-padding';
// It's like Menu but with sensible defaults, bug fixes and improvements. // It's like Menu but with sensible defaults, bug fixes and improvements.
function Menu2(props) { function Menu2(props) {
const { containerProps } = props; const { containerProps, instanceRef: _instanceRef } = props;
const size = useWindowSize(); const size = useWindowSize();
const instanceRef = useRef(); const instanceRef = _instanceRef?.current ? _instanceRef : useRef();
return ( return (
<Menu <Menu
boundingBoxPadding={safeBoundingBoxPadding()} boundingBoxPadding={safeBoundingBoxPadding()}
repositionFlag={`${size.width}x${size.height}`} repositionFlag={`${size.width}x${size.height}`}
unmountOnClose
{...props} {...props}
instanceRef={instanceRef} instanceRef={instanceRef}
containerProps={{ containerProps={{

View file

@ -14,6 +14,7 @@ import states from '../utils/states';
import AsyncText from './AsyncText'; import AsyncText from './AsyncText';
import Icon from './icon'; import Icon from './icon';
import Link from './link'; import Link from './link';
import Menu2 from './menu2';
import MenuLink from './menu-link'; import MenuLink from './menu-link';
function Shortcuts() { function Shortcuts() {
@ -139,11 +140,10 @@ function Shortcuts() {
</ul> </ul>
</nav> </nav>
) : ( ) : (
<Menu <Menu2
instanceRef={menuRef} instanceRef={menuRef}
overflow="auto" overflow="auto"
viewScroll="close" viewScroll="close"
boundingBoxPadding="8 8 8 8"
menuClassName="glass-menu shortcuts-menu" menuClassName="glass-menu shortcuts-menu"
gap={8} gap={8}
position="anchor" position="anchor"
@ -195,7 +195,7 @@ function Shortcuts() {
</MenuLink> </MenuLink>
); );
})} })}
</Menu> </Menu2>
)} )}
</div> </div>
); );

View file

@ -28,6 +28,7 @@ import { snapshot } from 'valtio/vanilla';
import AccountBlock from '../components/account-block'; import AccountBlock from '../components/account-block';
import EmojiText from '../components/emoji-text'; import EmojiText from '../components/emoji-text';
import Loader from '../components/loader'; import Loader from '../components/loader';
import Menu2 from '../components/menu2';
import MenuConfirm from '../components/menu-confirm'; import MenuConfirm from '../components/menu-confirm';
import Modal from '../components/modal'; import Modal from '../components/modal';
import NameText from '../components/name-text'; import NameText from '../components/name-text';
@ -1629,7 +1630,7 @@ function Status({
onClick={bookmarkStatus} onClick={bookmarkStatus}
/> />
</div> </div>
<Menu <Menu2
portal={{ portal={{
target: target:
document.querySelector('.status-deck') || document.body, document.querySelector('.status-deck') || document.body,
@ -1638,7 +1639,6 @@ function Status({
gap={4} gap={4}
overflow="auto" overflow="auto"
viewScroll="close" viewScroll="close"
boundingBoxPadding="8 8 8 8"
menuButton={ menuButton={
<div class="action"> <div class="action">
<button <button
@ -1652,7 +1652,7 @@ function Status({
} }
> >
{StatusMenuItems} {StatusMenuItems}
</Menu> </Menu2>
</div> </div>
</> </>
)} )}

View file

@ -7,6 +7,7 @@ import { useReducer } from 'preact/hooks';
import Avatar from '../components/avatar'; import Avatar from '../components/avatar';
import Icon from '../components/icon'; import Icon from '../components/icon';
import Link from '../components/link'; import Link from '../components/link';
import Menu2 from '../components/menu2';
import MenuConfirm from '../components/menu-confirm'; import MenuConfirm from '../components/menu-confirm';
import NameText from '../components/name-text'; import NameText from '../components/name-text';
import { api } from '../utils/api'; import { api } from '../utils/api';
@ -92,7 +93,7 @@ function Accounts({ onClose }) {
<span class="tag">Default</span>{' '} <span class="tag">Default</span>{' '}
</> </>
)} )}
<Menu <Menu2
align="end" align="end"
menuButton={ menuButton={
<button <button
@ -150,7 +151,7 @@ function Accounts({ onClose }) {
<Icon icon="exit" /> <Icon icon="exit" />
<span>Log out</span> <span>Log out</span>
</MenuConfirm> </MenuConfirm>
</Menu> </Menu2>
</div> </div>
</li> </li>
); );

View file

@ -23,6 +23,7 @@ import Icon from '../components/icon';
import Link from '../components/link'; import Link from '../components/link';
import Loader from '../components/loader'; import Loader from '../components/loader';
import MediaModal from '../components/media-modal'; import MediaModal from '../components/media-modal';
import Menu2 from '../components/menu2';
import NameText from '../components/name-text'; import NameText from '../components/name-text';
import RelativeTime from '../components/relative-time'; import RelativeTime from '../components/relative-time';
import Status from '../components/status'; import Status from '../components/status';
@ -1034,7 +1035,7 @@ function StatusThread({ id, closeLink = '/', instance: propInstance }) {
> >
<Icon icon="layout4" size="l" /> <Icon icon="layout4" size="l" />
</button> </button>
<Menu <Menu2
align="end" align="end"
portal={{ portal={{
// Need this, else the menu click will cause scroll jump // Need this, else the menu click will cause scroll jump
@ -1114,7 +1115,7 @@ function StatusThread({ id, closeLink = '/', instance: propInstance }) {
Switch to post's instance (<b>{postInstance}</b>) Switch to post's instance (<b>{postInstance}</b>)
</small> </small>
</MenuItem> </MenuItem>
</Menu> </Menu2>
<Link class="button plain deck-close" to={closeLink}> <Link class="button plain deck-close" to={closeLink}>
<Icon icon="x" size="xl" /> <Icon icon="x" size="xl" />
</Link> </Link>