Added mobile chat and some responsiveness
weird 0 popping out when toggling chat. wasn't able to find which component is responsible. Used bare mininum scss. May refactor in the future.
This commit is contained in:
@@ -4,6 +4,7 @@ import { useState, useMemo, useCallback, useEffect, useRef } from 'react';
|
|||||||
import { ChatMessage } from '../../interfaces/chat-message.model';
|
import { ChatMessage } from '../../interfaces/chat-message.model';
|
||||||
import { ChatState } from '../../interfaces/application-state';
|
import { ChatState } from '../../interfaces/application-state';
|
||||||
import ChatUserMessage from './ChatUserMessage';
|
import ChatUserMessage from './ChatUserMessage';
|
||||||
|
import { LoadingOutlined } from '@ant-design/icons';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
messages: ChatMessage[];
|
messages: ChatMessage[];
|
||||||
@@ -15,10 +16,12 @@ export default function ChatContainer(props: Props) {
|
|||||||
const loading = state === ChatState.Loading;
|
const loading = state === ChatState.Loading;
|
||||||
|
|
||||||
const chatContainerRef = useRef(null);
|
const chatContainerRef = useRef(null);
|
||||||
|
const spinIcon = <LoadingOutlined style={{fontSize: '32px'}} spin />
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ height: 'calc(100vh - 104.5px)' }}>
|
<div>
|
||||||
<Spin spinning={loading} />
|
<h1>Chat</h1>
|
||||||
|
<Spin spinning={loading} indicator={spinIcon} />
|
||||||
<Virtuoso
|
<Virtuoso
|
||||||
ref={chatContainerRef}
|
ref={chatContainerRef}
|
||||||
initialTopMostItemIndex={999}
|
initialTopMostItemIndex={999}
|
||||||
|
|||||||
@@ -1,14 +1,33 @@
|
|||||||
.root {
|
.root {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 8fr 4fr;
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobileChat {
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
background-color: white;
|
||||||
|
top: 0px;
|
||||||
|
width: 100%;
|
||||||
|
height: calc(50vh - var(--header-h));
|
||||||
}
|
}
|
||||||
|
|
||||||
.leftCol {
|
.leftCol {
|
||||||
display: grid;
|
display: grid;
|
||||||
// -64px, which is the header
|
// -64px, which is the header
|
||||||
grid-template-rows: 50vh calc(50vh - 64px);
|
grid-template-rows: 50vh calc(50vh - var(--header-h));
|
||||||
}
|
}
|
||||||
.lowerRow {
|
.lowerRow {
|
||||||
|
position: relative;
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-rows: 1fr 64px;
|
grid-template-rows: 1fr var(--header-h);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.mobileChat {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.root[data-columns='2'] {
|
||||||
|
grid-template-columns: 1fr var(--chat-w);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { useRecoilValue } from 'recoil';
|
import { useRecoilValue } from 'recoil';
|
||||||
import { Layout, Row, Col, Tabs } from 'antd';
|
import { Layout, Tabs } from 'antd';
|
||||||
import { chatVisibilityAtom, clientConfigStateAtom } from '../../stores/ClientConfigStore';
|
import { chatVisibilityAtom, clientConfigStateAtom } 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';
|
||||||
@@ -7,9 +7,12 @@ import OwncastPlayer from '../../video/OwncastPlayer';
|
|||||||
import FollowerCollection from '../../FollowersCollection';
|
import FollowerCollection from '../../FollowersCollection';
|
||||||
import s from './Content.module.scss';
|
import s from './Content.module.scss';
|
||||||
import Sidebar from '../Sidebar';
|
import Sidebar from '../Sidebar';
|
||||||
import { ChatVisibilityState } from '../../../interfaces/application-state';
|
|
||||||
import Footer from '../Footer';
|
import Footer from '../Footer';
|
||||||
import Grid from 'antd/lib/card/Grid';
|
import ChatContainer from '../../chat/ChatContainer';
|
||||||
|
import { ChatMessage } from '../../../interfaces/chat-message.model';
|
||||||
|
import { chatMessagesAtom, chatStateAtom } from '../../stores/ClientConfigStore';
|
||||||
|
import { ChatState, ChatVisibilityState } from '../../../interfaces/application-state';
|
||||||
|
import ChatTextField from '../../chat/ChatTextField/ChatTextField';
|
||||||
|
|
||||||
const { TabPane } = Tabs;
|
const { TabPane } = Tabs;
|
||||||
|
|
||||||
@@ -18,11 +21,14 @@ const { Content } = Layout;
|
|||||||
export default function FooterComponent() {
|
export default function FooterComponent() {
|
||||||
const clientConfig = useRecoilValue<ClientConfig>(clientConfigStateAtom);
|
const clientConfig = useRecoilValue<ClientConfig>(clientConfigStateAtom);
|
||||||
const chatOpen = useRecoilValue<ChatVisibilityState>(chatVisibilityAtom);
|
const chatOpen = useRecoilValue<ChatVisibilityState>(chatVisibilityAtom);
|
||||||
|
const messages = useRecoilValue<ChatMessage[]>(chatMessagesAtom);
|
||||||
|
const chatState = useRecoilValue<ChatState>(chatStateAtom);
|
||||||
|
|
||||||
const { extraPageContent } = clientConfig;
|
const { extraPageContent } = clientConfig;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Content className={`${s.root}`}>
|
<Content className={`${s.root}`} data-columns={chatOpen ? 2 : 1}>
|
||||||
<Col className={`${s.leftCol}`}>
|
<div className={`${s.leftCol}`}>
|
||||||
<OwncastPlayer source="https://watch.owncast.online" />
|
<OwncastPlayer source="https://watch.owncast.online" />
|
||||||
<div className={`${s.lowerRow}`}>
|
<div className={`${s.lowerRow}`}>
|
||||||
<Tabs defaultActiveKey="1" type="card">
|
<Tabs defaultActiveKey="1" type="card">
|
||||||
@@ -33,14 +39,16 @@ export default function FooterComponent() {
|
|||||||
<FollowerCollection />
|
<FollowerCollection />
|
||||||
</TabPane>
|
</TabPane>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
{chatOpen && (
|
||||||
|
<div className={`${s.mobileChat}`}>
|
||||||
|
<ChatContainer messages={messages} state={chatState} />
|
||||||
|
<ChatTextField />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
<Footer />
|
<Footer />
|
||||||
</div>
|
</div>
|
||||||
</Col>
|
</div>
|
||||||
{chatOpen && (
|
{chatOpen && <Sidebar />}
|
||||||
<Col>
|
|
||||||
<Sidebar />
|
|
||||||
</Col>
|
|
||||||
)}
|
|
||||||
</Content>
|
</Content>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
12
web/components/ui/Sidebar/Sidebar.module.scss
Normal file
12
web/components/ui/Sidebar/Sidebar.module.scss
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
.root {
|
||||||
|
background-color: var(--gray-700);
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.root {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
import Sider from 'antd/lib/layout/Sider';
|
import Sider from 'antd/lib/layout/Sider';
|
||||||
import { useRecoilValue } from 'recoil';
|
import { useRecoilValue } from 'recoil';
|
||||||
import { useEffect } from 'react';
|
|
||||||
import { ChatMessage } from '../../../interfaces/chat-message.model';
|
import { ChatMessage } from '../../../interfaces/chat-message.model';
|
||||||
import ChatContainer from '../../chat/ChatContainer';
|
import ChatContainer from '../../chat/ChatContainer';
|
||||||
|
import s from './Sidebar.module.scss';
|
||||||
import {
|
import {
|
||||||
chatMessagesAtom,
|
chatMessagesAtom,
|
||||||
chatVisibilityAtom,
|
chatVisibilityAtom,
|
||||||
@@ -18,6 +18,7 @@ export default function Sidebar() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Sider
|
<Sider
|
||||||
|
className={`${s.root}`}
|
||||||
collapsed={chatVisibility === ChatVisibilityState.Hidden}
|
collapsed={chatVisibility === ChatVisibilityState.Hidden}
|
||||||
collapsedWidth={0}
|
collapsedWidth={0}
|
||||||
width="100%"
|
width="100%"
|
||||||
|
|||||||
@@ -93,4 +93,9 @@
|
|||||||
--font-family: 'Inter', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
|
--font-family: 'Inter', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
|
||||||
'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji',
|
'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji',
|
||||||
'Segoe UI Symbol', 'Noto Color Emoji';
|
'Segoe UI Symbol', 'Noto Color Emoji';
|
||||||
|
|
||||||
|
// chat variables
|
||||||
|
--header-h: 64px;
|
||||||
|
--chat-w: 300px;
|
||||||
|
--chat-input-h: 40.5px;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user