mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
perf(reply-modal): fix laggy dragging during post loading with GPU-accelerated gestures
This commit is contained in:
@@ -9,6 +9,7 @@
|
|||||||
"@capacitor/app": "6.0.1",
|
"@capacitor/app": "6.0.1",
|
||||||
"@floating-ui/react": "0.26.1",
|
"@floating-ui/react": "0.26.1",
|
||||||
"@plebbit/plebbit-react-hooks": "https://github.com/plebbit/plebbit-react-hooks.git#6d35eb3b4dc84f8fdcbb46d95e3b1d78f1750b5f",
|
"@plebbit/plebbit-react-hooks": "https://github.com/plebbit/plebbit-react-hooks.git#6d35eb3b4dc84f8fdcbb46d95e3b1d78f1750b5f",
|
||||||
|
"@react-spring/web": "9.7.5",
|
||||||
"@testing-library/jest-dom": "5.14.1",
|
"@testing-library/jest-dom": "5.14.1",
|
||||||
"@testing-library/react": "13.0.0",
|
"@testing-library/react": "13.0.0",
|
||||||
"@testing-library/user-event": "13.2.1",
|
"@testing-library/user-event": "13.2.1",
|
||||||
@@ -16,6 +17,7 @@
|
|||||||
"@types/node": "20.8.2",
|
"@types/node": "20.8.2",
|
||||||
"@types/react": "18.2.25",
|
"@types/react": "18.2.25",
|
||||||
"@types/react-dom": "18.2.10",
|
"@types/react-dom": "18.2.10",
|
||||||
|
"@use-gesture/react": "10.3.1",
|
||||||
"cross-env": "7.0.3",
|
"cross-env": "7.0.3",
|
||||||
"electron-context-menu": "3.3.0",
|
"electron-context-menu": "3.3.0",
|
||||||
"electron-is-dev": "2.0.0",
|
"electron-is-dev": "2.0.0",
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
.container {
|
.container {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: calc(50% - 150px);
|
|
||||||
left: calc(50% - 150px);
|
|
||||||
display: block;
|
display: block;
|
||||||
padding: 2px;
|
padding: 2px;
|
||||||
font-size: 10pt;
|
font-size: 10pt;
|
||||||
@@ -10,6 +8,9 @@
|
|||||||
z-index: 3;
|
z-index: 3;
|
||||||
background-color: var(--challenge-modal-background-color);
|
background-color: var(--challenge-modal-background-color);
|
||||||
border: var(--challenge-modal-border);
|
border: var(--challenge-modal-border);
|
||||||
|
will-change: transform;
|
||||||
|
backface-visibility: hidden;
|
||||||
|
-webkit-backface-visibility: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
@@ -24,6 +25,9 @@
|
|||||||
background-color: var(--challenge-modal-title-background-color);
|
background-color: var(--challenge-modal-title-background-color);
|
||||||
color: var(--challenge-modal-title-text-color);
|
color: var(--challenge-modal-title-text-color);
|
||||||
border: var(--challenge-modal-title-border);
|
border: var(--challenge-modal-title-border);
|
||||||
|
user-select: none;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
touch-action: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.closeIcon {
|
.closeIcon {
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||||
import { useLocation, useParams } from 'react-router-dom';
|
import { useLocation, useParams } from 'react-router-dom';
|
||||||
import { Trans, useTranslation } from 'react-i18next';
|
import { Trans, useTranslation } from 'react-i18next';
|
||||||
import Draggable from 'react-draggable';
|
|
||||||
import { setAccount, useAccount, useComment, useSubplebbit } from '@plebbit/plebbit-react-hooks';
|
import { setAccount, useAccount, useComment, useSubplebbit } from '@plebbit/plebbit-react-hooks';
|
||||||
import Plebbit from '@plebbit/plebbit-js/dist/browser/index.js';
|
import Plebbit from '@plebbit/plebbit-js/dist/browser/index.js';
|
||||||
import { formatMarkdown } from '../../lib/utils/post-utils';
|
import { formatMarkdown } from '../../lib/utils/post-utils';
|
||||||
@@ -17,6 +16,8 @@ import _ from 'lodash';
|
|||||||
import useAnonMode from '../../hooks/use-anon-mode';
|
import useAnonMode from '../../hooks/use-anon-mode';
|
||||||
import FileUploader from '../../plugins/file-uploader';
|
import FileUploader from '../../plugins/file-uploader';
|
||||||
import { Capacitor } from '@capacitor/core';
|
import { Capacitor } from '@capacitor/core';
|
||||||
|
import { useSpring, animated } from '@react-spring/web';
|
||||||
|
import { useDrag } from '@use-gesture/react';
|
||||||
|
|
||||||
const isAndroid = Capacitor.getPlatform() === 'android';
|
const isAndroid = Capacitor.getPlatform() === 'android';
|
||||||
|
|
||||||
@@ -144,14 +145,32 @@ const ReplyModal = ({ closeModal, showReplyModal, parentCid, postCid, scrollY, s
|
|||||||
const nodeRef = useRef<HTMLDivElement>(null);
|
const nodeRef = useRef<HTMLDivElement>(null);
|
||||||
const isMobile = useIsMobile();
|
const isMobile = useIsMobile();
|
||||||
|
|
||||||
|
const [{ x, y }, api] = useSpring(() => ({ x: 0, y: 0 }));
|
||||||
|
|
||||||
|
const bind = useDrag(
|
||||||
|
({ offset: [ox, oy], first, last }) => {
|
||||||
|
api.start({ x: ox, y: oy, immediate: true });
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: () => [x.get(), y.get()],
|
||||||
|
filterTaps: true,
|
||||||
|
bounds: {
|
||||||
|
left: -300,
|
||||||
|
right: window.innerWidth - 100,
|
||||||
|
top: 0,
|
||||||
|
bottom: window.innerHeight - 100,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (nodeRef.current && isMobile) {
|
if (nodeRef.current && isMobile) {
|
||||||
const viewportHeight = window.innerHeight;
|
const viewportHeight = window.innerHeight;
|
||||||
const modalHeight = 150;
|
const modalHeight = 150;
|
||||||
const centeredPosition = scrollY + viewportHeight / 2 - modalHeight / 2;
|
const centeredPosition = scrollY + viewportHeight / 2 - modalHeight / 2;
|
||||||
nodeRef.current.style.top = `${centeredPosition}px`;
|
api.start({ y: centeredPosition, immediate: true });
|
||||||
}
|
}
|
||||||
}, [isMobile, scrollY]);
|
}, [isMobile, scrollY, api]);
|
||||||
|
|
||||||
const parentCidRef = useRef<HTMLSpanElement>(null);
|
const parentCidRef = useRef<HTMLSpanElement>(null);
|
||||||
|
|
||||||
@@ -275,8 +294,16 @@ const ReplyModal = ({ closeModal, showReplyModal, parentCid, postCid, scrollY, s
|
|||||||
}, [displayName, setPublishReplyOptions]);
|
}, [displayName, setPublishReplyOptions]);
|
||||||
|
|
||||||
const modalContent = (
|
const modalContent = (
|
||||||
<div className={styles.container} ref={nodeRef}>
|
<animated.div
|
||||||
<div className={`replyModalHandle ${styles.title}`}>
|
className={styles.container}
|
||||||
|
ref={nodeRef}
|
||||||
|
style={{
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
touchAction: 'none',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className={`replyModalHandle ${styles.title}`} {...(!isMobile ? bind() : {})}>
|
||||||
{t('reply_to_cid', { cid: `c/${parentCid && Plebbit.getShortCid(parentCid)}`, interpolation: { escapeValue: false } })}
|
{t('reply_to_cid', { cid: `c/${parentCid && Plebbit.getShortCid(parentCid)}`, interpolation: { escapeValue: false } })}
|
||||||
<button
|
<button
|
||||||
className={styles.closeIcon}
|
className={styles.closeIcon}
|
||||||
@@ -346,19 +373,10 @@ const ReplyModal = ({ closeModal, showReplyModal, parentCid, postCid, scrollY, s
|
|||||||
{lengthError ? <div className={styles.error}>{lengthError}</div> : error && <div className={styles.error}>{error}</div>}
|
{lengthError ? <div className={styles.error}>{lengthError}</div> : error && <div className={styles.error}>{error}</div>}
|
||||||
{!(isInAllView || isInSubscriptionsView) && offlineAlert}
|
{!(isInAllView || isInSubscriptionsView) && offlineAlert}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</animated.div>
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return showReplyModal && modalContent;
|
||||||
showReplyModal &&
|
|
||||||
(isMobile ? (
|
|
||||||
modalContent
|
|
||||||
) : (
|
|
||||||
<Draggable handle='.replyModalHandle' nodeRef={nodeRef}>
|
|
||||||
{modalContent}
|
|
||||||
</Draggable>
|
|
||||||
))
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ReplyModal;
|
export default ReplyModal;
|
||||||
|
|||||||
@@ -3412,6 +3412,51 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570"
|
resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570"
|
||||||
integrity sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==
|
integrity sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==
|
||||||
|
|
||||||
|
"@react-spring/animated@~9.7.5":
|
||||||
|
version "9.7.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/@react-spring/animated/-/animated-9.7.5.tgz#eb0373aaf99b879736b380c2829312dae3b05f28"
|
||||||
|
integrity sha512-Tqrwz7pIlsSDITzxoLS3n/v/YCUHQdOIKtOJf4yL6kYVSDTSmVK1LI1Q3M/uu2Sx4X3pIWF3xLUhlsA6SPNTNg==
|
||||||
|
dependencies:
|
||||||
|
"@react-spring/shared" "~9.7.5"
|
||||||
|
"@react-spring/types" "~9.7.5"
|
||||||
|
|
||||||
|
"@react-spring/core@~9.7.5":
|
||||||
|
version "9.7.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/@react-spring/core/-/core-9.7.5.tgz#72159079f52c1c12813d78b52d4f17c0bf6411f7"
|
||||||
|
integrity sha512-rmEqcxRcu7dWh7MnCcMXLvrf6/SDlSokLaLTxiPlAYi11nN3B5oiCUAblO72o+9z/87j2uzxa2Inm8UbLjXA+w==
|
||||||
|
dependencies:
|
||||||
|
"@react-spring/animated" "~9.7.5"
|
||||||
|
"@react-spring/shared" "~9.7.5"
|
||||||
|
"@react-spring/types" "~9.7.5"
|
||||||
|
|
||||||
|
"@react-spring/rafz@~9.7.5":
|
||||||
|
version "9.7.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/@react-spring/rafz/-/rafz-9.7.5.tgz#ee7959676e7b5d6a3813e8c17d5e50df98b95df9"
|
||||||
|
integrity sha512-5ZenDQMC48wjUzPAm1EtwQ5Ot3bLIAwwqP2w2owG5KoNdNHpEJV263nGhCeKKmuA3vG2zLLOdu3or6kuDjA6Aw==
|
||||||
|
|
||||||
|
"@react-spring/shared@~9.7.5":
|
||||||
|
version "9.7.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/@react-spring/shared/-/shared-9.7.5.tgz#6d513622df6ad750bbbd4dedb4ca0a653ec92073"
|
||||||
|
integrity sha512-wdtoJrhUeeyD/PP/zo+np2s1Z820Ohr/BbuVYv+3dVLW7WctoiN7std8rISoYoHpUXtbkpesSKuPIw/6U1w1Pw==
|
||||||
|
dependencies:
|
||||||
|
"@react-spring/rafz" "~9.7.5"
|
||||||
|
"@react-spring/types" "~9.7.5"
|
||||||
|
|
||||||
|
"@react-spring/types@~9.7.5":
|
||||||
|
version "9.7.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/@react-spring/types/-/types-9.7.5.tgz#e5dd180f3ed985b44fd2cd2f32aa9203752ef3e8"
|
||||||
|
integrity sha512-HVj7LrZ4ReHWBimBvu2SKND3cDVUPWKLqRTmWe/fNY6o1owGOX0cAHbdPDTMelgBlVbrTKrre6lFkhqGZErK/g==
|
||||||
|
|
||||||
|
"@react-spring/web@^9.7.5":
|
||||||
|
version "9.7.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/@react-spring/web/-/web-9.7.5.tgz#7d7782560b3a6fb9066b52824690da738605de80"
|
||||||
|
integrity sha512-lmvqGwpe+CSttsWNZVr+Dg62adtKhauGwLyGE/RRyZ8AAMLgb9x3NDMA5RMElXo+IMyTkPp7nxTB8ZQlmhb6JQ==
|
||||||
|
dependencies:
|
||||||
|
"@react-spring/animated" "~9.7.5"
|
||||||
|
"@react-spring/core" "~9.7.5"
|
||||||
|
"@react-spring/shared" "~9.7.5"
|
||||||
|
"@react-spring/types" "~9.7.5"
|
||||||
|
|
||||||
"@remix-run/router@1.9.0":
|
"@remix-run/router@1.9.0":
|
||||||
version "1.9.0"
|
version "1.9.0"
|
||||||
resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.9.0.tgz#9033238b41c4cbe1e961eccb3f79e2c588328cf6"
|
resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.9.0.tgz#9033238b41c4cbe1e961eccb3f79e2c588328cf6"
|
||||||
@@ -4471,6 +4516,18 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.1.tgz#28fa185f67daaf7b7a1a8c1d445132c5d979f8bd"
|
resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.1.tgz#28fa185f67daaf7b7a1a8c1d445132c5d979f8bd"
|
||||||
integrity sha512-fEzPV3hSkSMltkw152tJKNARhOupqbH96MZWyRjNaYZOMIzbrTeQDG+MTc6Mr2pgzFQzFxAfmhGDNP5QK++2ZA==
|
integrity sha512-fEzPV3hSkSMltkw152tJKNARhOupqbH96MZWyRjNaYZOMIzbrTeQDG+MTc6Mr2pgzFQzFxAfmhGDNP5QK++2ZA==
|
||||||
|
|
||||||
|
"@use-gesture/core@10.3.1":
|
||||||
|
version "10.3.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@use-gesture/core/-/core-10.3.1.tgz#976c9421e905f0079d49822cfd5c2e56b808fc56"
|
||||||
|
integrity sha512-WcINiDt8WjqBdUXye25anHiNxPc0VOrlT8F6LLkU6cycrOGUDyY/yyFmsg3k8i5OLvv25llc0QC45GhR/C8llw==
|
||||||
|
|
||||||
|
"@use-gesture/react@^10.3.1":
|
||||||
|
version "10.3.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@use-gesture/react/-/react-10.3.1.tgz#17a743a894d9bd9a0d1980c618f37f0164469867"
|
||||||
|
integrity sha512-Yy19y6O2GJq8f7CHf7L0nxL8bf4PZCPaVOCgJrusOeFHY1LvHgYXnmnXg6N5iwAnbgbZCDjo60SiM6IPJi9C5g==
|
||||||
|
dependencies:
|
||||||
|
"@use-gesture/core" "10.3.1"
|
||||||
|
|
||||||
"@webassemblyjs/ast@1.14.1", "@webassemblyjs/ast@^1.14.1":
|
"@webassemblyjs/ast@1.14.1", "@webassemblyjs/ast@^1.14.1":
|
||||||
version "1.14.1"
|
version "1.14.1"
|
||||||
resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.14.1.tgz#a9f6a07f2b03c95c8d38c4536a1fdfb521ff55b6"
|
resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.14.1.tgz#a9f6a07f2b03c95c8d38c4536a1fdfb521ff55b6"
|
||||||
|
|||||||
Reference in New Issue
Block a user