2022-05-03 08:13:36 +03:00
|
|
|
/* eslint-disable no-case-declarations */
|
2022-05-14 00:44:16 +03:00
|
|
|
import { useEffect } from 'react';
|
2022-05-03 03:45:22 +03:00
|
|
|
import { atom, useRecoilState, useSetRecoilState } from 'recoil';
|
2022-04-28 09:19:20 +03:00
|
|
|
import { makeEmptyClientConfig, ClientConfig } from '../../interfaces/client-config.model';
|
|
|
|
import ClientConfigService from '../../services/client-config-service';
|
2022-04-30 01:09:53 +03:00
|
|
|
import ChatService from '../../services/chat-service';
|
2022-05-03 03:45:22 +03:00
|
|
|
import WebsocketService from '../../services/websocket-service';
|
2022-04-29 00:36:05 +03:00
|
|
|
import { ChatMessage } from '../../interfaces/chat-message.model';
|
2022-05-14 00:44:16 +03:00
|
|
|
import { ServerStatus, makeEmptyServerStatus } from '../../interfaces/server-status.model';
|
|
|
|
|
2022-05-03 03:45:22 +03:00
|
|
|
import {
|
|
|
|
AppState,
|
|
|
|
ChatState,
|
2022-05-11 01:36:09 +03:00
|
|
|
VideoState,
|
2022-05-03 03:45:22 +03:00
|
|
|
ChatVisibilityState,
|
|
|
|
getChatState,
|
|
|
|
getChatVisibilityState,
|
|
|
|
} from '../../interfaces/application-state';
|
2022-05-03 08:13:36 +03:00
|
|
|
import {
|
|
|
|
ConnectedClientInfoEvent,
|
2022-05-04 00:17:05 +03:00
|
|
|
MessageType,
|
2022-05-03 08:13:36 +03:00
|
|
|
ChatEvent,
|
2022-05-12 09:31:31 +03:00
|
|
|
SocketEvent,
|
2022-05-03 08:13:36 +03:00
|
|
|
} from '../../interfaces/socket-events';
|
|
|
|
import handleConnectedClientInfoMessage from './eventhandlers/connectedclientinfo';
|
|
|
|
import handleChatMessage from './eventhandlers/handleChatMessage';
|
2022-05-14 00:44:16 +03:00
|
|
|
import ServerStatusService from '../../services/status-service';
|
|
|
|
|
|
|
|
// Server status is what gets updated such as viewer count, durations,
|
|
|
|
// stream title, online/offline state, etc.
|
|
|
|
export const serverStatusState = atom<ServerStatus>({
|
|
|
|
key: 'serverStatusState',
|
|
|
|
default: makeEmptyServerStatus(),
|
|
|
|
});
|
2022-04-26 09:10:07 +03:00
|
|
|
|
2022-04-28 09:19:20 +03:00
|
|
|
// The config that comes from the API.
|
2022-05-03 03:45:22 +03:00
|
|
|
export const clientConfigStateAtom = atom({
|
2022-04-26 09:10:07 +03:00
|
|
|
key: 'clientConfigState',
|
|
|
|
default: makeEmptyClientConfig(),
|
|
|
|
});
|
|
|
|
|
2022-05-03 03:45:22 +03:00
|
|
|
export const appStateAtom = atom<AppState>({
|
|
|
|
key: 'appStateAtom',
|
|
|
|
default: AppState.Loading,
|
|
|
|
});
|
|
|
|
|
|
|
|
export const chatStateAtom = atom<ChatState>({
|
|
|
|
key: 'chatStateAtom',
|
|
|
|
default: ChatState.Offline,
|
|
|
|
});
|
|
|
|
|
2022-05-11 01:36:09 +03:00
|
|
|
export const videoStateAtom = atom<VideoState>({
|
|
|
|
key: 'videoStateAtom',
|
|
|
|
default: VideoState.Unavailable,
|
|
|
|
});
|
|
|
|
|
2022-05-03 03:45:22 +03:00
|
|
|
export const chatVisibilityAtom = atom<ChatVisibilityState>({
|
2022-04-30 01:09:53 +03:00
|
|
|
key: 'chatVisibility',
|
2022-05-03 03:45:22 +03:00
|
|
|
default: ChatVisibilityState.Visible,
|
2022-04-28 09:19:20 +03:00
|
|
|
});
|
|
|
|
|
2022-05-03 03:45:22 +03:00
|
|
|
export const chatDisplayNameAtom = atom<string>({
|
2022-04-28 09:19:20 +03:00
|
|
|
key: 'chatDisplayName',
|
2022-04-30 01:09:53 +03:00
|
|
|
default: null,
|
|
|
|
});
|
|
|
|
|
2022-05-03 03:45:22 +03:00
|
|
|
export const accessTokenAtom = atom<string>({
|
|
|
|
key: 'accessTokenAtom',
|
2022-04-30 01:09:53 +03:00
|
|
|
default: null,
|
2022-04-28 09:19:20 +03:00
|
|
|
});
|
|
|
|
|
2022-05-03 03:45:22 +03:00
|
|
|
export const chatMessagesAtom = atom<ChatMessage[]>({
|
2022-04-29 00:36:05 +03:00
|
|
|
key: 'chatMessages',
|
|
|
|
default: [] as ChatMessage[],
|
|
|
|
});
|
|
|
|
|
2022-05-05 02:55:54 +03:00
|
|
|
export const websocketServiceAtom = atom<WebsocketService>({
|
|
|
|
key: 'websocketServiceAtom',
|
|
|
|
default: null,
|
|
|
|
});
|
|
|
|
|
2022-04-30 01:09:53 +03:00
|
|
|
export function ClientConfigStore() {
|
2022-05-03 03:45:22 +03:00
|
|
|
const setClientConfig = useSetRecoilState<ClientConfig>(clientConfigStateAtom);
|
2022-05-14 00:44:16 +03:00
|
|
|
const setServerStatus = useSetRecoilState<ServerStatus>(serverStatusState);
|
2022-05-03 03:45:22 +03:00
|
|
|
const setChatVisibility = useSetRecoilState<ChatVisibilityState>(chatVisibilityAtom);
|
2022-05-03 08:13:36 +03:00
|
|
|
const setChatState = useSetRecoilState<ChatState>(chatStateAtom);
|
2022-05-03 23:01:50 +03:00
|
|
|
const [chatMessages, setChatMessages] = useRecoilState<ChatMessage[]>(chatMessagesAtom);
|
2022-05-03 03:45:22 +03:00
|
|
|
const setChatDisplayName = useSetRecoilState<string>(chatDisplayNameAtom);
|
2022-05-03 08:13:36 +03:00
|
|
|
const [appState, setAppState] = useRecoilState<AppState>(appStateAtom);
|
|
|
|
const [accessToken, setAccessToken] = useRecoilState<string>(accessTokenAtom);
|
2022-05-12 09:31:31 +03:00
|
|
|
const setWebsocketService = useSetRecoilState<WebsocketService>(websocketServiceAtom);
|
2022-05-03 08:13:36 +03:00
|
|
|
|
2022-05-05 09:06:35 +03:00
|
|
|
let ws: WebsocketService;
|
2022-04-26 09:10:07 +03:00
|
|
|
|
|
|
|
const updateClientConfig = async () => {
|
|
|
|
try {
|
|
|
|
const config = await ClientConfigService.getConfig();
|
|
|
|
setClientConfig(config);
|
|
|
|
} catch (error) {
|
|
|
|
console.error(`ClientConfigService -> getConfig() ERROR: \n${error}`);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2022-05-14 00:44:16 +03:00
|
|
|
const updateServerStatus = async () => {
|
|
|
|
try {
|
|
|
|
const status = await ServerStatusService.getStatus();
|
|
|
|
setServerStatus(status);
|
|
|
|
if (status.online) {
|
|
|
|
setAppState(AppState.Online);
|
|
|
|
} else {
|
|
|
|
setAppState(AppState.Offline);
|
|
|
|
}
|
|
|
|
return status;
|
|
|
|
} catch (error) {
|
|
|
|
console.error(`serverStatusState -> getStatus() ERROR: \n${error}`);
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2022-05-03 03:45:22 +03:00
|
|
|
const handleUserRegistration = async (optionalDisplayName?: string) => {
|
2022-04-30 01:09:53 +03:00
|
|
|
try {
|
2022-05-03 03:45:22 +03:00
|
|
|
setAppState(AppState.Registering);
|
2022-04-30 01:09:53 +03:00
|
|
|
const response = await ChatService.registerUser(optionalDisplayName);
|
2022-05-03 03:45:22 +03:00
|
|
|
console.log(`ChatService -> registerUser() response: \n${response}`);
|
|
|
|
const { accessToken: newAccessToken, displayName: newDisplayName } = response;
|
2022-04-30 01:09:53 +03:00
|
|
|
if (!newAccessToken) {
|
|
|
|
return;
|
|
|
|
}
|
2022-05-03 03:45:22 +03:00
|
|
|
console.log('setting access token', newAccessToken);
|
|
|
|
setAccessToken(newAccessToken);
|
|
|
|
// setLocalStorage('accessToken', newAccessToken);
|
|
|
|
setChatDisplayName(newDisplayName);
|
2022-04-30 01:09:53 +03:00
|
|
|
} catch (e) {
|
|
|
|
console.error(`ChatService -> registerUser() ERROR: \n${e}`);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2022-05-03 08:13:36 +03:00
|
|
|
const handleMessage = (message: SocketEvent) => {
|
|
|
|
switch (message.type) {
|
2022-05-04 00:17:05 +03:00
|
|
|
case MessageType.CONNECTED_USER_INFO:
|
2022-05-03 08:13:36 +03:00
|
|
|
handleConnectedClientInfoMessage(message as ConnectedClientInfoEvent);
|
|
|
|
break;
|
2022-05-04 00:17:05 +03:00
|
|
|
case MessageType.CHAT:
|
2022-05-03 23:01:50 +03:00
|
|
|
handleChatMessage(message as ChatEvent, chatMessages, setChatMessages);
|
2022-05-03 08:13:36 +03:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
console.error('Unknown socket message type: ', message.type);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2022-04-30 01:09:53 +03:00
|
|
|
const getChatHistory = async () => {
|
|
|
|
try {
|
|
|
|
const messages = await ChatService.getChatHistory(accessToken);
|
2022-05-03 23:01:50 +03:00
|
|
|
const updatedChatMessages = [...messages, ...chatMessages];
|
|
|
|
setChatMessages(updatedChatMessages);
|
2022-04-30 01:09:53 +03:00
|
|
|
} catch (error) {
|
|
|
|
console.error(`ChatService -> getChatHistory() ERROR: \n${error}`);
|
|
|
|
}
|
2022-05-03 08:13:36 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
const startChat = async () => {
|
|
|
|
setChatState(ChatState.Loading);
|
|
|
|
try {
|
2022-05-05 09:06:35 +03:00
|
|
|
ws = new WebsocketService(accessToken, '/ws');
|
2022-05-05 02:55:54 +03:00
|
|
|
ws.handleMessage = handleMessage;
|
|
|
|
setWebsocketService(ws);
|
2022-05-03 08:13:36 +03:00
|
|
|
} catch (error) {
|
|
|
|
console.error(`ChatService -> startChat() ERROR: \n${error}`);
|
|
|
|
}
|
2022-04-30 01:09:53 +03:00
|
|
|
};
|
|
|
|
|
2022-04-26 09:10:07 +03:00
|
|
|
useEffect(() => {
|
|
|
|
updateClientConfig();
|
2022-04-30 01:09:53 +03:00
|
|
|
handleUserRegistration();
|
2022-04-26 09:10:07 +03:00
|
|
|
}, []);
|
|
|
|
|
2022-05-14 00:44:16 +03:00
|
|
|
useEffect(() => {
|
|
|
|
setInterval(() => {
|
|
|
|
updateServerStatus();
|
|
|
|
}, 5000);
|
|
|
|
updateServerStatus();
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
useEffect(() => {
|
2022-05-03 03:45:22 +03:00
|
|
|
if (!accessToken) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-04-30 01:09:53 +03:00
|
|
|
getChatHistory();
|
2022-05-03 08:13:36 +03:00
|
|
|
startChat();
|
2022-04-30 01:09:53 +03:00
|
|
|
}, [accessToken]);
|
|
|
|
|
2022-05-03 03:45:22 +03:00
|
|
|
useEffect(() => {
|
|
|
|
const updatedChatState = getChatState(appState);
|
2022-05-14 00:44:16 +03:00
|
|
|
console.log('updatedChatState', updatedChatState);
|
2022-05-03 03:45:22 +03:00
|
|
|
setChatState(updatedChatState);
|
|
|
|
const updatedChatVisibility = getChatVisibilityState(appState);
|
|
|
|
console.log(
|
|
|
|
'app state: ',
|
|
|
|
AppState[appState],
|
|
|
|
'chat state:',
|
|
|
|
ChatState[updatedChatState],
|
|
|
|
'chat visibility:',
|
|
|
|
ChatVisibilityState[updatedChatVisibility],
|
|
|
|
);
|
|
|
|
setChatVisibility(updatedChatVisibility);
|
|
|
|
}, [appState]);
|
|
|
|
|
2022-04-26 09:10:07 +03:00
|
|
|
return null;
|
|
|
|
}
|