cinny/src/app/organisms/room/RoomView.jsx

151 lines
4.3 KiB
React
Raw Normal View History

2021-08-04 09:52:59 +00:00
import React, { useState, useEffect, useRef } from 'react';
2021-07-28 13:15:52 +00:00
import PropTypes from 'prop-types';
2021-08-31 13:13:31 +00:00
import './RoomView.scss';
2021-07-28 13:15:52 +00:00
import EventEmitter from 'events';
import RoomTimeline from '../../../client/state/RoomTimeline';
import ScrollView from '../../atoms/scroll/ScrollView';
2021-08-31 13:13:31 +00:00
import RoomViewHeader from './RoomViewHeader';
import RoomViewContent from './RoomViewContent';
import RoomViewFloating from './RoomViewFloating';
import RoomViewInput from './RoomViewInput';
import RoomViewCmdBar from './RoomViewCmdBar';
2021-07-28 13:15:52 +00:00
2021-08-04 09:52:59 +00:00
import { scrollToBottom, isAtBottom, autoScrollToBottom } from './common';
2021-07-28 13:15:52 +00:00
2021-08-04 09:52:59 +00:00
const viewEvent = new EventEmitter();
2021-07-28 13:15:52 +00:00
let lastScrollTop = 0;
let lastScrollHeight = 0;
let isReachedBottom = true;
let isReachedTop = false;
2021-08-31 13:13:31 +00:00
function RoomView({ roomId }) {
2021-07-28 13:15:52 +00:00
const [roomTimeline, updateRoomTimeline] = useState(null);
const timelineSVRef = useRef(null);
useEffect(() => {
roomTimeline?.removeInternalListeners();
updateRoomTimeline(new RoomTimeline(roomId));
isReachedBottom = true;
isReachedTop = false;
}, [roomId]);
const timelineScroll = {
reachBottom() {
scrollToBottom(timelineSVRef);
},
autoReachBottom() {
autoScrollToBottom(timelineSVRef);
},
tryRestoringScroll() {
const sv = timelineSVRef.current;
const { scrollHeight } = sv;
if (lastScrollHeight === scrollHeight) return;
if (lastScrollHeight < scrollHeight) {
sv.scrollTop = lastScrollTop + (scrollHeight - lastScrollHeight);
} else {
timelineScroll.reachBottom();
}
},
enableSmoothScroll() {
timelineSVRef.current.style.scrollBehavior = 'smooth';
},
disableSmoothScroll() {
timelineSVRef.current.style.scrollBehavior = 'auto';
},
isScrollable() {
const oHeight = timelineSVRef.current.offsetHeight;
const sHeight = timelineSVRef.current.scrollHeight;
if (sHeight > oHeight) return true;
return false;
},
};
function onTimelineScroll(e) {
const { scrollTop, scrollHeight, offsetHeight } = e.target;
const scrollBottom = scrollTop + offsetHeight;
lastScrollTop = scrollTop;
lastScrollHeight = scrollHeight;
const PLACEHOLDER_HEIGHT = 96;
const PLACEHOLDER_COUNT = 3;
const topPagKeyPoint = PLACEHOLDER_COUNT * PLACEHOLDER_HEIGHT;
const bottomPagKeyPoint = scrollHeight - (offsetHeight / 2);
if (!isReachedBottom && isAtBottom(timelineSVRef)) {
isReachedBottom = true;
viewEvent.emit('toggle-reached-bottom', true);
}
if (isReachedBottom && !isAtBottom(timelineSVRef)) {
isReachedBottom = false;
viewEvent.emit('toggle-reached-bottom', false);
}
// TOP of timeline
if (scrollTop < topPagKeyPoint && isReachedTop === false) {
isReachedTop = true;
viewEvent.emit('reached-top');
return;
}
isReachedTop = false;
// BOTTOM of timeline
if (scrollBottom > bottomPagKeyPoint) {
// TODO:
}
}
return (
2021-08-31 13:13:31 +00:00
<div className="room-view">
<RoomViewHeader roomId={roomId} />
<div className="room-view__content-wrapper">
<div className="room-view__scrollable">
2021-07-28 13:15:52 +00:00
<ScrollView onScroll={onTimelineScroll} ref={timelineSVRef} autoHide>
{roomTimeline !== null && (
2021-08-31 13:13:31 +00:00
<RoomViewContent
2021-07-28 13:15:52 +00:00
roomId={roomId}
roomTimeline={roomTimeline}
timelineScroll={timelineScroll}
2021-08-04 09:52:59 +00:00
viewEvent={viewEvent}
2021-07-28 13:15:52 +00:00
/>
)}
</ScrollView>
{roomTimeline !== null && (
2021-08-31 13:13:31 +00:00
<RoomViewFloating
2021-07-28 13:15:52 +00:00
roomId={roomId}
roomTimeline={roomTimeline}
timelineScroll={timelineScroll}
2021-08-04 09:52:59 +00:00
viewEvent={viewEvent}
2021-07-28 13:15:52 +00:00
/>
)}
</div>
{roomTimeline !== null && (
2021-08-31 13:13:31 +00:00
<div className="room-view__sticky">
<RoomViewInput
2021-07-28 13:15:52 +00:00
roomId={roomId}
roomTimeline={roomTimeline}
timelineScroll={timelineScroll}
2021-08-04 09:52:59 +00:00
viewEvent={viewEvent}
2021-07-28 13:15:52 +00:00
/>
2021-08-31 13:13:31 +00:00
<RoomViewCmdBar
2021-07-28 13:15:52 +00:00
roomId={roomId}
roomTimeline={roomTimeline}
2021-08-04 09:52:59 +00:00
viewEvent={viewEvent}
2021-07-28 13:15:52 +00:00
/>
2021-08-04 09:52:59 +00:00
</div>
2021-07-28 13:15:52 +00:00
)}
</div>
</div>
);
}
2021-08-31 13:13:31 +00:00
RoomView.propTypes = {
2021-07-28 13:15:52 +00:00
roomId: PropTypes.string.isRequired,
};
2021-08-31 13:13:31 +00:00
export default RoomView;