Skip to content

Commit

Permalink
Merge pull request #1847 from holium/RE-269
Browse files Browse the repository at this point in the history
Add rooms interface to standalone chat
  • Loading branch information
drunkplato authored Jun 30, 2023
2 parents e3233dd + 45790ad commit 4658547
Show file tree
Hide file tree
Showing 25 changed files with 797 additions and 142 deletions.
35 changes: 18 additions & 17 deletions app/src/renderer/apps/Courier/components/ChatLogHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ import { useMemo } from 'react';
import { observer } from 'mobx-react';
import styled from 'styled-components';

import { Button, Flex, Icon, Spinner } from '@holium/design-system/general';
import { Button, Flex, Icon } from '@holium/design-system/general';
import { Menu, MenuItemProps } from '@holium/design-system/navigation';

import { StartRoomButton } from 'renderer/components/StartRoomButton/StartRoomButton';
import { useAppState } from 'renderer/stores/app.store';
import { useShipStore } from 'renderer/stores/ship.store';

Expand Down Expand Up @@ -45,7 +46,7 @@ const ChatLogHeaderPresenter = ({
}: Props) => {
const { loggedInAccount, shellStore } = useAppState();
const { chatStore } = useShipStore();
const { selectedChat, chatLoader, setSubroute, toggleMuted } = chatStore;
const { selectedChat, setSubroute, toggleMuted } = chatStore;
const isSpaceChat = selectedChat?.type === 'space';

const chatLogId = useMemo(() => `chat-log-${path}`, [path]);
Expand Down Expand Up @@ -142,22 +143,22 @@ const ChatLogHeaderPresenter = ({
)}
<ChatLogHeaderContent isStandaloneChat={isStandaloneChat} />
</Flex>
<Flex gap={8}>
{chatLoader.isLoading && (
<Spinner size="16px" width={1.5} color="var(--rlm-text-color)" />
)}
<Flex gap="12px" alignItems="center">
{hasMenu && (
<Menu
id={`chat-${path}-menu`}
orientation="bottom-left"
offset={{ x: 2, y: 2 }}
triggerEl={
<Button.IconButton size={26}>
<Icon name="MoreHorizontal" size={22} opacity={0.5} />
</Button.IconButton>
}
options={contextMenuOptions}
/>
<>
<StartRoomButton isStandaloneChat={isStandaloneChat} />
<Menu
id={`chat-${path}-menu`}
orientation="bottom-left"
offset={{ x: 2, y: 2 }}
triggerEl={
<Button.IconButton size={26}>
<Icon name="MoreHorizontal" size={22} opacity={0.5} />
</Button.IconButton>
}
options={contextMenuOptions}
/>
</>
)}
</Flex>
</ChatLogHeaderContainer>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ const ChatLogHeaderContentPresenter = ({ isStandaloneChat = false }: Props) => {
transition={{
duration: isStandaloneChat ? 0 : 0.15,
}}
width={210}
initial={{ opacity: 0 }}
animate={{ opacity: 0.5, lineHeight: '1' }}
fontSize={2}
Expand All @@ -64,7 +63,6 @@ const ChatLogHeaderContentPresenter = ({ isStandaloneChat = false }: Props) => {
transition={{
duration: 0.15,
}}
width={210}
initial={{ opacity: 0.5 }}
animate={{ opacity: 0.5, lineHeight: '1' }}
fontSize={1}
Expand Down Expand Up @@ -99,7 +97,6 @@ const ChatLogHeaderContentPresenter = ({ isStandaloneChat = false }: Props) => {
{pretitle}
<Text.Custom
truncate
width={255}
layoutId={isStandaloneChat ? `chat-${path}-name` : undefined}
layout="preserve-aspect"
textAlign="left"
Expand Down
69 changes: 54 additions & 15 deletions app/src/renderer/apps/Courier/components/ChatRow/ChatRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,25 @@ import { MouseEvent, useEffect, useMemo, useState } from 'react';
import { observer } from 'mobx-react';

import { convertFragmentsToPreview } from '@holium/design-system/blocks';
import { Flex, Icon, Row, Text } from '@holium/design-system/general';
import {
AvatarRow,
Flex,
Icon,
Row,
Text,
} from '@holium/design-system/general';
import { timelineDate } from '@holium/design-system/util';

import { ChatPathType } from 'os/services/ship/chat/chat.types';
import { useRoomsStore } from 'renderer/apps/Rooms/store/RoomsStoreContext';
import { useContextMenu } from 'renderer/components';
import { useAppState } from 'renderer/stores/app.store';
import { SpaceModelType } from 'renderer/stores/models/spaces.model';
import { useShipStore } from 'renderer/stores/ship.store';

import { ChatAvatar } from '../ChatAvatar';
import { UnreadBadge } from '../UnreadBadge';
import { ChatRowHasRoomSvg } from './ChatRowHasRoomSvg';
import { useChatRowContextMenuOptions } from './useChatRowContextMenuOptions';

type ChatRowProps = {
Expand All @@ -39,7 +47,8 @@ export const ChatRowPresenter = ({
onClick,
}: ChatRowProps) => {
const { loggedInAccount, shellStore } = useAppState();
const { notifStore, chatStore, spacesStore } = useShipStore();
const { notifStore, chatStore, spacesStore, friends } = useShipStore();
const roomsStore = useRoomsStore();
const {
inbox,
getChatHeader,
Expand All @@ -55,6 +64,14 @@ export const ChatRowPresenter = ({

const unreadCount = getUnreadCountByPath(path);

const hasRoom = roomsStore.getRoomByPath(path);

const roomParticipants =
hasRoom?.present.map((patp: string) => {
return friends.getContactAvatarMetadata(patp);
}) ?? [];
const firstFiveParticipants = roomParticipants.slice(0, 5);

const chatRowId = useMemo(() => `chat-row-${path}`, [path]);
const isPinned = isChatPinned(path);
const isMuted = isChatMuted(path);
Expand Down Expand Up @@ -155,8 +172,7 @@ export const ChatRowPresenter = ({
>
<Flex flex={1} gap={12} alignItems="center" minWidth={0}>
<Flex
// layoutId={isStandaloneChat ? undefined : `chat-${path}-avatar`}
// layout={isStandaloneChat ? undefined : 'preserve-aspect'}
position="relative"
transition={{
duration: isStandaloneChat ? 0 : 0.15,
}}
Expand All @@ -171,6 +187,20 @@ export const ChatRowPresenter = ({
metadata={metadata}
canEdit={false}
/>
{hasRoom && (
<Flex
position="absolute"
bottom={-7}
right={-7}
background="var(--rlm-accent-color)"
borderRadius="50%"
padding="2px"
alignItems="center"
justifyContent="center"
>
<ChatRowHasRoomSvg />
</Flex>
)}
</Flex>
<Flex
flex={1}
Expand Down Expand Up @@ -220,17 +250,26 @@ export const ChatRowPresenter = ({
{title}
</Text.Custom>
</Flex>
<Flex gap="6px" alignItems="center">
<Text.Custom
style={{ wordBreak: 'keep-all' }}
fontWeight={400}
fontSize={1}
opacity={0.3}
>
{lastMessageTimestamp}
</Text.Custom>
{unreadCount > 0 && <UnreadBadge count={unreadCount} />}
</Flex>
{hasRoom ? (
<AvatarRow
people={firstFiveParticipants}
size={16}
offset={4}
borderRadiusOverride="5px"
/>
) : (
<Flex gap="6px" alignItems="center">
<Text.Custom
style={{ wordBreak: 'keep-all' }}
fontWeight={400}
fontSize={1}
opacity={0.3}
>
{lastMessageTimestamp}
</Text.Custom>
{unreadCount > 0 && <UnreadBadge count={unreadCount} />}
</Flex>
)}
</Flex>
<Flex
flex={1}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export const ChatRowHasRoomSvg = () => (
<svg
width="14"
height="14"
viewBox="0 0 14 14"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M2.91659 4.08366H4.08325V9.91699H2.91659V4.08366ZM0.583252 5.83366H1.74992V8.16699H0.583252V5.83366ZM5.24992 1.16699H6.41658V11.667H5.24992V1.16699ZM7.58325 2.33366H8.74992V12.8337H7.58325V2.33366ZM9.91658 4.08366H11.0833V9.91699H9.91658V4.08366ZM12.2499 5.83366H13.4166V8.16699H12.2499V5.83366Z"
fill="white"
/>
</svg>
);
14 changes: 13 additions & 1 deletion app/src/renderer/apps/Courier/views/ChatLog/ChatLogBody.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { RefObject } from 'react';
import { observer } from 'mobx-react';

import { Flex, WindowedListRef } from '@holium/design-system/general';
import { Flex, Spinner, WindowedListRef } from '@holium/design-system/general';

import {
ChatFragmentMobxType,
Expand Down Expand Up @@ -83,6 +83,7 @@ const ChatLogBodyPresenter = ({
flexDirection="column"
alignItems="center"
justifyContent="center"
position="relative"
>
<ChatLogBodyList
messages={messages}
Expand All @@ -95,6 +96,17 @@ const ChatLogBodyPresenter = ({
isEmpty={messages.length === 0}
isLoaded={chatLoader.isLoaded}
/>
{chatLoader.isLoading && (
<div
style={{
position: 'absolute',
top: isStandaloneChat ? 8 : 0,
right: isStandaloneChat ? 12 : 0,
}}
>
<Spinner size="16px" width={1.5} color="var(--rlm-accent-color)" />
</div>
)}
</Flex>
<ChatInputContainer isStandaloneChat={isStandaloneChat}>
{selectedChat && (
Expand Down
56 changes: 41 additions & 15 deletions app/src/renderer/apps/Rooms/Room/Voice.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,44 @@
import { useEffect, useState } from 'react';
import { useEffect, useMemo, useState } from 'react';
import { observer } from 'mobx-react';

import { useTrayApps } from 'renderer/apps/store';
import { useAppState } from 'renderer/stores/app.store';
import { useShipStore } from 'renderer/stores/ship.store';

import { SpeakerGrid } from '../components/SpeakerGrid';
import { SpeakerGridStandaloneChat } from '../components/SpeakerGridStandaloneChat';
import { roomTrayConfig } from '../config';
import { useRoomsStore } from '../store/RoomsStoreContext';

const VoiceViewPresenter = () => {
const roomsStore = useRoomsStore();
type Props = {
isStandaloneChat?: boolean;
};

const VoiceViewPresenter = ({ isStandaloneChat }: Props) => {
const roomsStore = useRoomsStore();
const { setTrayAppHeight } = useTrayApps();
const { loggedInAccount } = useAppState();
const { friends } = useShipStore();
const [activeSpeaker, setActiveSpeaker] = useState<string | null>(null);

const { setTrayAppHeight } = useTrayApps();
const peers = roomsStore.currentRoomPresent ?? [];
const ourId = useMemo(() => loggedInAccount?.serverId, [loggedInAccount]);
const peers = useMemo(
() => roomsStore.currentRoomPresent ?? [],
[roomsStore.currentRoomPresent]
);

// Sort peers in the following priority:
// #1: Active speaker
// #2: Ourself
const peersSorted = useMemo(() => {
return peers.slice().sort((a, b) => {
if (a === activeSpeaker) return -1;
if (b === activeSpeaker) return 1;
if (a === ourId) return -1;
if (b === ourId) return 1;
return 0;
});
}, [peers, activeSpeaker, ourId]);

useEffect(() => {
const regularHeight = roomTrayConfig.dimensions.height;
Expand Down Expand Up @@ -93,20 +114,25 @@ const VoiceViewPresenter = () => {
return friends.getContactAvatarMetadata(peerId);
};

const ourId = loggedInAccount?.serverId;
if (isStandaloneChat) {
return (
<SpeakerGridStandaloneChat
ourId={ourId ?? ''}
activeSpeaker={activeSpeaker ?? ourId ?? peersSorted[0]}
peers={peersSorted}
getContactMetadata={getContactMetadata}
getPeer={getPeer}
room={roomsStore.currentRoom}
kickPeer={roomsStore.kickPeer}
retryPeer={roomsStore.retryPeer}
/>
);
}

return (
<SpeakerGrid
activeSpeaker={activeSpeaker || ourId || null}
peers={peers.slice().sort((a, b) => {
if (a === ourId) {
return -1;
}
if (b === ourId) {
return 1;
}
return 0;
})}
peers={peersSorted}
getContactMetadata={getContactMetadata}
getPeer={getPeer}
ourId={ourId ?? ''}
Expand Down
9 changes: 1 addition & 8 deletions app/src/renderer/apps/Rooms/Room/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { useEffect, useState } from 'react';
import { observer } from 'mobx-react';
import { darken } from 'polished';

import { Button, CommButton, Flex, Icon, Text } from '@holium/design-system';

Expand All @@ -17,16 +16,13 @@ import { VoiceView } from './Voice';
type RoomViews = 'voice' | 'chat' | 'invite' | 'info';

const RoomPresenter = () => {
const { loggedInAccount, theme, shellStore } = useAppState();
const { loggedInAccount, shellStore } = useAppState();
const roomsStore = useRoomsStore();
const { roomsApp } = useTrayApps();

const { dockColor, mode } = theme;
const [roomView, setRoomView] = useState<RoomViews>('voice');
const isMuted = roomsStore.ourPeer.isMuted;
const hasVideo = roomsStore.ourPeer.isVideoOn;
const commButtonBg =
mode === 'light' ? darken(0.04, dockColor) : darken(0.01, dockColor);

useEffect(() => {
trackEvent('OPENED', 'ROOMS_VOICE');
Expand Down Expand Up @@ -194,7 +190,6 @@ const RoomPresenter = () => {
<Flex gap={12} flex={1} justifyContent="center" alignItems="center">
<CommButton
icon={isMuted ? 'MicOff' : 'MicOn'}
customBg={commButtonBg}
onClick={(evt) => {
evt.stopPropagation();
if (isMuted) {
Expand All @@ -206,12 +201,10 @@ const RoomPresenter = () => {
/>
<CommButton
icon={shellStore.multiplayerEnabled ? 'MouseOn' : 'MouseOff'}
customBg={commButtonBg}
onClick={shellStore.toggleMultiplayer}
/>
<CommButton
icon={hasVideo ? 'VideoOn' : 'VideoOff'}
customBg={commButtonBg}
onClick={() => {
roomsStore.toggleVideo(!hasVideo);
}}
Expand Down
Loading

0 comments on commit 4658547

Please sign in to comment.