Chat popout
This commit is contained in:
@ -8,14 +8,14 @@
|
|||||||
gap: 16px;
|
gap: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.live-chat>div:nth-child(1) {
|
.live-chat > .header {
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
line-height: 30px;
|
line-height: 30px;
|
||||||
padding: 0px 0px 16px;
|
padding: 0px 0px 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.live-chat>div:nth-child(2) {
|
.live-chat > .messages {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 12px;
|
gap: 12px;
|
||||||
@ -24,17 +24,17 @@
|
|||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.live-chat>div:nth-child(3) {
|
.live-chat > .write-message {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 10px;
|
gap: 8px;
|
||||||
padding: 6px 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.live-chat .write-message {
|
.live-chat > .write-message > div:nth-child(1) {
|
||||||
background: #171717;
|
background: #171717;
|
||||||
border-radius: 16px;
|
border-radius: 16px;
|
||||||
padding: 8px 16px;
|
padding: 8px 16px;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
height: 32px;
|
height: 32px;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
|
@ -9,7 +9,12 @@ import { Profile } from "./profile";
|
|||||||
import { Icon } from "./icon";
|
import { Icon } from "./icon";
|
||||||
import Spinner from "./spinner";
|
import Spinner from "./spinner";
|
||||||
|
|
||||||
export function LiveChat({ link }: { link: NostrLink }) {
|
export interface LiveChatOptions {
|
||||||
|
canWrite?: boolean,
|
||||||
|
showHeader?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export function LiveChat({ link, options }: { link: NostrLink, options?: LiveChatOptions }) {
|
||||||
const [chat, setChat] = useState("");
|
const [chat, setChat] = useState("");
|
||||||
const messages = useLiveChatFeed(link);
|
const messages = useLiveChatFeed(link);
|
||||||
|
|
||||||
@ -32,10 +37,10 @@ export function LiveChat({ link }: { link: NostrLink }) {
|
|||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<div className="live-chat">
|
<div className="live-chat">
|
||||||
<div>
|
{(options?.showHeader ?? true) && <div className="header">
|
||||||
Stream Chat
|
Stream Chat
|
||||||
</div>
|
</div>}
|
||||||
<div>
|
<div className="messages">
|
||||||
{[...(messages.data ?? [])]
|
{[...(messages.data ?? [])]
|
||||||
.sort((a, b) => b.created_at - a.created_at)
|
.sort((a, b) => b.created_at - a.created_at)
|
||||||
.map(a => (
|
.map(a => (
|
||||||
@ -43,8 +48,8 @@ export function LiveChat({ link }: { link: NostrLink }) {
|
|||||||
))}
|
))}
|
||||||
{messages.data === undefined && <Spinner />}
|
{messages.data === undefined && <Spinner />}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
{(options?.canWrite ?? true) && <div className="write-message">
|
||||||
<div className="write-message">
|
<div>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
autoFocus={false}
|
autoFocus={false}
|
||||||
@ -63,7 +68,7 @@ export function LiveChat({ link }: { link: NostrLink }) {
|
|||||||
<AsyncButton onClick={sendChatMessage} className="btn btn-border">
|
<AsyncButton onClick={sendChatMessage} className="btn btn-border">
|
||||||
Send
|
Send
|
||||||
</AsyncButton>
|
</AsyncButton>
|
||||||
</div>
|
</div>}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import { RootPage } from './pages/root';
|
|||||||
import { RouterProvider, createBrowserRouter } from 'react-router-dom';
|
import { RouterProvider, createBrowserRouter } from 'react-router-dom';
|
||||||
import { LayoutPage } from 'pages/layout';
|
import { LayoutPage } from 'pages/layout';
|
||||||
import { StreamPage } from 'pages/stream-page';
|
import { StreamPage } from 'pages/stream-page';
|
||||||
|
import { ChatPopout } from 'pages/chat-popout';
|
||||||
|
|
||||||
export const System = new NostrSystem({
|
export const System = new NostrSystem({
|
||||||
|
|
||||||
@ -29,11 +30,15 @@ const router = createBrowserRouter([
|
|||||||
element: <StreamPage />
|
element: <StreamPage />
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/chat/:id",
|
||||||
|
element: <ChatPopout />
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
const root = ReactDOM.createRoot(document.getElementById('root') as HTMLDivElement);
|
const root = ReactDOM.createRoot(document.getElementById('root') as HTMLDivElement);
|
||||||
root.render(
|
root.render(
|
||||||
<React.StrictMode>
|
<React.StrictMode>
|
||||||
<RouterProvider router={router} />
|
<RouterProvider router={router} />
|
||||||
</React.StrictMode>
|
</React.StrictMode>
|
||||||
);
|
);
|
10
src/pages/chat-popout.css
Normal file
10
src/pages/chat-popout.css
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
.popout-chat .live-chat {
|
||||||
|
height: calc(100vh - 20px);
|
||||||
|
padding: 10px;
|
||||||
|
border: unset;
|
||||||
|
border-radius: unset;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popout-chat .live-chat .messages {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
16
src/pages/chat-popout.tsx
Normal file
16
src/pages/chat-popout.tsx
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import "./chat-popout.css";
|
||||||
|
import { LiveChat } from "element/live-chat";
|
||||||
|
import { useParams } from "react-router-dom";
|
||||||
|
import { parseNostrLink } from "@snort/system";
|
||||||
|
|
||||||
|
export function ChatPopout() {
|
||||||
|
const params = useParams();
|
||||||
|
const link = parseNostrLink(params.id!);
|
||||||
|
|
||||||
|
return <div className="popout-chat">
|
||||||
|
<LiveChat link={link} options={{
|
||||||
|
canWrite: false,
|
||||||
|
showHeader: false
|
||||||
|
}} />
|
||||||
|
</div>
|
||||||
|
}
|
Reference in New Issue
Block a user