1
0
Fork 0
mirror of https://github.com/anyproto/anytype-ts.git synced 2025-06-08 05:57:02 +09:00

code-review

This commit is contained in:
Andrew Simachev 2024-11-01 09:47:12 +01:00
parent fca3c382b4
commit 75bf48024a
No known key found for this signature in database
GPG key ID: 1DFE44B21443F0EF
10 changed files with 67 additions and 57 deletions

1
dist/index.html vendored
View file

@ -5,7 +5,6 @@
<title>Anytype</title>
</head>
<body>
<div id="floater-root"></div>
<div id="root"></div>
<script src="./js/run.js" type="text/javascript"></script>

1
dist/index.web.html vendored
View file

@ -20,7 +20,6 @@
<script src="./js/polyfill.js" type="text/javascript"></script>
</head>
<body onload="onload();">
<div id="floater-root"></div>
<div id="root"></div>
<script src="./js/run.js" type="text/javascript"></script>
<script type="text/javascript">

View file

@ -1,3 +1,2 @@
.floater { position: absolute; pointer-events: none; z-index: 200; }
.floater.show > * { opacity: 1; pointer-events: auto; transition: opacity 0.2s ease-in-out; }
.floater.hide > * { opacity: 0; pointer-events: none; transition: opacity 0.2s ease-in-out; }
.floater { position: absolute; pointer-events: none; z-index: 200; transition: opacity 0.2s ease-in-out; opacity: 0; }
.floater.show { opacity: 1; pointer-events: auto; }

View file

@ -193,7 +193,9 @@ class App extends React.Component<object, State> {
) : ''}
{drag}
<div id="floaterContainer" />
<div id="tooltipContainer" />
<div id="globalFade">
<Loader id="loader" />
</div>

View file

@ -2,13 +2,12 @@ import { H } from 'Lib';
import React, { useState, useEffect, ReactNode, useRef } from 'react';
import ReactDOM from 'react-dom';
interface Props {
children: ReactNode;
anchorEl: HTMLElement | null;
gap?: number;
isShown?: boolean;
}
};
export const Floater: React.FC<Props> = ({
children,
@ -18,42 +17,50 @@ export const Floater: React.FC<Props> = ({
}) => {
const ref = useRef<HTMLDivElement>(null);
const [ position, setPosition ] = useState({ top: 0, left: 0 });
const cn = [ 'floater' ];
if (isShown) {
cn.push('show');
};
const onMove = () => {
if (anchorEl && ref.current) {
const anchorElRect = anchorEl.getBoundingClientRect();
const elRect = ref.current.getBoundingClientRect();
const { top: at, left: al, width: aw, height: ah } = anchorElRect;
const sy = window.scrollY;
const eh = elRect.height;
const ew = elRect.width;
const nl = al + aw / 2 - ew / 2;
let nt = at - eh - offset + sy;
if (nt < 0) {
nt = at + ah + offset + sy;
} else {
nt = at - eh - offset + sy;
}
setPosition({ top: nt, left: nl });
if (!anchorEl || !ref.current) {
return;
};
const anchorElRect = anchorEl.getBoundingClientRect();
const elRect = ref.current.getBoundingClientRect();
const { top: at, left: al, width: aw, height: ah } = anchorElRect;
const sy = window.scrollY;
const eh = elRect.height;
const ew = elRect.width;
const nl = al + aw / 2 - ew / 2;
let nt = at - eh - offset + sy;
if (nt < 0) {
nt = at + ah + offset + sy;
} else {
nt = at - eh - offset + sy;
};
setPosition({ top: nt, left: nl });
};
H.useElementMovement(anchorEl, onMove);
useEffect(() => onMove(), [ anchorEl, ref.current, isShown ]);
return ReactDOM.createPortal(
<div className={`floater ${isShown ? 'show' : 'hide'}`}
ref={ref}
style={{ transform: `translate3d(${position.left}px, ${position.top}px, 0px)`}}
>
{children}
</div>,
document.getElementById('floater-root')
(
<div
className={cn.join(' ')}
ref={ref}
style={{ transform: `translate3d(${position.left}px, ${position.top}px, 0px)`}}
>
{children}
</div>
),
document.getElementById('floaterContainer')
);
};
};

View file

@ -31,9 +31,7 @@ class ElementMovementObserver {
});
this.startObserving();
}
};
private checkForMovement = () => {
const currentPosition = this.getPosition();
@ -41,7 +39,7 @@ class ElementMovementObserver {
if (this.hasPositionChanged(currentPosition)) {
this.lastPosition = currentPosition;
this.onMove(currentPosition);
}
};
};
private getPosition (): Position {
@ -53,17 +51,16 @@ class ElementMovementObserver {
width: rect.width,
height: rect.height
};
}
};
private hasPositionChanged (currentPosition: Position): boolean {
private hasPositionChanged (current: Position): boolean {
return (
currentPosition.x !== this.lastPosition.x ||
currentPosition.y !== this.lastPosition.y ||
currentPosition.width !== this.lastPosition.width ||
currentPosition.height !== this.lastPosition.height
(current.x !== this.lastPosition.x) ||
(current.y !== this.lastPosition.y) ||
(current.width !== this.lastPosition.width) ||
(current.height !== this.lastPosition.height)
);
}
};
private startObserving (): void {
const config: MutationObserverInit = {
@ -90,17 +87,17 @@ class ElementMovementObserver {
this.movementObserver.disconnect();
this.resizeObserver.disconnect();
window.removeEventListener('scroll', this.checkForMovement);
}
}
};
};
export default function useElementMovement ( element: HTMLElement | null, callback: (position: Position) => void ) {
useEffect(() => {
if (!element) return;
if (!element) {
return;
};
const movementObserver = new ElementMovementObserver(element, callback);
return () => {
movementObserver.disconnect();
};
}, [element, callback]);
}
return () => movementObserver.disconnect();
}, [ element, callback ]);
};

View file

@ -4,7 +4,7 @@ import * as M from 'Model'; // Models
import * as S from 'Store'; // Stores
import * as U from './util'; // Utils
import * as C from './api/command'; // Commands
import * as H from './hook'; // React Hooks
import * as H from 'Hook'; // React Hooks
import Renderer from './renderer';
import { dispatcher } from './api/dispatcher';

View file

@ -53,6 +53,12 @@
],
"Store": [
"ts/store",
],
"Hook/*": [
"ts/hook/*",
],
"Hook": [
"ts/hook",
],
"dist/*": [
"../dist/*"

View file

@ -44,6 +44,7 @@ module.exports = (env, argv) => {
Interface: path.resolve(__dirname, 'src/ts/interface'),
Model: path.resolve(__dirname, 'src/ts/model'),
Docs: path.resolve(__dirname, 'src/ts/docs'),
Hook: path.resolve(__dirname, 'src/ts/hook'),
},
modules: [
path.resolve('./src/'),