latch and unlatch topic stream

This commit is contained in:
Roland Osborne 2022-04-19 00:27:56 -07:00
parent 5816751e11
commit b5df466dc6
3 changed files with 53 additions and 17 deletions

View File

@ -1,9 +1,20 @@
import React, { useEffect } from 'react';
import React, { useEffect, useState } from 'react';
import { TopicItemWrapper } from './TopicItem.styled';
import ReactResizeDetector from 'react-resize-detector';
export function TopicItem({ topic, padding, onHeight }) {
const [ text, setText ] = useState(null);
useEffect(() => {
try {
setText(JSON.parse(topic.data.topicDetail.data).text);
}
catch(err) {
console.log("invalid topic", topic);
}
}, [topic]);
return (
<ReactResizeDetector handleHeight={true}>
{({ height }) => {
@ -12,7 +23,7 @@ export function TopicItem({ topic, padding, onHeight }) {
}
return (
<TopicItemWrapper style={{ paddingTop: padding }}>
<div>{ JSON.stringify(topic) }</div>
<div>{ text }</div>
</TopicItemWrapper>
)
}}

View File

@ -13,8 +13,8 @@ export function VirtualList({ topics }) {
const [ viewHeight, setViewHeight ] = useState(DEFAULT_LIST_HEIGHT);
const [ canvasHeight, setCanvasHeight ] = useState(DEFAULT_LIST_HEIGHT*3);
const [ items, setItems ] = useState([]);
const [ scroll, setScroll ] = useState('hidden');
let unlatch = useRef(0);
let latch = useRef(true);
let scrollTop = useRef(0);
let containers = useRef([]);
@ -44,6 +44,15 @@ export function VirtualList({ topics }) {
setTopics();
}, [topics]);
const onScrollWheel = (e) => {
if (e.deltaY < 0 && latch.current) {
scrollTop.current -= 32;
listRef.current.scrollTo({ top: scrollTop.current, left: 0, behavior: 'smooth' });
setScroll('auto');
latch.current = false;
}
}
const onScrollView = (e) => {
// add or remove from overscan
@ -52,11 +61,19 @@ export function VirtualList({ topics }) {
// set or clear latch
unlatch.current -= 1;
scrollTop.current = e.target.scrollTop;
loadNextItem();
console.log("UNLATCH: ", unlatch.current);
if (!latch.current) {
let view = getPlacement();
if (view?.overscan?.bottom <= 0) {
setScroll('hidden');
latch.current = true;
alignItems();
listRef.current.scrollTo({ top: scrollTop.current, left: 0 });
}
}
loadNextItem();
}
const loadNextItem = () => {
@ -127,16 +144,19 @@ console.log("ADD ITEM AFTER");
let view = getPlacement();
if (latch.current) {
if (view.position.height < viewHeight) {
unlatch.current += 1;
if (scrollTop.current != view.position.top) {
listRef.current.scrollTo({ top: view.position.top, left: 0, behavior: 'smooth' });
scrollTop.current = view.position.top;
}
}
else {
unlatch.current += 1;
if (scrollTop.current != view.position.bottom - viewHeight) {
listRef.current.scrollTo({ top: view.position.bottom - viewHeight, left: 0, behavior: 'smooth' });
scrollTop.current = view.position.bottom - viewHeight;
}
}
console.log("ALIGN: ", scrollTop.current)
}
}
loadNextItem();
@ -149,7 +169,6 @@ console.log("ADD ITEM AFTER");
let view = getPlacement();
if (!view) {
let pos = canvasHeight / 2;
unlatch.current += 1;
listRef.current.scrollTo({ top: pos, left: 0 });
scrollTop.current = pos;
@ -163,7 +182,6 @@ console.log("ADD ITEM AFTER");
containers.current.push(container);
addItemBottom(getItem(container));
unlatch.current += 1;
listRef.current.scrollTo({ top: container.top, left: 0, behavior: 'smooth' });
}
else {
@ -205,8 +223,8 @@ console.log("ADD ITEM AFTER");
{({ height }) => {
setViewHeight(height);
return (
<VirtualListWrapper onScroll={onScrollView}>
<div class="rollview" ref={listRef} onScroll={onScrollView}>
<VirtualListWrapper onScroll={onScrollView} onWheel={onScrollWheel}>
<div class="rollview" style={{ overflowY: scroll }} ref={listRef} onScroll={onScrollView}>
<div class="roll" style={{ height: canvasHeight }}>
{ items }
</div>

View File

@ -7,9 +7,16 @@ export const VirtualListWrapper = styled.div`
overflow: hidden;
.rollview {
overflow-y: auto;
width: 100%;
height: 100%;
/* hide scrollbar for IE, Edge and Firefox */
-ms-overflow-style: none;
scrollbar-width: none;
}
.rollview::-webkit-scrollbar {
display: none;
}
.roll {