diff --git a/web/components/Follower.tsx b/web/components/Follower.tsx
index e7d395dd3..ff9ec1b38 100644
--- a/web/components/Follower.tsx
+++ b/web/components/Follower.tsx
@@ -1,9 +1,19 @@
+import { Avatar, Comment } from 'antd';
+import React from 'react';
import { Follower } from '../interfaces/follower';
interface Props {
follower: Follower;
}
-export default function FollowerCollection(props: Props) {
- return
This is a single follower
;
+export default function SingleFollower(props: Props) {
+ const { follower } = props;
+
+ return (
+ }
+ content={follower.name}
+ />
+ );
}
diff --git a/web/components/FollowersCollection.tsx b/web/components/FollowersCollection.tsx
index aa2eb333e..f0751b5e8 100644
--- a/web/components/FollowersCollection.tsx
+++ b/web/components/FollowersCollection.tsx
@@ -1,9 +1,24 @@
+import { Pagination } from 'antd';
import { Follower } from '../interfaces/follower';
+import SingleFollower from './Follower';
interface Props {
+ total: number;
followers: Follower[];
}
export default function FollowerCollection(props: Props) {
- return List of followers go here
;
+ const ITEMS_PER_PAGE = 24;
+
+ const { followers, total } = props;
+ const pages = Math.ceil(total / ITEMS_PER_PAGE);
+
+ return (
+
+ {followers.map(follower => (
+
+ ))}
+
+
+ );
}
diff --git a/web/components/chat/ChatContainer.tsx b/web/components/chat/ChatContainer.tsx
index b5d62c419..a2f66d952 100644
--- a/web/components/chat/ChatContainer.tsx
+++ b/web/components/chat/ChatContainer.tsx
@@ -1,10 +1,11 @@
import { Spin } from 'antd';
import { Virtuoso } from 'react-virtuoso';
import { useState, useMemo, useCallback, useEffect, useRef } from 'react';
+import { LoadingOutlined } from '@ant-design/icons';
import { ChatMessage } from '../../interfaces/chat-message.model';
import { ChatState } from '../../interfaces/application-state';
import ChatUserMessage from './ChatUserMessage';
-import { LoadingOutlined } from '@ant-design/icons';
+import { MessageType } from '../../interfaces/socket-events';
interface Props {
messages: ChatMessage[];
@@ -16,8 +17,19 @@ export default function ChatContainer(props: Props) {
const loading = state === ChatState.Loading;
const chatContainerRef = useRef(null);
- const spinIcon =
+ const spinIcon = ;
+ const getViewForMessage = message => {
+ switch (message.type) {
+ case MessageType.CHAT:
+ return ;
+ default:
+ return null;
+ }
+ return null;
+ };
+
+ console.log(messages);
return (
Chat
@@ -26,9 +38,7 @@ export default function ChatContainer(props: Props) {
ref={chatContainerRef}
initialTopMostItemIndex={999}
data={messages}
- itemContent={(index, message) => (
-
- )}
+ itemContent={(index, message) => getViewForMessage(message)}
followOutput="smooth"
/>
diff --git a/web/components/stores/ClientConfigStore.tsx b/web/components/stores/ClientConfigStore.tsx
index 0cf873ff7..9a92b133b 100644
--- a/web/components/stores/ClientConfigStore.tsx
+++ b/web/components/stores/ClientConfigStore.tsx
@@ -17,7 +17,7 @@ import {
import {
SocketEvent,
ConnectedClientInfoEvent,
- SocketMessageType,
+ MessageType,
ChatEvent,
} from '../../interfaces/socket-events';
import handleConnectedClientInfoMessage from './eventhandlers/connectedclientinfo';
@@ -102,10 +102,10 @@ export function ClientConfigStore() {
const handleMessage = (message: SocketEvent) => {
switch (message.type) {
- case SocketMessageType.CONNECTED_USER_INFO:
+ case MessageType.CONNECTED_USER_INFO:
handleConnectedClientInfoMessage(message as ConnectedClientInfoEvent);
break;
- case SocketMessageType.CHAT:
+ case MessageType.CHAT:
handleChatMessage(message as ChatEvent, chatMessages, setChatMessages);
break;
default:
diff --git a/web/components/ui/Content/Content.tsx b/web/components/ui/Content/Content.tsx
index d992241c3..bc941cd59 100644
--- a/web/components/ui/Content/Content.tsx
+++ b/web/components/ui/Content/Content.tsx
@@ -1,6 +1,12 @@
import { useRecoilValue } from 'recoil';
-import { Layout, Tabs } from 'antd';
-import { chatVisibilityAtom, clientConfigStateAtom } from '../../stores/ClientConfigStore';
+import { Layout, Tabs, Layout, Row, Col, Tabs } from 'antd';
+import Grid from 'antd/lib/card/Grid';
+import {
+ chatVisibilityAtom,
+ clientConfigStateAtom,
+ chatMessagesAtom,
+ chatStateAtom,
+} from '../../stores/ClientConfigStore';
import { ClientConfig } from '../../../interfaces/client-config.model';
import CustomPageContent from '../../CustomPageContent';
import OwncastPlayer from '../../video/OwncastPlayer';
@@ -10,7 +16,6 @@ import Sidebar from '../Sidebar';
import Footer from '../Footer';
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';
@@ -26,6 +31,10 @@ export default function FooterComponent() {
const { extraPageContent } = clientConfig;
+ const followers: Follower[] = [];
+
+ const total = 0;
+
return (
@@ -36,7 +45,7 @@ export default function FooterComponent() {
-
+
{chatOpen && (
diff --git a/web/interfaces/socket-events.ts b/web/interfaces/socket-events.ts
index fde34d67e..1f3066346 100644
--- a/web/interfaces/socket-events.ts
+++ b/web/interfaces/socket-events.ts
@@ -1,6 +1,6 @@
import { User } from './user.model';
-export enum SocketMessageType {
+export enum MessageType {
CHAT = 'CHAT',
PING = 'PING',
NAME_CHANGE = 'NAME_CHANGE',
@@ -21,7 +21,7 @@ export enum SocketMessageType {
export interface SocketEvent {
id: string;
timestamp: Date;
- type: SocketMessageType;
+ type: MessageType;
}
export interface ConnectedClientInfoEvent extends SocketEvent {
diff --git a/web/services/websocket-service.ts b/web/services/websocket-service.ts
index b82bebeb2..9ff972de3 100644
--- a/web/services/websocket-service.ts
+++ b/web/services/websocket-service.ts
@@ -1,8 +1,8 @@
import { message } from 'antd';
-import { SocketMessageType } from '../interfaces/socket-events';
+import { MessageType } from '../interfaces/socket-events';
interface SocketMessage {
- type: SocketMessageType;
+ type: MessageType;
data: any;
}
@@ -96,7 +96,7 @@ export default class WebsocketService {
}
// Send PONGs
- if (message.type === SocketMessageType.PING) {
+ if (message.type === MessageType.PING) {
this.sendPong();
return;
}
@@ -106,7 +106,7 @@ export default class WebsocketService {
// Outbound: Other components can pass an object to `send`.
send(message: any) {
// Sanity check that what we're sending is a valid type.
- if (!message.type || !SocketMessageType[message.type]) {
+ if (!message.type || !MessageType[message.type]) {
console.warn(`Outbound message: Unknown socket message type: "${message.type}" sent.`);
}
@@ -116,7 +116,7 @@ export default class WebsocketService {
// Reply to a PING as a keep alive.
sendPong() {
- const pong = { type: SocketMessageType.PONG };
+ const pong = { type: MessageType.PONG };
this.send(pong);
}
}
diff --git a/web/stories/Follower.stories.tsx b/web/stories/Follower.stories.tsx
index 2f2847dbd..ba0a9e1bc 100644
--- a/web/stories/Follower.stories.tsx
+++ b/web/stories/Follower.stories.tsx
@@ -1,14 +1,14 @@
import React from 'react';
import { ComponentStory, ComponentMeta } from '@storybook/react';
-import * as FollowerComponent from '../components/Follower';
+import SingleFollower from '../components/Follower';
export default {
title: 'owncast/Follower',
- component: FollowerComponent,
+ component: SingleFollower,
parameters: {},
-} as ComponentMeta;
+} as ComponentMeta;
-const Template: ComponentStory = args => ;
+const Template: ComponentStory = args => ;
export const Example = Template.bind({});
Example.args = {