mirror of
https://github.com/balzack/databag.git
synced 2025-02-12 11:39:17 +00:00
latch and unlatch topic stream
This commit is contained in:
parent
5816751e11
commit
b5df466dc6
@ -1,9 +1,20 @@
|
|||||||
import React, { useEffect } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { TopicItemWrapper } from './TopicItem.styled';
|
import { TopicItemWrapper } from './TopicItem.styled';
|
||||||
import ReactResizeDetector from 'react-resize-detector';
|
import ReactResizeDetector from 'react-resize-detector';
|
||||||
|
|
||||||
export function TopicItem({ topic, padding, onHeight }) {
|
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 (
|
return (
|
||||||
<ReactResizeDetector handleHeight={true}>
|
<ReactResizeDetector handleHeight={true}>
|
||||||
{({ height }) => {
|
{({ height }) => {
|
||||||
@ -12,7 +23,7 @@ export function TopicItem({ topic, padding, onHeight }) {
|
|||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<TopicItemWrapper style={{ paddingTop: padding }}>
|
<TopicItemWrapper style={{ paddingTop: padding }}>
|
||||||
<div>{ JSON.stringify(topic) }</div>
|
<div>{ text }</div>
|
||||||
</TopicItemWrapper>
|
</TopicItemWrapper>
|
||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
|
@ -13,8 +13,8 @@ export function VirtualList({ topics }) {
|
|||||||
const [ viewHeight, setViewHeight ] = useState(DEFAULT_LIST_HEIGHT);
|
const [ viewHeight, setViewHeight ] = useState(DEFAULT_LIST_HEIGHT);
|
||||||
const [ canvasHeight, setCanvasHeight ] = useState(DEFAULT_LIST_HEIGHT*3);
|
const [ canvasHeight, setCanvasHeight ] = useState(DEFAULT_LIST_HEIGHT*3);
|
||||||
const [ items, setItems ] = useState([]);
|
const [ items, setItems ] = useState([]);
|
||||||
|
const [ scroll, setScroll ] = useState('hidden');
|
||||||
|
|
||||||
let unlatch = useRef(0);
|
|
||||||
let latch = useRef(true);
|
let latch = useRef(true);
|
||||||
let scrollTop = useRef(0);
|
let scrollTop = useRef(0);
|
||||||
let containers = useRef([]);
|
let containers = useRef([]);
|
||||||
@ -44,6 +44,15 @@ export function VirtualList({ topics }) {
|
|||||||
setTopics();
|
setTopics();
|
||||||
}, [topics]);
|
}, [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) => {
|
const onScrollView = (e) => {
|
||||||
|
|
||||||
// add or remove from overscan
|
// add or remove from overscan
|
||||||
@ -52,11 +61,19 @@ export function VirtualList({ topics }) {
|
|||||||
|
|
||||||
// set or clear latch
|
// set or clear latch
|
||||||
|
|
||||||
unlatch.current -= 1;
|
|
||||||
scrollTop.current = e.target.scrollTop;
|
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 = () => {
|
const loadNextItem = () => {
|
||||||
@ -127,15 +144,18 @@ console.log("ADD ITEM AFTER");
|
|||||||
let view = getPlacement();
|
let view = getPlacement();
|
||||||
if (latch.current) {
|
if (latch.current) {
|
||||||
if (view.position.height < viewHeight) {
|
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' });
|
listRef.current.scrollTo({ top: view.position.top, left: 0, behavior: 'smooth' });
|
||||||
scrollTop.current = view.position.top;
|
scrollTop.current = view.position.top;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
unlatch.current += 1;
|
if (scrollTop.current != view.position.bottom - viewHeight) {
|
||||||
listRef.current.scrollTo({ top: view.position.bottom - viewHeight, left: 0, behavior: 'smooth' });
|
listRef.current.scrollTo({ top: view.position.bottom - viewHeight, left: 0, behavior: 'smooth' });
|
||||||
scrollTop.current = view.position.bottom - viewHeight;
|
scrollTop.current = view.position.bottom - viewHeight;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
console.log("ALIGN: ", scrollTop.current)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,7 +169,6 @@ console.log("ADD ITEM AFTER");
|
|||||||
let view = getPlacement();
|
let view = getPlacement();
|
||||||
if (!view) {
|
if (!view) {
|
||||||
let pos = canvasHeight / 2;
|
let pos = canvasHeight / 2;
|
||||||
unlatch.current += 1;
|
|
||||||
listRef.current.scrollTo({ top: pos, left: 0 });
|
listRef.current.scrollTo({ top: pos, left: 0 });
|
||||||
scrollTop.current = pos;
|
scrollTop.current = pos;
|
||||||
|
|
||||||
@ -163,7 +182,6 @@ console.log("ADD ITEM AFTER");
|
|||||||
containers.current.push(container);
|
containers.current.push(container);
|
||||||
addItemBottom(getItem(container));
|
addItemBottom(getItem(container));
|
||||||
|
|
||||||
unlatch.current += 1;
|
|
||||||
listRef.current.scrollTo({ top: container.top, left: 0, behavior: 'smooth' });
|
listRef.current.scrollTo({ top: container.top, left: 0, behavior: 'smooth' });
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -205,8 +223,8 @@ console.log("ADD ITEM AFTER");
|
|||||||
{({ height }) => {
|
{({ height }) => {
|
||||||
setViewHeight(height);
|
setViewHeight(height);
|
||||||
return (
|
return (
|
||||||
<VirtualListWrapper onScroll={onScrollView}>
|
<VirtualListWrapper onScroll={onScrollView} onWheel={onScrollWheel}>
|
||||||
<div class="rollview" ref={listRef} onScroll={onScrollView}>
|
<div class="rollview" style={{ overflowY: scroll }} ref={listRef} onScroll={onScrollView}>
|
||||||
<div class="roll" style={{ height: canvasHeight }}>
|
<div class="roll" style={{ height: canvasHeight }}>
|
||||||
{ items }
|
{ items }
|
||||||
</div>
|
</div>
|
||||||
|
@ -7,9 +7,16 @@ export const VirtualListWrapper = styled.div`
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
.rollview {
|
.rollview {
|
||||||
overflow-y: auto;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
||||||
|
/* hide scrollbar for IE, Edge and Firefox */
|
||||||
|
-ms-overflow-style: none;
|
||||||
|
scrollbar-width: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rollview::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.roll {
|
.roll {
|
||||||
|
Loading…
Reference in New Issue
Block a user