Skip to content

Commit

Permalink
fix: scrollTo wrong positionning
Browse files Browse the repository at this point in the history
  • Loading branch information
mikbry authored Mar 11, 2024
2 parents d7997d4 + 2ff08a5 commit 0eebe4b
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 62 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { Button } from '../../../ui/button';

type ConversationListProps = {
conversationId: string;
scrollPosition: number;
scrollPosition: number | undefined;
messages: Message[];
onScrollPosition: (props: KeyedScrollPosition) => void;
onResendMessage: (m: Message) => void;
Expand All @@ -45,10 +45,12 @@ function ConversationList({
onScrollPosition(props);
};

const position = { x: scrollPosition === -1 ? -1 : 0, y: scrollPosition };
const position = {
x: scrollPosition === -1 ? -1 : 0,
y: scrollPosition === undefined ? -1 : scrollPosition,
};
const [ref, scrollTo] = useScroll(conversationId, position, handleUpdatePosition);

// console.log('scrollPosition', scrollPosition, position, ref, scrollTo);
return (
<div className="flex grow flex-col overflow-hidden">
<div ref={ref} className="overflow-y-auto">
Expand All @@ -75,7 +77,7 @@ function ConversationList({
</div>

<div className="z-100 relative w-full">
{scrollPosition < 99 && scrollPosition > -1 && (
{scrollPosition !== undefined && scrollPosition < 99 && (
<Button
variant="ghost"
size="icon"
Expand Down
12 changes: 8 additions & 4 deletions webapp/components/views/Threads/Conversation/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,13 @@ export function ConversationPanel({

const handleScrollPosition = ({ key, position }: KeyedScrollPosition) => {
const conversation = getConversation(key, conversations);
if (conversation && conversation.scrollPosition !== position.y && position.y !== -1) {
logger.info(`handleScrollPosition ${key} ${conversation.id}`, position);
conversation.scrollPosition = position.y;
logger.info(
`handleScrollPosition ${key} ${conversation?.id}`,
position,
conversation?.scrollPosition,
);
if (conversation && conversation.scrollPosition !== position.y) {
conversation.scrollPosition = position.y === -1 ? undefined : position.y;
const updatedConversations = updateConversation(conversation, conversations, true);
updateConversations(updatedConversations);
}
Expand Down Expand Up @@ -88,7 +92,7 @@ export function ConversationPanel({
scrollPosition={
selectedConversation && selectedConversation.scrollPosition !== undefined
? selectedConversation.scrollPosition
: -1
: undefined
}
messages={messages || []}
onScrollPosition={handleScrollPosition}
Expand Down
89 changes: 35 additions & 54 deletions webapp/hooks/useScroll.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,23 +19,17 @@ import { Position2D, Rect, getBoundingClientRect } from '@/utils/ui';
export type KeyedScrollPosition = { key: string | undefined; position: Position2D; rect?: Rect };

const containerRectToPercentage = (elementRect: Rect, parentRect: Rect): Rect => {
let width = +(elementRect.width - parentRect.width - parentRect.x).toFixed(1);
if (width === 0) {
width = -1;
}
const width = +(elementRect.width - parentRect.width - parentRect.x).toFixed(1);
const height = +(elementRect.height - parentRect.height - parentRect.y).toFixed(1);

let height = +(elementRect.height - parentRect.height - parentRect.y).toFixed(1);
if (height === 0) {
height = -1;
}
const ex = +elementRect.x.toFixed(1);
const ey = +elementRect.y.toFixed(1);
const x = width < 1 ? 0 : +((-ex / width) * 100).toFixed(1);
const y = height < 1 ? 0 : +((-ey / height) * 100).toFixed(1);
const x = width <= 0 ? -1 : +((-ex / width) * 100).toFixed(1);
const y = height <= 0 ? -1 : +((-ey / height) * 100).toFixed(1);
// logger.info('containerRectToPercentage', ey, elementRect, parentRect, x, y, height);
return {
x,
y,
y: y < 0 ? 0 : y,
width,
height,
};
Expand All @@ -52,20 +46,15 @@ const percentageToContainerRect = (
parent: HTMLDivElement,
position: Position2D,
): Rect => {
const px = position.x > 0 ? position.x : 0;
const py = position.y > 0 ? position.y : 0;
const parentRect = getBoundingClientRect(parent);
let width = +(elementRect.width - parentRect.width).toFixed(1);
if (width === 0) {
width = -1;
}

let height = +(elementRect.height - parentRect.height).toFixed(1);
if (height === 0) {
height = -1;
}
const width = +(elementRect.width - parentRect.width).toFixed(1);
const height = +(elementRect.height - parentRect.height).toFixed(1);

const x = width < 1 ? 0 : -((position.x / 100) * width).toFixed(1);
const y = height < 1 ? 0 : -((position.y / 100) * height).toFixed(1) + 50;
// logger.info('percentageToContainerRect', y, elementRect, parentRect, position, height);
const x = width <= 0 ? -1 : -((px / 100) * width).toFixed(1);
const y = height <= 0 ? -1 : -((py / 100) * height).toFixed(1) + 50;
// logger.info('percentageToContainerRect', y, elementRect, parentRect, position, px, py, height);
return {
x,
y,
Expand Down Expand Up @@ -109,7 +98,7 @@ export default function useScroll(

const currentRect = keyedRect.current.rect;
const parent = previousNode.current as HTMLDivElement;
logger.info('handleResize', contentRect, currentRect, parent);
// logger.info('handleResize', contentRect, currentRect, parent);
if (
parent &&
(!currentRect ||
Expand All @@ -119,29 +108,37 @@ export default function useScroll(
const rect = percentageToContainerRect(contentRect, parent, position);
const { width, height, ...xy } = rect;
if (height < 1 && width < 1) {
logger.info('handleResize not scroll', rect, contentRect, currentRect, xy, position);
keyedRect.current = { key, position: { x: -1, y: -1 }, rect };
if (position.x !== -1 && position.y !== -1) {
onUpdatePosition(keyedRect.current);
}
return;
}
const compare = containerRectToPercentage(
const resizedRect = containerRectToPercentage(
{ width: contentRect.width, height: contentRect.height, x: rect.x, y: rect.y },
getBoundingClientRect(parent),
);
logger.info(
/* logger.info(
'resize update',
`y=${position.y} yc=${compare.y}`,
`y=${position.y} yc=${compare.y}`,
`x=${position.x} xc=${resizedRect.x}`,
`y=${position.y} yc=${resizedRect.y}`,
position,
compare,
resizedRect,
xy,
width,
height,
contentRect,
);
parent.scrollTo({ left: -xy.x, top: -xy.y, behavior: 'instant' });
keyedRect.current = { key, position: xy, rect };
); */
// parent.scrollTo({ left: -xy.x, top: -xy.y, behavior: 'instant' });
keyedRect.current = { key, position: { x: resizedRect.x, y: resizedRect.y }, rect };
if (position.x !== resizedRect.x || position.y !== resizedRect.y) {
onUpdatePosition(keyedRect.current);
}
isResizing.current = true;
}
},
[key, position],
[key, onUpdatePosition, position],
);

const handleScrollEnd = useCallback(
Expand All @@ -152,25 +149,12 @@ export default function useScroll(
return;
}
// logger.info(`handleScrollEnd newPosition ${key}`, keyedRect.current, position, rect);
if (rect.width && rect.height) {
if (rect.width > 0 || rect.height > 0) {
const newKeyedPosition: KeyedScrollPosition = {
key,
position: { x: rect.x, y: rect.y },
rect,
};
/* if (
(keyedRect.current.key === key &&
keyedRect.current.position.x !== newKeyedPosition.position.x) ||
keyedRect.current.position.y !== newKeyedPosition.position.y
) {
keyedRect.current = newKeyedPosition;
if (
keyedRect.current.rect?.height === newKeyedPosition.rect?.height &&
keyedRect.current.rect?.width === newKeyedPosition.rect?.width
) {
onUpdatePosition(newKeyedPosition);
}
} */
onUpdatePosition(newKeyedPosition);
}

Expand Down Expand Up @@ -206,7 +190,7 @@ export default function useScroll(

const parent = previousNode.current as HTMLDivElement;
if (parent) {
logger.info(`scrollTo isScrolling ${key} ${parent}`, isScrolling, scrollPosition, position);
// logger.info(`scrollTo isScrolling ${key} ${parent}`, isScrolling, scrollPosition, position);
const element = parent.firstChild as HTMLDivElement;
if (!element) {
return;
Expand All @@ -216,7 +200,7 @@ export default function useScroll(
element as HTMLDivElement,
parent as HTMLDivElement,
);
logger.info('currentRect', currentRect, scrollPosition, position);
// logger.info('currentRect', currentRect, scrollPosition, position);
if (currentRect.height < 1) {
// logger.info('not scroll', scrollPosition, currentRect);
return;
Expand All @@ -234,13 +218,10 @@ export default function useScroll(
parent.scrollTo(-newPosition.x, -newPosition.y + parentRect.y);
const rect = containerToPercentage(element, parent);
keyedRect.current = { key, position: { x: rect.x, y: rect.y }, rect };
/* waitAfterScroll(() => {
isScrolling.current = false;
}); */
// isScrolling.current = false;
onUpdatePosition(keyedRect.current);
}
},
[key, position],
[key, onUpdatePosition, position],
);

const customRef = useCallback(
Expand Down

0 comments on commit 0eebe4b

Please sign in to comment.