Chat popup (#3098)
* add pop out chat button * add button to close chat popup * chat is hidden on main interface when a popup chat is open * NameChangeEvent renames clients with the given id if you have two or more owncast windows (or pop-out chats) open, changing your name in 1 client is reflected in all clients. * replace isChatVisible booleans with chatState enum * update stories to use ChatState * fix build tests --------- Co-authored-by: janWilejan <>
This commit is contained in:
@@ -18,6 +18,7 @@ import {
|
||||
ConnectedClientInfoEvent,
|
||||
MessageType,
|
||||
ChatEvent,
|
||||
NameChangeEvent,
|
||||
MessageVisibilityEvent,
|
||||
SocketEvent,
|
||||
FediverseEvent,
|
||||
@@ -88,11 +89,6 @@ export const isMobileAtom = atom<boolean | undefined>({
|
||||
default: undefined,
|
||||
});
|
||||
|
||||
export const chatVisibleToggleAtom = atom<boolean>({
|
||||
key: 'chatVisibilityToggleAtom',
|
||||
default: true,
|
||||
});
|
||||
|
||||
export const isVideoPlayingAtom = atom<boolean>({
|
||||
key: 'isVideoPlayingAtom',
|
||||
default: false,
|
||||
@@ -122,15 +118,23 @@ export const isChatAvailableSelector = selector({
|
||||
},
|
||||
});
|
||||
|
||||
// Chat is visible if the user wishes it to be visible AND the required
|
||||
// chat state is set.
|
||||
export const isChatVisibleSelector = selector({
|
||||
key: 'isChatVisibleSelector',
|
||||
get: ({ get }) => {
|
||||
const state: AppStateOptions = get(appStateAtom);
|
||||
const userVisibleToggle: boolean = get(chatVisibleToggleAtom);
|
||||
return state.chatAvailable && userVisibleToggle && !hasWebsocketDisconnected;
|
||||
},
|
||||
// The requested state of chat in the UI
|
||||
export enum ChatState {
|
||||
VISIBLE, // Chat is open (the default state when the stream is online)
|
||||
HIDDEN, // Chat is hidden
|
||||
POPPED_OUT, // Chat is playing in a popout window
|
||||
EMBEDDED, // This window is opened at /embed/chat/readwrite/
|
||||
}
|
||||
|
||||
export const chatStateAtom = atom<ChatState>({
|
||||
key: 'chatState',
|
||||
default: (() => {
|
||||
// XXX Somehow, `window` is undefined here, even though this runs in client
|
||||
const window = globalThis;
|
||||
return window?.location?.pathname === '/embed/chat/readwrite/'
|
||||
? ChatState.EMBEDDED
|
||||
: ChatState.VISIBLE;
|
||||
})(),
|
||||
});
|
||||
|
||||
// We display in an "online/live" state as long as video is actively playing.
|
||||
@@ -315,7 +319,7 @@ export const ClientConfigStore: FC = () => {
|
||||
setChatMessages(currentState => [...currentState, message as ChatEvent]);
|
||||
break;
|
||||
case MessageType.NAME_CHANGE:
|
||||
handleNameChangeEvent(message as ChatEvent, setChatMessages);
|
||||
handleNameChangeEvent(message as NameChangeEvent, setChatMessages, setCurrentUser);
|
||||
break;
|
||||
case MessageType.USER_JOINED:
|
||||
setChatMessages(currentState => [...currentState, message as ChatEvent]);
|
||||
|
||||
Reference in New Issue
Block a user