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:
@@ -13,10 +13,11 @@ interface Props {
|
|||||||
usernameToHighlight: string;
|
usernameToHighlight: string;
|
||||||
chatUserId: string;
|
chatUserId: string;
|
||||||
isModerator: boolean;
|
isModerator: boolean;
|
||||||
|
isMobile: boolean | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function ChatContainer(props: Props) {
|
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 [atBottom, setAtBottom] = useState(false);
|
||||||
// const [showButton, setShowButton] = useState(false);
|
// const [showButton, setShowButton] = useState(false);
|
||||||
@@ -66,7 +67,7 @@ export default function ChatContainer(props: Props) {
|
|||||||
() => (
|
() => (
|
||||||
<>
|
<>
|
||||||
<Virtuoso
|
<Virtuoso
|
||||||
style={{ height: '75vh' }}
|
style={{ height: isMobile ? 500 : '77vh' }}
|
||||||
ref={chatContainerRef}
|
ref={chatContainerRef}
|
||||||
initialTopMostItemIndex={messages.length - 1} // Force alignment to bottom
|
initialTopMostItemIndex={messages.length - 1} // Force alignment to bottom
|
||||||
data={messages}
|
data={messages}
|
||||||
@@ -93,7 +94,7 @@ export default function ChatContainer(props: Props) {
|
|||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
),
|
),
|
||||||
[messages, usernameToHighlight, chatUserId, isModerator, atBottom],
|
[messages, usernameToHighlight, chatUserId, isModerator, atBottom, isMobile],
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
.root {
|
.root {
|
||||||
position: absolute;
|
position: relative;
|
||||||
bottom: 0px;
|
bottom: 0px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: .3rem;
|
padding: .3rem;
|
||||||
|
|||||||
@@ -76,6 +76,11 @@ export const appStateAtom = atom<AppStateOptions>({
|
|||||||
default: makeEmptyAppState(),
|
default: makeEmptyAppState(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const isMobileAtom = atom<boolean | undefined>({
|
||||||
|
key: 'isMobileAtom',
|
||||||
|
default: undefined,
|
||||||
|
});
|
||||||
|
|
||||||
export const chatVisibleToggleAtom = atom<boolean>({
|
export const chatVisibleToggleAtom = atom<boolean>({
|
||||||
key: 'chatVisibilityToggleAtom',
|
key: 'chatVisibilityToggleAtom',
|
||||||
default: true,
|
default: true,
|
||||||
|
|||||||
@@ -1,19 +1,28 @@
|
|||||||
.root {
|
.root {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 1fr auto;
|
grid-template-columns: 1fr auto;
|
||||||
|
&.mobile {
|
||||||
|
display: block;
|
||||||
|
// height: calc(100vh - 64px);
|
||||||
|
// overflow-y: hidden;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.mobileChat {
|
.mobileChat {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: block;
|
display: block;
|
||||||
top: 0px;
|
// top: 0px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
[data-virtuoso-scroller] {
|
||||||
|
height: 500px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.leftCol {
|
.leftCol {
|
||||||
display: grid;
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
.lowerRow {
|
.streamInfo {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: grid;
|
display: grid;
|
||||||
}
|
}
|
||||||
@@ -43,7 +52,7 @@
|
|||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
font-size: 2.5vw;
|
font-size: 1.5rem;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: var(--theme-text-primary);
|
color: var(--theme-text-primary);
|
||||||
}
|
}
|
||||||
@@ -61,8 +70,3 @@
|
|||||||
z-index: 999999;
|
z-index: 999999;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 768px) {
|
|
||||||
.mobileChat {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
/* eslint-disable react/no-danger */
|
/* eslint-disable react/no-danger */
|
||||||
import { useRecoilValue } from 'recoil';
|
import { useRecoilValue, useSetRecoilState } from 'recoil';
|
||||||
import { Layout, Tabs, Spin } from 'antd';
|
import { Layout, Tabs, Spin } from 'antd';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
|
import cn from 'classnames';
|
||||||
import { LOCAL_STORAGE_KEYS, getLocalStorage, setLocalStorage } from '../../../utils/localStorage';
|
import { LOCAL_STORAGE_KEYS, getLocalStorage, setLocalStorage } from '../../../utils/localStorage';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@@ -13,6 +14,7 @@ import {
|
|||||||
serverStatusState,
|
serverStatusState,
|
||||||
appStateAtom,
|
appStateAtom,
|
||||||
isOnlineSelector,
|
isOnlineSelector,
|
||||||
|
isMobileAtom,
|
||||||
} from '../../stores/ClientConfigStore';
|
} from '../../stores/ClientConfigStore';
|
||||||
import { ClientConfig } from '../../../interfaces/client-config.model';
|
import { ClientConfig } from '../../../interfaces/client-config.model';
|
||||||
import CustomPageContent from '../../CustomPageContent';
|
import CustomPageContent from '../../CustomPageContent';
|
||||||
@@ -48,6 +50,8 @@ export default function ContentComponent() {
|
|||||||
const status = useRecoilValue<ServerStatus>(serverStatusState);
|
const status = useRecoilValue<ServerStatus>(serverStatusState);
|
||||||
const clientConfig = useRecoilValue<ClientConfig>(clientConfigStateAtom);
|
const clientConfig = useRecoilValue<ClientConfig>(clientConfigStateAtom);
|
||||||
const isChatVisible = useRecoilValue<boolean>(isChatVisibleSelector);
|
const isChatVisible = useRecoilValue<boolean>(isChatVisibleSelector);
|
||||||
|
const setIsMobile = useSetRecoilState<boolean>(isMobileAtom);
|
||||||
|
const isMobile = useRecoilValue(isMobileAtom);
|
||||||
const messages = useRecoilValue<ChatMessage[]>(chatMessagesAtom);
|
const messages = useRecoilValue<ChatMessage[]>(chatMessagesAtom);
|
||||||
const online = useRecoilValue<boolean>(isOnlineSelector);
|
const online = useRecoilValue<boolean>(isOnlineSelector);
|
||||||
const chatDisplayName = useRecoilValue<string>(chatDisplayNameAtom);
|
const chatDisplayName = useRecoilValue<string>(chatDisplayNameAtom);
|
||||||
@@ -97,15 +101,31 @@ export default function ContentComponent() {
|
|||||||
setLocalStorage(LOCAL_STORAGE_KEYS.hasDisplayedNotificationModal, true);
|
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(() => {
|
useEffect(() => {
|
||||||
incrementVisitCounter();
|
incrementVisitCounter();
|
||||||
|
checkIfMobile();
|
||||||
|
window.addEventListener('resize', checkIfMobile);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const rootClassName = cn(s.root, {
|
||||||
|
[s.mobile]: isMobile,
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Content className={`${s.root}`}>
|
<Content className={rootClassName}>
|
||||||
<Spin className={s.loadingSpinner} size="large" spinning={appState.appLoading} />
|
<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 && <OwncastPlayer source="/hls/stream.m3u8" online={online} />}
|
||||||
{!online && (
|
{!online && (
|
||||||
<OfflineBanner
|
<OfflineBanner
|
||||||
@@ -142,7 +162,7 @@ export default function ContentComponent() {
|
|||||||
<BrowserNotifyModal />
|
<BrowserNotifyModal />
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
||||||
<div className={`${s.lowerRow}`}>
|
<div className={s.streamInfo}>
|
||||||
<div className={s.logoTitleSection}>
|
<div className={s.logoTitleSection}>
|
||||||
<ServerLogo src="/logo" />
|
<ServerLogo src="/logo" />
|
||||||
<div className={s.titleSection}>
|
<div className={s.titleSection}>
|
||||||
@@ -158,30 +178,33 @@ export default function ContentComponent() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Tabs defaultActiveKey="1">
|
<Tabs defaultActiveKey="1">
|
||||||
<TabPane tab="About" key="1" className={`${s.pageContentSection}`}>
|
<TabPane tab="About" key="1" className={s.pageContentSection}>
|
||||||
<div dangerouslySetInnerHTML={{ __html: summary }} />
|
<div dangerouslySetInnerHTML={{ __html: summary }} />
|
||||||
<CustomPageContent content={extraPageContent} />
|
<CustomPageContent content={extraPageContent} />
|
||||||
</TabPane>
|
</TabPane>
|
||||||
<TabPane tab="Followers" key="2" className={`${s.pageContentSection}`}>
|
<TabPane tab="Followers" key="2" className={s.pageContentSection}>
|
||||||
<FollowerCollection total={total} followers={followers} />
|
<FollowerCollection total={total} followers={followers} />
|
||||||
</TabPane>
|
</TabPane>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
{isChatVisible && (
|
{isChatVisible && isMobile && (
|
||||||
<div className={`${s.mobileChat}`}>
|
<div style={{ position: 'relative' }}>
|
||||||
<ChatContainer
|
<div className={s.mobileChat}>
|
||||||
messages={messages}
|
<ChatContainer
|
||||||
loading={appState.chatLoading}
|
messages={messages}
|
||||||
usernameToHighlight={chatDisplayName}
|
loading={appState.chatLoading}
|
||||||
chatUserId={chatUserId}
|
usernameToHighlight={chatDisplayName}
|
||||||
isModerator={false}
|
chatUserId={chatUserId}
|
||||||
/>
|
isModerator={false}
|
||||||
|
isMobile={isMobile}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
<ChatTextField />
|
<ChatTextField />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<Footer version={version} />
|
<Footer version={version} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{isChatVisible && <Sidebar />}
|
{isChatVisible && !isMobile && <Sidebar />}
|
||||||
</Content>
|
</Content>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
|
/* eslint-disable react/require-default-props */
|
||||||
import { CSSProperties } from 'react';
|
import { CSSProperties } from 'react';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
style: CSSProperties;
|
style?: CSSProperties;
|
||||||
fill: string;
|
fill?: string;
|
||||||
stroke: string;
|
stroke?: string;
|
||||||
}
|
}
|
||||||
export default function ModIcon({
|
export default function ModIcon({
|
||||||
style = { width: '1rem', height: '1rem' },
|
style = { width: '1rem', height: '1rem' },
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
position: sticky;
|
position: sticky;
|
||||||
top: var(--header-h);
|
top: var(--header-h);
|
||||||
display: block;
|
display: block;
|
||||||
|
height: calc(100vh - var(--header-h));
|
||||||
max-height: calc(100vh - var(--header-h));
|
max-height: calc(100vh - var(--header-h));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ export default function Sidebar() {
|
|||||||
usernameToHighlight={chatDisplayName}
|
usernameToHighlight={chatDisplayName}
|
||||||
chatUserId={chatUserId}
|
chatUserId={chatUserId}
|
||||||
isModerator={false}
|
isModerator={false}
|
||||||
|
isMobile={false}
|
||||||
/>
|
/>
|
||||||
<ChatTextField />
|
<ChatTextField />
|
||||||
</Sider>
|
</Sider>
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
.player {
|
.player {
|
||||||
height: 80vh;
|
height: auto !important;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
video {
|
||||||
|
position: static !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.poster {
|
.poster {
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ const AddMessagesChatExample = args => {
|
|||||||
usernameToHighlight={null}
|
usernameToHighlight={null}
|
||||||
chatUserId={null}
|
chatUserId={null}
|
||||||
isModerator={false}
|
isModerator={false}
|
||||||
|
isMobile={false}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user