0

Changed chat behaviour

added recoil value isMobile to determine which chat to display and
style. #1978

changed the player to actually span across the viewport without the
black borders around it.
This commit is contained in:
t1enne 2022-07-03 12:36:30 +02:00
parent 4fcdfdc730
commit d12712a107
10 changed files with 74 additions and 34 deletions

View File

@ -13,10 +13,11 @@ interface Props {
usernameToHighlight: string;
chatUserId: string;
isModerator: boolean;
isMobile: boolean | undefined;
}
export default function ChatContainer(props: Props) {
const { messages, loading, usernameToHighlight, chatUserId, isModerator } = props;
const { messages, loading, usernameToHighlight, chatUserId, isModerator, isMobile } = props;
const [atBottom, setAtBottom] = useState(false);
// const [showButton, setShowButton] = useState(false);
@ -66,7 +67,7 @@ export default function ChatContainer(props: Props) {
() => (
<>
<Virtuoso
style={{ height: '75vh' }}
style={{ height: isMobile ? 500 : '77vh' }}
ref={chatContainerRef}
initialTopMostItemIndex={messages.length - 1} // Force alignment to bottom
data={messages}
@ -93,7 +94,7 @@ export default function ChatContainer(props: Props) {
)}
</>
),
[messages, usernameToHighlight, chatUserId, isModerator, atBottom],
[messages, usernameToHighlight, chatUserId, isModerator, atBottom, isMobile],
);
return (

View File

@ -1,5 +1,5 @@
.root {
position: absolute;
position: relative;
bottom: 0px;
width: 100%;
padding: .3rem;

View File

@ -76,6 +76,11 @@ export const appStateAtom = atom<AppStateOptions>({
default: makeEmptyAppState(),
});
export const isMobileAtom = atom<boolean | undefined>({
key: 'isMobileAtom',
default: undefined,
});
export const chatVisibleToggleAtom = atom<boolean>({
key: 'chatVisibilityToggleAtom',
default: true,

View File

@ -1,19 +1,28 @@
.root {
display: grid;
grid-template-columns: 1fr auto;
&.mobile {
display: block;
// height: calc(100vh - 64px);
// overflow-y: hidden;
}
}
.mobileChat {
position: relative;
display: block;
top: 0px;
// top: 0px;
width: 100%;
[data-virtuoso-scroller] {
height: 500px;
}
}
.leftCol {
display: grid;
display: flex;
flex-direction: column;
}
.lowerRow {
.streamInfo {
position: relative;
display: grid;
}
@ -43,7 +52,7 @@
margin-left: 10px;
.title {
font-size: 2.5vw;
font-size: 1.5rem;
font-weight: bold;
color: var(--theme-text-primary);
}
@ -61,8 +70,3 @@
z-index: 999999;
}
@media (min-width: 768px) {
.mobileChat {
display: none;
}
}

View File

@ -1,7 +1,8 @@
/* eslint-disable react/no-danger */
import { useRecoilValue } from 'recoil';
import { useRecoilValue, useSetRecoilState } from 'recoil';
import { Layout, Tabs, Spin } from 'antd';
import { useEffect, useState } from 'react';
import cn from 'classnames';
import { LOCAL_STORAGE_KEYS, getLocalStorage, setLocalStorage } from '../../../utils/localStorage';
import {
@ -13,6 +14,7 @@ import {
serverStatusState,
appStateAtom,
isOnlineSelector,
isMobileAtom,
} from '../../stores/ClientConfigStore';
import { ClientConfig } from '../../../interfaces/client-config.model';
import CustomPageContent from '../../CustomPageContent';
@ -48,6 +50,8 @@ export default function ContentComponent() {
const status = useRecoilValue<ServerStatus>(serverStatusState);
const clientConfig = useRecoilValue<ClientConfig>(clientConfigStateAtom);
const isChatVisible = useRecoilValue<boolean>(isChatVisibleSelector);
const setIsMobile = useSetRecoilState<boolean>(isMobileAtom);
const isMobile = useRecoilValue(isMobileAtom);
const messages = useRecoilValue<ChatMessage[]>(chatMessagesAtom);
const online = useRecoilValue<boolean>(isOnlineSelector);
const chatDisplayName = useRecoilValue<string>(chatDisplayNameAtom);
@ -97,15 +101,31 @@ export default function ContentComponent() {
setLocalStorage(LOCAL_STORAGE_KEYS.hasDisplayedNotificationModal, true);
};
const checkIfMobile = () => {
const w = window.innerWidth;
if (isMobile === undefined) {
if (w <= 768) setIsMobile(true);
else setIsMobile(false);
}
if (!isMobile && w <= 768) setIsMobile(true);
if (isMobile && w > 768) setIsMobile(false);
};
useEffect(() => {
incrementVisitCounter();
checkIfMobile();
window.addEventListener('resize', checkIfMobile);
}, []);
const rootClassName = cn(s.root, {
[s.mobile]: isMobile,
});
return (
<Content className={`${s.root}`}>
<Content className={rootClassName}>
<Spin className={s.loadingSpinner} size="large" spinning={appState.appLoading} />
<div className={`${s.leftCol}`}>
<div className={s.leftCol}>
{online && <OwncastPlayer source="/hls/stream.m3u8" online={online} />}
{!online && (
<OfflineBanner
@ -142,7 +162,7 @@ export default function ContentComponent() {
<BrowserNotifyModal />
</Modal>
<div className={`${s.lowerRow}`}>
<div className={s.streamInfo}>
<div className={s.logoTitleSection}>
<ServerLogo src="/logo" />
<div className={s.titleSection}>
@ -158,30 +178,33 @@ export default function ContentComponent() {
</div>
<Tabs defaultActiveKey="1">
<TabPane tab="About" key="1" className={`${s.pageContentSection}`}>
<TabPane tab="About" key="1" className={s.pageContentSection}>
<div dangerouslySetInnerHTML={{ __html: summary }} />
<CustomPageContent content={extraPageContent} />
</TabPane>
<TabPane tab="Followers" key="2" className={`${s.pageContentSection}`}>
<TabPane tab="Followers" key="2" className={s.pageContentSection}>
<FollowerCollection total={total} followers={followers} />
</TabPane>
</Tabs>
{isChatVisible && (
<div className={`${s.mobileChat}`}>
<ChatContainer
messages={messages}
loading={appState.chatLoading}
usernameToHighlight={chatDisplayName}
chatUserId={chatUserId}
isModerator={false}
/>
{isChatVisible && isMobile && (
<div style={{ position: 'relative' }}>
<div className={s.mobileChat}>
<ChatContainer
messages={messages}
loading={appState.chatLoading}
usernameToHighlight={chatDisplayName}
chatUserId={chatUserId}
isModerator={false}
isMobile={isMobile}
/>
</div>
<ChatTextField />
</div>
)}
<Footer version={version} />
</div>
</div>
{isChatVisible && <Sidebar />}
{isChatVisible && !isMobile && <Sidebar />}
</Content>
);
}

View File

@ -1,9 +1,10 @@
/* eslint-disable react/require-default-props */
import { CSSProperties } from 'react';
interface Props {
style: CSSProperties;
fill: string;
stroke: string;
style?: CSSProperties;
fill?: string;
stroke?: string;
}
export default function ModIcon({
style = { width: '1rem', height: '1rem' },

View File

@ -9,6 +9,7 @@
position: sticky;
top: var(--header-h);
display: block;
height: calc(100vh - var(--header-h));
max-height: calc(100vh - var(--header-h));
}
}

View File

@ -26,6 +26,7 @@ export default function Sidebar() {
usernameToHighlight={chatDisplayName}
chatUserId={chatUserId}
isModerator={false}
isMobile={false}
/>
<ChatTextField />
</Sider>

View File

@ -1,9 +1,12 @@
.player {
height: 80vh;
height: auto !important;
width: 100%;
video {
position: static !important;
}
}
.poster {
width: 100%;
height: 100%;
}
}

View File

@ -38,6 +38,7 @@ const AddMessagesChatExample = args => {
usernameToHighlight={null}
chatUserId={null}
isModerator={false}
isMobile={false}
/>
</div>
);