mirror of
https://github.com/owncast/owncast.git
synced 2024-11-21 20:28:15 +03:00
Add current user object that holds user session values instead of standalone getters. Closes #2050
This commit is contained in:
parent
d94723bd3a
commit
80a012a3c7
12 changed files with 103 additions and 98 deletions
3
web/.vscode/settings.json
vendored
3
web/.vscode/settings.json
vendored
|
@ -9,5 +9,6 @@
|
||||||
"linkify",
|
"linkify",
|
||||||
"paypal",
|
"paypal",
|
||||||
"toggleswitch"
|
"toggleswitch"
|
||||||
]
|
],
|
||||||
|
"deepscan.enable": true
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ import { useHotkeys } from 'react-hotkeys-hook';
|
||||||
import dynamic from 'next/dynamic';
|
import dynamic from 'next/dynamic';
|
||||||
import {
|
import {
|
||||||
chatVisibleToggleAtom,
|
chatVisibleToggleAtom,
|
||||||
chatDisplayNameAtom,
|
currentUserAtom,
|
||||||
appStateAtom,
|
appStateAtom,
|
||||||
} from '../../stores/ClientConfigStore';
|
} from '../../stores/ClientConfigStore';
|
||||||
import styles from './UserDropdown.module.scss';
|
import styles from './UserDropdown.module.scss';
|
||||||
|
@ -34,12 +34,19 @@ export type UserDropdownProps = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const UserDropdown: FC<UserDropdownProps> = ({ username: defaultUsername = undefined }) => {
|
export const UserDropdown: FC<UserDropdownProps> = ({ username: defaultUsername = undefined }) => {
|
||||||
const username = defaultUsername || useRecoilValue(chatDisplayNameAtom);
|
|
||||||
const [showNameChangeModal, setShowNameChangeModal] = useState<boolean>(false);
|
const [showNameChangeModal, setShowNameChangeModal] = useState<boolean>(false);
|
||||||
const [showAuthModal, setShowAuthModal] = useState<boolean>(false);
|
const [showAuthModal, setShowAuthModal] = useState<boolean>(false);
|
||||||
const [chatToggleVisible, setChatToggleVisible] = useRecoilState(chatVisibleToggleAtom);
|
const [chatToggleVisible, setChatToggleVisible] = useRecoilState(chatVisibleToggleAtom);
|
||||||
const appState = useRecoilValue<AppStateOptions>(appStateAtom);
|
const appState = useRecoilValue<AppStateOptions>(appStateAtom);
|
||||||
|
|
||||||
|
const currentUser = useRecoilValue(currentUserAtom);
|
||||||
|
if (!currentUser) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { displayName } = currentUser;
|
||||||
|
const username = defaultUsername || displayName;
|
||||||
|
|
||||||
const toggleChatVisibility = () => {
|
const toggleChatVisibility = () => {
|
||||||
setChatToggleVisible(!chatToggleVisible);
|
setChatToggleVisible(!chatToggleVisible);
|
||||||
};
|
};
|
||||||
|
|
|
@ -9,7 +9,7 @@ import IndieAuthIcon from '../../../assets/images/indieauth.png';
|
||||||
|
|
||||||
import styles from './AuthModal.module.scss';
|
import styles from './AuthModal.module.scss';
|
||||||
import {
|
import {
|
||||||
chatDisplayNameAtom,
|
currentUserAtom,
|
||||||
chatAuthenticatedAtom,
|
chatAuthenticatedAtom,
|
||||||
accessTokenAtom,
|
accessTokenAtom,
|
||||||
} from '../../stores/ClientConfigStore';
|
} from '../../stores/ClientConfigStore';
|
||||||
|
@ -17,10 +17,15 @@ import {
|
||||||
const { TabPane } = Tabs;
|
const { TabPane } = Tabs;
|
||||||
|
|
||||||
export const AuthModal: FC = () => {
|
export const AuthModal: FC = () => {
|
||||||
const chatDisplayName = useRecoilValue<string>(chatDisplayNameAtom);
|
const currentUser = useRecoilValue(currentUserAtom);
|
||||||
|
if (!currentUser) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
const authenticated = useRecoilValue<boolean>(chatAuthenticatedAtom);
|
const authenticated = useRecoilValue<boolean>(chatAuthenticatedAtom);
|
||||||
const accessToken = useRecoilValue<string>(accessTokenAtom);
|
const accessToken = useRecoilValue<string>(accessTokenAtom);
|
||||||
const federationEnabled = true;
|
const federationEnabled = true;
|
||||||
|
const { displayName } = currentUser;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
@ -41,7 +46,7 @@ export const AuthModal: FC = () => {
|
||||||
>
|
>
|
||||||
<IndieAuthModal
|
<IndieAuthModal
|
||||||
authenticated={authenticated}
|
authenticated={authenticated}
|
||||||
displayName={chatDisplayName}
|
displayName={displayName}
|
||||||
accessToken={accessToken}
|
accessToken={accessToken}
|
||||||
/>
|
/>
|
||||||
</TabPane>
|
</TabPane>
|
||||||
|
@ -56,7 +61,7 @@ export const AuthModal: FC = () => {
|
||||||
>
|
>
|
||||||
<FediAuthModal
|
<FediAuthModal
|
||||||
authenticated={authenticated}
|
authenticated={authenticated}
|
||||||
displayName={chatDisplayName}
|
displayName={displayName}
|
||||||
accessToken={accessToken}
|
accessToken={accessToken}
|
||||||
/>
|
/>
|
||||||
</TabPane>
|
</TabPane>
|
||||||
|
|
|
@ -3,11 +3,7 @@ import { useRecoilValue } from 'recoil';
|
||||||
import { Input, Button, Select } from 'antd';
|
import { Input, Button, Select } from 'antd';
|
||||||
import { MessageType } from '../../../interfaces/socket-events';
|
import { MessageType } from '../../../interfaces/socket-events';
|
||||||
import WebsocketService from '../../../services/websocket-service';
|
import WebsocketService from '../../../services/websocket-service';
|
||||||
import {
|
import { websocketServiceAtom, currentUserAtom } from '../../stores/ClientConfigStore';
|
||||||
websocketServiceAtom,
|
|
||||||
chatDisplayNameAtom,
|
|
||||||
chatDisplayColorAtom,
|
|
||||||
} from '../../stores/ClientConfigStore';
|
|
||||||
|
|
||||||
const { Option } = Select;
|
const { Option } = Select;
|
||||||
|
|
||||||
|
@ -26,10 +22,14 @@ const UserColor: FC<UserColorProps> = ({ color }) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const NameChangeModal: FC = () => {
|
export const NameChangeModal: FC = () => {
|
||||||
|
const currentUser = useRecoilValue(currentUserAtom);
|
||||||
|
if (!currentUser) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { displayName, displayColor } = currentUser;
|
||||||
const websocketService = useRecoilValue<WebsocketService>(websocketServiceAtom);
|
const websocketService = useRecoilValue<WebsocketService>(websocketServiceAtom);
|
||||||
const chatDisplayName = useRecoilValue<string>(chatDisplayNameAtom);
|
const [newName, setNewName] = useState<any>(displayName);
|
||||||
const chatDisplayColor = useRecoilValue<number>(chatDisplayColorAtom) || 0;
|
|
||||||
const [newName, setNewName] = useState<any>(chatDisplayName);
|
|
||||||
|
|
||||||
const handleNameChange = () => {
|
const handleNameChange = () => {
|
||||||
const nameChange = {
|
const nameChange = {
|
||||||
|
@ -39,8 +39,7 @@ export const NameChangeModal: FC = () => {
|
||||||
websocketService.send(nameChange);
|
websocketService.send(nameChange);
|
||||||
};
|
};
|
||||||
|
|
||||||
const saveEnabled =
|
const saveEnabled = newName !== displayName && newName !== '' && websocketService?.isConnected();
|
||||||
newName !== chatDisplayName && newName !== '' && websocketService?.isConnected();
|
|
||||||
|
|
||||||
const handleColorChange = (color: string) => {
|
const handleColorChange = (color: string) => {
|
||||||
const colorChange = {
|
const colorChange = {
|
||||||
|
@ -63,7 +62,7 @@ export const NameChangeModal: FC = () => {
|
||||||
placeholder="Your chat display name"
|
placeholder="Your chat display name"
|
||||||
maxLength={30}
|
maxLength={30}
|
||||||
showCount
|
showCount
|
||||||
defaultValue={chatDisplayName}
|
defaultValue={displayName}
|
||||||
/>
|
/>
|
||||||
<Button disabled={!saveEnabled} onClick={handleNameChange}>
|
<Button disabled={!saveEnabled} onClick={handleNameChange}>
|
||||||
Change name
|
Change name
|
||||||
|
@ -73,7 +72,7 @@ export const NameChangeModal: FC = () => {
|
||||||
<Select
|
<Select
|
||||||
style={{ width: 120 }}
|
style={{ width: 120 }}
|
||||||
onChange={handleColorChange}
|
onChange={handleColorChange}
|
||||||
defaultValue={chatDisplayColor.toString()}
|
defaultValue={displayColor.toString()}
|
||||||
getPopupContainer={triggerNode => triggerNode.parentElement}
|
getPopupContainer={triggerNode => triggerNode.parentElement}
|
||||||
>
|
>
|
||||||
{colorOptions.map(e => (
|
{colorOptions.map(e => (
|
||||||
|
|
|
@ -6,6 +6,7 @@ import ClientConfigService from '../../services/client-config-service';
|
||||||
import ChatService from '../../services/chat-service';
|
import ChatService from '../../services/chat-service';
|
||||||
import WebsocketService from '../../services/websocket-service';
|
import WebsocketService from '../../services/websocket-service';
|
||||||
import { ChatMessage } from '../../interfaces/chat-message.model';
|
import { ChatMessage } from '../../interfaces/chat-message.model';
|
||||||
|
import { CurrentUser } from '../../interfaces/current-user';
|
||||||
import { ServerStatus, makeEmptyServerStatus } from '../../interfaces/server-status.model';
|
import { ServerStatus, makeEmptyServerStatus } from '../../interfaces/server-status.model';
|
||||||
import appStateModel, {
|
import appStateModel, {
|
||||||
AppStateEvent,
|
AppStateEvent,
|
||||||
|
@ -44,31 +45,16 @@ export const clientConfigStateAtom = atom({
|
||||||
default: makeEmptyClientConfig(),
|
default: makeEmptyClientConfig(),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const chatDisplayNameAtom = atom<string>({
|
|
||||||
key: 'chatDisplayName',
|
|
||||||
default: null,
|
|
||||||
});
|
|
||||||
|
|
||||||
export const chatDisplayColorAtom = atom<number>({
|
|
||||||
key: 'chatDisplayColor',
|
|
||||||
default: null,
|
|
||||||
});
|
|
||||||
|
|
||||||
export const chatUserIdAtom = atom<string>({
|
|
||||||
key: 'chatUserIdAtom',
|
|
||||||
default: null,
|
|
||||||
});
|
|
||||||
|
|
||||||
export const isChatModeratorAtom = atom<boolean>({
|
|
||||||
key: 'isModeratorAtom',
|
|
||||||
default: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
export const accessTokenAtom = atom<string>({
|
export const accessTokenAtom = atom<string>({
|
||||||
key: 'accessTokenAtom',
|
key: 'accessTokenAtom',
|
||||||
default: null,
|
default: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const currentUserAtom = atom<CurrentUser>({
|
||||||
|
key: 'currentUserAtom',
|
||||||
|
default: null,
|
||||||
|
});
|
||||||
|
|
||||||
export const chatMessagesAtom = atom<ChatMessage[]>({
|
export const chatMessagesAtom = atom<ChatMessage[]>({
|
||||||
key: 'chatMessages',
|
key: 'chatMessages',
|
||||||
default: [] as ChatMessage[],
|
default: [] as ChatMessage[],
|
||||||
|
@ -126,7 +112,7 @@ export const isChatVisibleSelector = selector({
|
||||||
get: ({ get }) => {
|
get: ({ get }) => {
|
||||||
const state: AppStateOptions = get(appStateAtom);
|
const state: AppStateOptions = get(appStateAtom);
|
||||||
const userVisibleToggle: boolean = get(chatVisibleToggleAtom);
|
const userVisibleToggle: boolean = get(chatVisibleToggleAtom);
|
||||||
const accessToken: String = get(accessTokenAtom);
|
const accessToken: string = get(accessTokenAtom);
|
||||||
return accessToken && state.chatAvailable && userVisibleToggle;
|
return accessToken && state.chatAvailable && userVisibleToggle;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -135,7 +121,7 @@ export const isChatAvailableSelector = selector({
|
||||||
key: 'isChatAvailableSelector',
|
key: 'isChatAvailableSelector',
|
||||||
get: ({ get }) => {
|
get: ({ get }) => {
|
||||||
const state: AppStateOptions = get(appStateAtom);
|
const state: AppStateOptions = get(appStateAtom);
|
||||||
const accessToken: String = get(accessTokenAtom);
|
const accessToken: string = get(accessTokenAtom);
|
||||||
return accessToken && state.chatAvailable;
|
return accessToken && state.chatAvailable;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -174,12 +160,8 @@ function mergeMeta(meta) {
|
||||||
|
|
||||||
export const ClientConfigStore: FC = () => {
|
export const ClientConfigStore: FC = () => {
|
||||||
const [appState, appStateSend, appStateService] = useMachine(appStateModel);
|
const [appState, appStateSend, appStateService] = useMachine(appStateModel);
|
||||||
|
const [currentUser, setCurrentUser] = useRecoilState(currentUserAtom);
|
||||||
const setChatDisplayName = useSetRecoilState<string>(chatDisplayNameAtom);
|
|
||||||
const setChatDisplayColor = useSetRecoilState<Number>(chatDisplayColorAtom);
|
|
||||||
const setChatUserId = useSetRecoilState<string>(chatUserIdAtom);
|
|
||||||
const setChatAuthenticated = useSetRecoilState<boolean>(chatAuthenticatedAtom);
|
const setChatAuthenticated = useSetRecoilState<boolean>(chatAuthenticatedAtom);
|
||||||
const setIsChatModerator = useSetRecoilState<boolean>(isChatModeratorAtom);
|
|
||||||
const [clientConfig, setClientConfig] = useRecoilState<ClientConfig>(clientConfigStateAtom);
|
const [clientConfig, setClientConfig] = useRecoilState<ClientConfig>(clientConfigStateAtom);
|
||||||
const setServerStatus = useSetRecoilState<ServerStatus>(serverStatusState);
|
const setServerStatus = useSetRecoilState<ServerStatus>(serverStatusState);
|
||||||
const setClockSkew = useSetRecoilState<Number>(clockSkewAtom);
|
const setClockSkew = useSetRecoilState<Number>(clockSkewAtom);
|
||||||
|
@ -264,10 +246,13 @@ export const ClientConfigStore: FC = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('setting access token', newAccessToken);
|
console.log('setting access token', newAccessToken);
|
||||||
|
setCurrentUser({
|
||||||
|
...currentUser,
|
||||||
|
displayName: newDisplayName,
|
||||||
|
displayColor,
|
||||||
|
});
|
||||||
setAccessToken(newAccessToken);
|
setAccessToken(newAccessToken);
|
||||||
setLocalStorage(ACCESS_TOKEN_KEY, newAccessToken);
|
setLocalStorage(ACCESS_TOKEN_KEY, newAccessToken);
|
||||||
setChatDisplayName(newDisplayName);
|
|
||||||
setChatDisplayColor(displayColor);
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
sendEvent(AppStateEvent.Fail);
|
sendEvent(AppStateEvent.Fail);
|
||||||
console.error(`ChatService -> registerUser() ERROR: \n${e}`);
|
console.error(`ChatService -> registerUser() ERROR: \n${e}`);
|
||||||
|
@ -276,7 +261,7 @@ export const ClientConfigStore: FC = () => {
|
||||||
|
|
||||||
const resetAndReAuth = () => {
|
const resetAndReAuth = () => {
|
||||||
setLocalStorage(ACCESS_TOKEN_KEY, '');
|
setLocalStorage(ACCESS_TOKEN_KEY, '');
|
||||||
setAccessToken('');
|
setAccessToken(null);
|
||||||
handleUserRegistration();
|
handleUserRegistration();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -299,11 +284,8 @@ export const ClientConfigStore: FC = () => {
|
||||||
case MessageType.CONNECTED_USER_INFO:
|
case MessageType.CONNECTED_USER_INFO:
|
||||||
handleConnectedClientInfoMessage(
|
handleConnectedClientInfoMessage(
|
||||||
message as ConnectedClientInfoEvent,
|
message as ConnectedClientInfoEvent,
|
||||||
setChatDisplayName,
|
|
||||||
setChatDisplayColor,
|
|
||||||
setChatUserId,
|
|
||||||
setIsChatModerator,
|
|
||||||
setChatAuthenticated,
|
setChatAuthenticated,
|
||||||
|
setCurrentUser,
|
||||||
);
|
);
|
||||||
setChatMessages(currentState => [...currentState, message as ChatEvent]);
|
setChatMessages(currentState => [...currentState, message as ChatEvent]);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -2,18 +2,18 @@ import { ConnectedClientInfoEvent } from '../../../interfaces/socket-events';
|
||||||
|
|
||||||
export function handleConnectedClientInfoMessage(
|
export function handleConnectedClientInfoMessage(
|
||||||
message: ConnectedClientInfoEvent,
|
message: ConnectedClientInfoEvent,
|
||||||
setChatDisplayName: (string) => void,
|
|
||||||
setChatDisplayColor: (number) => void,
|
|
||||||
setChatUserId: (number) => void,
|
|
||||||
setIsChatModerator: (boolean) => void,
|
|
||||||
setChatAuthenticated: (boolean) => void,
|
setChatAuthenticated: (boolean) => void,
|
||||||
|
setCurrentUser: (CurrentUser) => void,
|
||||||
) {
|
) {
|
||||||
const { user } = message;
|
const { user } = message;
|
||||||
const { id, displayName, displayColor, scopes, authenticated } = user;
|
const { id, displayName, displayColor, scopes, authenticated } = user;
|
||||||
setChatDisplayName(displayName);
|
|
||||||
setChatDisplayColor(displayColor);
|
|
||||||
setChatUserId(id);
|
|
||||||
setIsChatModerator(scopes?.includes('MODERATOR'));
|
|
||||||
setChatAuthenticated(authenticated);
|
setChatAuthenticated(authenticated);
|
||||||
|
|
||||||
|
setCurrentUser({
|
||||||
|
id: id.toString(),
|
||||||
|
displayName,
|
||||||
|
displayColor,
|
||||||
|
isModerator: scopes?.includes('MODERATOR'),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
export default handleConnectedClientInfoMessage;
|
export default handleConnectedClientInfoMessage;
|
||||||
|
|
|
@ -8,8 +8,7 @@ import { LOCAL_STORAGE_KEYS, getLocalStorage, setLocalStorage } from '../../../u
|
||||||
import {
|
import {
|
||||||
clientConfigStateAtom,
|
clientConfigStateAtom,
|
||||||
chatMessagesAtom,
|
chatMessagesAtom,
|
||||||
chatDisplayNameAtom,
|
currentUserAtom,
|
||||||
chatUserIdAtom,
|
|
||||||
isChatAvailableSelector,
|
isChatAvailableSelector,
|
||||||
isChatVisibleSelector,
|
isChatVisibleSelector,
|
||||||
appStateAtom,
|
appStateAtom,
|
||||||
|
@ -134,12 +133,12 @@ export const Content: FC = () => {
|
||||||
const clientConfig = useRecoilValue<ClientConfig>(clientConfigStateAtom);
|
const clientConfig = useRecoilValue<ClientConfig>(clientConfigStateAtom);
|
||||||
const isChatVisible = useRecoilValue<boolean>(isChatVisibleSelector);
|
const isChatVisible = useRecoilValue<boolean>(isChatVisibleSelector);
|
||||||
const isChatAvailable = useRecoilValue<boolean>(isChatAvailableSelector);
|
const isChatAvailable = useRecoilValue<boolean>(isChatAvailableSelector);
|
||||||
|
const currentUser = useRecoilValue(currentUserAtom);
|
||||||
|
|
||||||
const [isMobile, setIsMobile] = useRecoilState<boolean | undefined>(isMobileAtom);
|
const [isMobile, setIsMobile] = useRecoilState<boolean | undefined>(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 chatUserId = useRecoilValue<string>(chatUserIdAtom);
|
|
||||||
const { viewerCount, lastConnectTime, lastDisconnectTime, streamTitle } =
|
const { viewerCount, lastConnectTime, lastDisconnectTime, streamTitle } =
|
||||||
useRecoilValue<ServerStatus>(serverStatusState);
|
useRecoilValue<ServerStatus>(serverStatusState);
|
||||||
const {
|
const {
|
||||||
|
@ -200,6 +199,11 @@ export const Content: FC = () => {
|
||||||
window.addEventListener('resize', checkIfMobile);
|
window.addEventListener('resize', checkIfMobile);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
if (!currentUser) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { id: currentUserId, displayName } = currentUser;
|
||||||
const showChat = !chatDisabled && isChatAvailable && isChatVisible;
|
const showChat = !chatDisabled && isChatAvailable && isChatVisible;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -261,8 +265,8 @@ export const Content: FC = () => {
|
||||||
socialHandles={socialHandles}
|
socialHandles={socialHandles}
|
||||||
extraPageContent={extraPageContent}
|
extraPageContent={extraPageContent}
|
||||||
messages={messages}
|
messages={messages}
|
||||||
chatDisplayName={chatDisplayName}
|
chatDisplayName={displayName}
|
||||||
chatUserId={chatUserId}
|
chatUserId={currentUserId}
|
||||||
showChat={showChat}
|
showChat={showChat}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
|
|
|
@ -5,26 +5,20 @@ import { ChatMessage } from '../../../interfaces/chat-message.model';
|
||||||
import { ChatContainer } from '../../chat/ChatContainer/ChatContainer';
|
import { ChatContainer } from '../../chat/ChatContainer/ChatContainer';
|
||||||
import styles from './Sidebar.module.scss';
|
import styles from './Sidebar.module.scss';
|
||||||
|
|
||||||
import {
|
import { currentUserAtom, visibleChatMessagesSelector } from '../../stores/ClientConfigStore';
|
||||||
chatDisplayNameAtom,
|
|
||||||
chatUserIdAtom,
|
|
||||||
isChatModeratorAtom,
|
|
||||||
visibleChatMessagesSelector,
|
|
||||||
} from '../../stores/ClientConfigStore';
|
|
||||||
|
|
||||||
export const Sidebar: FC = () => {
|
export const Sidebar: FC = () => {
|
||||||
const chatDisplayName = useRecoilValue<string>(chatDisplayNameAtom);
|
const currentUser = useRecoilValue(currentUserAtom);
|
||||||
const chatUserId = useRecoilValue<string>(chatUserIdAtom);
|
|
||||||
const isChatModerator = useRecoilValue<boolean>(isChatModeratorAtom);
|
|
||||||
const messages = useRecoilValue<ChatMessage[]>(visibleChatMessagesSelector);
|
const messages = useRecoilValue<ChatMessage[]>(visibleChatMessagesSelector);
|
||||||
|
|
||||||
|
const { id, isModerator, displayName } = currentUser;
|
||||||
return (
|
return (
|
||||||
<Sider className={styles.root} collapsedWidth={0} width={320}>
|
<Sider className={styles.root} collapsedWidth={0} width={320}>
|
||||||
<ChatContainer
|
<ChatContainer
|
||||||
messages={messages}
|
messages={messages}
|
||||||
usernameToHighlight={chatDisplayName}
|
usernameToHighlight={displayName}
|
||||||
chatUserId={chatUserId}
|
chatUserId={id}
|
||||||
isModerator={isChatModerator}
|
isModerator={isModerator}
|
||||||
/>
|
/>
|
||||||
</Sider>
|
</Sider>
|
||||||
);
|
);
|
||||||
|
|
6
web/interfaces/current-user.ts
Normal file
6
web/interfaces/current-user.ts
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
export interface CurrentUser {
|
||||||
|
id: string;
|
||||||
|
displayName: string;
|
||||||
|
displayColor: number;
|
||||||
|
isModerator: boolean;
|
||||||
|
}
|
|
@ -3,23 +3,24 @@ import { ChatMessage } from '../../../../interfaces/chat-message.model';
|
||||||
import { ChatContainer } from '../../../../components/chat/ChatContainer/ChatContainer';
|
import { ChatContainer } from '../../../../components/chat/ChatContainer/ChatContainer';
|
||||||
import {
|
import {
|
||||||
ClientConfigStore,
|
ClientConfigStore,
|
||||||
chatDisplayNameAtom,
|
currentUserAtom,
|
||||||
chatUserIdAtom,
|
|
||||||
visibleChatMessagesSelector,
|
visibleChatMessagesSelector,
|
||||||
} from '../../../../components/stores/ClientConfigStore';
|
} from '../../../../components/stores/ClientConfigStore';
|
||||||
|
|
||||||
export default function ReadOnlyChatEmbed() {
|
export default function ReadOnlyChatEmbed() {
|
||||||
const chatDisplayName = useRecoilValue<string>(chatDisplayNameAtom);
|
const currentUser = useRecoilValue(currentUserAtom);
|
||||||
const chatUserId = useRecoilValue<string>(chatUserIdAtom);
|
|
||||||
const messages = useRecoilValue<ChatMessage[]>(visibleChatMessagesSelector);
|
const messages = useRecoilValue<ChatMessage[]>(visibleChatMessagesSelector);
|
||||||
|
if (!currentUser) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const { id, displayName } = currentUser;
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<ClientConfigStore />
|
<ClientConfigStore />
|
||||||
<ChatContainer
|
<ChatContainer
|
||||||
messages={messages}
|
messages={messages}
|
||||||
usernameToHighlight={chatDisplayName}
|
usernameToHighlight={displayName}
|
||||||
chatUserId={chatUserId}
|
chatUserId={id}
|
||||||
isModerator={false}
|
isModerator={false}
|
||||||
showInput={false}
|
showInput={false}
|
||||||
height="100vh"
|
height="100vh"
|
||||||
|
|
|
@ -3,32 +3,34 @@ import { ChatMessage } from '../../../../interfaces/chat-message.model';
|
||||||
import { ChatContainer } from '../../../../components/chat/ChatContainer/ChatContainer';
|
import { ChatContainer } from '../../../../components/chat/ChatContainer/ChatContainer';
|
||||||
import {
|
import {
|
||||||
ClientConfigStore,
|
ClientConfigStore,
|
||||||
chatDisplayNameAtom,
|
currentUserAtom,
|
||||||
chatUserIdAtom,
|
|
||||||
visibleChatMessagesSelector,
|
visibleChatMessagesSelector,
|
||||||
clientConfigStateAtom,
|
clientConfigStateAtom,
|
||||||
isChatModeratorAtom,
|
|
||||||
} from '../../../../components/stores/ClientConfigStore';
|
} from '../../../../components/stores/ClientConfigStore';
|
||||||
import Header from '../../../../components/ui/Header/Header';
|
import Header from '../../../../components/ui/Header/Header';
|
||||||
import { ClientConfig } from '../../../../interfaces/client-config.model';
|
import { ClientConfig } from '../../../../interfaces/client-config.model';
|
||||||
|
|
||||||
export default function ReadWriteChatEmbed() {
|
export default function ReadWriteChatEmbed() {
|
||||||
const chatDisplayName = useRecoilValue<string>(chatDisplayNameAtom);
|
const currentUser = useRecoilValue(currentUserAtom);
|
||||||
const chatUserId = useRecoilValue<string>(chatUserIdAtom);
|
|
||||||
const messages = useRecoilValue<ChatMessage[]>(visibleChatMessagesSelector);
|
const messages = useRecoilValue<ChatMessage[]>(visibleChatMessagesSelector);
|
||||||
const clientConfig = useRecoilValue<ClientConfig>(clientConfigStateAtom);
|
const clientConfig = useRecoilValue<ClientConfig>(clientConfigStateAtom);
|
||||||
const isModerator = useRecoilValue<boolean>(isChatModeratorAtom);
|
|
||||||
|
|
||||||
const { name, chatDisabled } = clientConfig;
|
const { name, chatDisabled } = clientConfig;
|
||||||
|
|
||||||
|
if (!currentUser) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { id, displayName, isModerator } = currentUser;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<ClientConfigStore />
|
<ClientConfigStore />
|
||||||
<Header name={name} chatAvailable chatDisabled={chatDisabled} />
|
<Header name={name} chatAvailable chatDisabled={chatDisabled} />
|
||||||
<ChatContainer
|
<ChatContainer
|
||||||
messages={messages}
|
messages={messages}
|
||||||
usernameToHighlight={chatDisplayName}
|
usernameToHighlight={displayName}
|
||||||
chatUserId={chatUserId}
|
chatUserId={id}
|
||||||
isModerator={isModerator}
|
isModerator={isModerator}
|
||||||
showInput
|
showInput
|
||||||
height="80vh"
|
height="80vh"
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import React, { useEffect } from 'react';
|
import React, { useEffect } from 'react';
|
||||||
import { ComponentStory, ComponentMeta } from '@storybook/react';
|
import { ComponentStory, ComponentMeta } from '@storybook/react';
|
||||||
import { RecoilRoot, useSetRecoilState } from 'recoil';
|
import { RecoilRoot, useRecoilState, useSetRecoilState } from 'recoil';
|
||||||
import ReadWritePage from '../pages/embed/chat/readwrite/index';
|
import ReadWritePage from '../pages/embed/chat/readwrite/index';
|
||||||
import { ChatMessage } from '../interfaces/chat-message.model';
|
import { ChatMessage } from '../interfaces/chat-message.model';
|
||||||
import {
|
import {
|
||||||
chatMessagesAtom,
|
chatMessagesAtom,
|
||||||
chatDisplayNameAtom,
|
currentUserAtom,
|
||||||
clientConfigStateAtom,
|
clientConfigStateAtom,
|
||||||
} from '../components/stores/ClientConfigStore';
|
} from '../components/stores/ClientConfigStore';
|
||||||
import { ClientConfig } from '../interfaces/client-config.model';
|
import { ClientConfig } from '../interfaces/client-config.model';
|
||||||
|
@ -21,8 +21,8 @@ const testMessages =
|
||||||
const messages: ChatMessage[] = JSON.parse(testMessages);
|
const messages: ChatMessage[] = JSON.parse(testMessages);
|
||||||
|
|
||||||
const Page = () => {
|
const Page = () => {
|
||||||
|
const [currentUser, setCurrentUser] = useRecoilState(currentUserAtom);
|
||||||
const setMessages = useSetRecoilState(chatMessagesAtom);
|
const setMessages = useSetRecoilState(chatMessagesAtom);
|
||||||
const setDisplayName = useSetRecoilState(chatDisplayNameAtom);
|
|
||||||
const setClientConfig = useSetRecoilState<ClientConfig>(clientConfigStateAtom);
|
const setClientConfig = useSetRecoilState<ClientConfig>(clientConfigStateAtom);
|
||||||
|
|
||||||
const fakeConfig: ClientConfig = {
|
const fakeConfig: ClientConfig = {
|
||||||
|
@ -45,7 +45,11 @@ const Page = () => {
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setMessages(messages);
|
setMessages(messages);
|
||||||
setDisplayName('fake-chat-user');
|
setCurrentUser({
|
||||||
|
...currentUser,
|
||||||
|
displayName: 'fake-chat-user',
|
||||||
|
});
|
||||||
|
|
||||||
setClientConfig(fakeConfig);
|
setClientConfig(fakeConfig);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue