Skip to content

Commit

Permalink
Merge branch 'main' into feature/zapp-communication-proposal
Browse files Browse the repository at this point in the history
  • Loading branch information
RickyRoller committed Mar 7, 2025
2 parents 8c59c5d + b3d7d14 commit e44e862
Show file tree
Hide file tree
Showing 24 changed files with 95 additions and 134 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ZERO",
"version": "1.294.0",
"version": "1.296.0",
"private": true,
"main": "./public/electron.js",
"engines": {
Expand Down
14 changes: 14 additions & 0 deletions src/apps/feed/components/feed-chat/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { validateFeedChat } from '../../../../store/chat';
import { send } from '../../../../store/messages';
import { config } from '../../../../config';
import { Spinner } from '@zero-tech/zui/components/LoadingIndicator';
import { MembersSidekick } from '../../../../components/sidekick/variants/members-sidekick';

describe('FeedChatContainer', () => {
const subject = (props: any = {}) => {
Expand Down Expand Up @@ -135,6 +136,19 @@ describe('FeedChatContainer', () => {
expect(validateFeedChat).toHaveBeenLastCalledWith(`new-zid:${config.matrixHomeServerName}`);
});

it('should render members sidekick when is secondary sidekick open', () => {
const wrapper = subject({
zid: 'test-zid',
channel: { id: 'channel-id' },
activeConversationId: 'conversation-id',
isJoiningConversation: true,
isConversationsLoaded: true,
isSecondarySidekickOpen: true,
});

expect(wrapper).toHaveElement(MembersSidekick);
});

describe('mapState', () => {
const getState = (state: any) =>
({
Expand Down
7 changes: 3 additions & 4 deletions src/apps/feed/components/feed-chat/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { RootState } from '../../../../store/reducer';
import { connectContainer } from '../../../../store/redux-container';
import { ChatViewContainer } from '../../../../components/chat-view-container/chat-view-container';
import { validateFeedChat } from '../../../../store/chat';
import { Channel, onRemoveReply } from '../../../../store/channels';
import { Channel, denormalize, onRemoveReply } from '../../../../store/channels';
import { MessageInput } from '../../../../components/message-input/container';
import { send as sendMessage } from '../../../../store/messages';
import { SendPayload as PayloadSendMessage } from '../../../../store/messages/saga';
Expand All @@ -18,7 +18,6 @@ import { toggleSecondarySidekick } from '../../../../store/group-management';
import { MembersSidekick } from '../../../../components/sidekick/variants/members-sidekick';
import { Spinner } from '@zero-tech/zui/components/LoadingIndicator';
import { ConversationActionsContainer } from '../../../../components/messenger/conversation-actions/container';
import { denormalizedChannelSelector } from '../../../../store/channels/selectors';

import classNames from 'classnames';
import styles from './styles.module.scss';
Expand Down Expand Up @@ -55,7 +54,7 @@ export class Container extends React.Component<Properties> {
groupManagement,
} = state;

const channel = denormalizedChannelSelector(state, activeConversationId);
const channel = denormalize(activeConversationId, state);
const rawChannel = rawChannelSelector(activeConversationId)(state);

return {
Expand Down Expand Up @@ -210,7 +209,7 @@ export class Container extends React.Component<Properties> {
{this.renderHeader()}{' '}
{this.renderBody(this.props.isJoiningConversation || !this.props.isConversationsLoaded)}
</Panel>
<MembersSidekick className={styles.MembersSidekick} />
{this.props.isSecondarySidekickOpen && <MembersSidekick className={styles.MembersSidekick} />}
</>
)}
</>
Expand Down
41 changes: 24 additions & 17 deletions src/apps/feed/components/sidekick/lib/selectors.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,29 @@
import { createSelector } from '@reduxjs/toolkit';
import { RootState } from '../../../../../store/reducer';
import { denormalizeConversations } from '../../../../../store/channels-list';
import { UnreadCount } from './useSidekick';
import { DefaultRoomLabels } from '../../../../../store/channels';
import { denormalizedConversationsSelector } from '../../../../../store/channels-list/selectors';

export const selectSocialChannelsUnreadCounts = createSelector([denormalizedConversationsSelector], (conversations) => {
return conversations
.filter((c) => c.isSocialChannel && c.zid)
.reduce((acc, channel) => {
acc[channel.zid!] = { total: channel.unreadCount?.total || 0, highlight: channel.unreadCount?.highlight || 0 };
return acc;
}, {} as { [zid: string]: UnreadCount });
});
export const selectSocialChannelsUnreadCounts = createSelector(
[(state: RootState) => denormalizeConversations(state)],
(conversations) => {
return conversations
.filter((c) => c.isSocialChannel && c.zid)
.reduce((acc, channel) => {
acc[channel.zid!] = { total: channel.unreadCount?.total || 0, highlight: channel.unreadCount?.highlight || 0 };
return acc;
}, {} as { [zid: string]: UnreadCount });
}
);

export const selectMutedChannels = createSelector([denormalizedConversationsSelector], (conversations) => {
return conversations
.filter((c) => c.isSocialChannel && c.zid)
.reduce((acc, channel) => {
acc[channel.zid!] = channel.labels?.includes(DefaultRoomLabels.MUTE);
return acc;
}, {} as { [zid: string]: boolean });
});
export const selectMutedChannels = createSelector(
[(state: RootState) => denormalizeConversations(state)],
(conversations) => {
return conversations
.filter((c) => c.isSocialChannel && c.zid)
.reduce((acc, channel) => {
acc[channel.zid!] = channel.labels?.includes(DefaultRoomLabels.MUTE);
return acc;
}, {} as { [zid: string]: boolean });
}
);
45 changes: 7 additions & 38 deletions src/apps/messenger/Main.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { shallow } from 'enzyme';

import { Container as Main, Properties } from './Main';
import { MessengerChat } from '../../components/messenger/chat';
import { MessengerFeed } from '../../components/messenger/feed';
import { JoiningConversationDialog } from '../../components/joining-conversation-dialog';
import { MembersSidekick } from '../../components/sidekick/variants/members-sidekick';

jest.mock('../../lib/web3/thirdweb/client', () => ({
getThirdWebClient: jest.fn(),
Expand All @@ -20,9 +20,9 @@ describe(Main, () => {
isAuthenticated: false,
},
isValidConversation: false,
isSocialChannel: false,
isJoiningConversation: false,
isConversationsLoaded: true,
isSecondarySidekickOpen: false,
...props,
};

Expand All @@ -49,7 +49,7 @@ describe(Main, () => {
expect(wrapper).not.toHaveElement(JoiningConversationDialog);
});

it('renders direct message chat component when not a social channel, conversations loaded and is valid', () => {
it('renders direct message chat component when conversations loaded and is valid', () => {
const wrapper = subject({ context: { isAuthenticated: true }, isValidConversation: true });

expect(wrapper).toHaveElement(MessengerChat);
Expand All @@ -58,51 +58,20 @@ describe(Main, () => {
it('should not render messenger chat container when conversations have not loaded', () => {
const wrapper = subject({
context: { isAuthenticated: true },
isSocialChannel: true,
isValidConversation: true,
isConversationsLoaded: false,
});

expect(wrapper).not.toHaveElement(MessengerChat);
});

it('should not render messenger chat container when is not valid conversation', () => {
it('should render members sidekick when is secondary sidekick open', () => {
const wrapper = subject({
context: { isAuthenticated: true },
isSocialChannel: false,
isValidConversation: false,
isConversationsLoaded: false,
});

expect(wrapper).not.toHaveElement(MessengerFeed);
});

it('renders messenger feed container when is social channel, conversations loaded and is valid conversation', () => {
const wrapper = subject({ context: { isAuthenticated: true }, isSocialChannel: true, isValidConversation: true });

expect(wrapper).toHaveElement(MessengerFeed);
});

it('should not render messenger feed container when is not social channel ', () => {
const wrapper = subject({ context: { isAuthenticated: true }, isSocialChannel: false, isValidConversation: true });

expect(wrapper).not.toHaveElement(MessengerFeed);
});

it('should not render messenger feed container when conversations have not loaded', () => {
const wrapper = subject({
context: { isAuthenticated: true },
isSocialChannel: true,
isValidConversation: true,
isConversationsLoaded: false,
isSecondarySidekickOpen: true,
isConversationsLoaded: true,
});

expect(wrapper).not.toHaveElement(MessengerFeed);
});

it('should not render messenger feed container when is not valid conversation', () => {
const wrapper = subject({ context: { isAuthenticated: true }, isSocialChannel: true, isValidConversation: false });

expect(wrapper).not.toHaveElement(MessengerFeed);
expect(wrapper).toHaveElement(MembersSidekick);
});
});
15 changes: 5 additions & 10 deletions src/apps/messenger/Main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,11 @@ import { connectContainer } from '../../store/redux-container';

import { withContext as withAuthenticationContext } from '../../components/authentication/context';
import { MessengerChat } from '../../components/messenger/chat';
import { MessengerFeed } from '../../components/messenger/feed';
import { DevPanelContainer } from '../../components/dev-panel/container';
import { FeatureFlag } from '../../components/feature-flag';
import { JoiningConversationDialog } from '../../components/joining-conversation-dialog';
import { ConversationsSidekick } from '../../components/sidekick/variants/conversations-sidekick';
import { MembersSidekick } from '../../components/sidekick/variants/members-sidekick';
import { denormalizedChannelSelector } from '../../store/channels/selectors';

import styles from './Main.module.scss';

Expand All @@ -19,24 +17,23 @@ export interface Properties {
isAuthenticated: boolean;
};
isValidConversation: boolean;
isSocialChannel: boolean;
isJoiningConversation: boolean;
isConversationsLoaded: boolean;
isSecondarySidekickOpen: boolean;
}

export class Container extends React.Component<Properties> {
static mapState(state: RootState): Partial<Properties> {
const {
chat: { activeConversationId, isJoiningConversation, isConversationsLoaded },
groupManagement: { isSecondarySidekickOpen },
} = state;

const currentChannel = denormalizedChannelSelector(state, activeConversationId) || null;

return {
isValidConversation: !!activeConversationId,
isSocialChannel: currentChannel?.isSocialChannel,
isJoiningConversation,
isConversationsLoaded,
isSecondarySidekickOpen,
};
}

Expand All @@ -53,11 +50,9 @@ export class Container extends React.Component<Properties> {
<div className={styles.Split}>
{this.props.isJoiningConversation && !this.props.isValidConversation && <JoiningConversationDialog />}

{this.props.isConversationsLoaded &&
this.props.isValidConversation &&
(this.props.isSocialChannel ? <MessengerFeed /> : <MessengerChat />)}
{this.props.isConversationsLoaded && this.props.isValidConversation && <MessengerChat />}
</div>
{this.props.isConversationsLoaded && <MembersSidekick />}
{this.props.isConversationsLoaded && this.props.isSecondarySidekickOpen && <MembersSidekick />}

<FeatureFlag featureFlag='enableDevPanel'>
<DevPanelContainer />
Expand Down
6 changes: 3 additions & 3 deletions src/components/app-bar/container.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { useRouteMatch } from 'react-router-dom';
import { AppBar as AppBarComponent } from './';
import { denormalizeConversations } from '../../store/channels-list';
import { useSelector } from 'react-redux';
import { RootState } from '../../store';
import { DefaultRoomLabels } from '../../store/channels';
import { denormalizedConversationsSelector } from '../../store/channels-list/selectors';
import { activeZAppFeatureSelector } from '../../store/active-zapp/selectors';

export const AppBar = () => {
Expand All @@ -23,7 +23,7 @@ const useAppBar = () => {
const match = useRouteMatch('/:app');

const hasUnreadNotifications = useSelector((state: RootState) => {
const conversations = denormalizedConversationsSelector(state);
const conversations = denormalizeConversations(state);
return conversations.some(
(channel) =>
channel.unreadCount?.total > 0 &&
Expand All @@ -33,7 +33,7 @@ const useAppBar = () => {
});

const hasUnreadHighlights = useSelector((state: RootState) => {
const conversations = denormalizedConversationsSelector(state);
const conversations = denormalizeConversations(state);
return conversations.some(
(channel) =>
channel.unreadCount?.highlight > 0 &&
Expand Down
5 changes: 2 additions & 3 deletions src/components/chat-view-container/chat-view-container.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
AdminMessageType,
sendEmojiReaction,
} from '../../store/messages';
import { Channel, ConversationStatus, onReply } from '../../store/channels';
import { Channel, ConversationStatus, denormalize, onReply } from '../../store/channels';
import { ChatView } from './chat-view';
import { AuthenticationState } from '../../store/authentication/types';
import { EditPayload, Payload as PayloadFetchMessages } from '../../store/messages/saga';
Expand All @@ -25,7 +25,6 @@ import { openMessageInfo } from '../../store/message-info';
import { toggleSecondarySidekick } from '../../store/group-management';
import { linkMessages, mapMessagesById, mapMessagesByRootId } from './utils';
import { openReportUserModal } from '../../store/report-user';
import { denormalizedChannelSelector } from '../../store/channels/selectors';

export interface Properties extends PublicProperties {
channel: Channel;
Expand Down Expand Up @@ -64,7 +63,7 @@ export class Container extends React.Component<Properties> {
}

static mapState(state: RootState, props: PublicProperties): Partial<Properties> {
const channel = denormalizedChannelSelector(state, props.channelId) || null;
const channel = denormalize(props.channelId, state) || null;
const {
authentication: { user },
chat: { activeConversationId },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { RootState } from '../../../store/reducer';
import { ConfirmationDefinition, MemberManagementDialog } from '.';
import { denormalize as denormalizeUser } from '../../../store/users';
import { displayName } from '../../../lib/user';
import { denormalize as denormalizeChannel } from '../../../store/channels';
import {
cancelMemberManagement,
removeMember,
Expand All @@ -13,7 +14,6 @@ import {
setMemberAsModerator,
removeMemberAsModerator,
} from '../../../store/group-management';
import { denormalizedChannelSelector } from '../../../store/channels/selectors';

export interface PublicProperties {}

Expand All @@ -38,7 +38,7 @@ export class Container extends React.Component<Properties> {
groupManagement: { memberManagement },
} = state;
const user = denormalizeUser(memberManagement.userId, state);
const channel = denormalizedChannelSelector(state, memberManagement.roomId);
const channel = denormalizeChannel(memberManagement.roomId, state);

return {
type: memberManagement.type,
Expand Down
9 changes: 5 additions & 4 deletions src/components/messenger/chat/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from 'react';
import classNames from 'classnames';
import { RootState } from '../../../store/reducer';
import { connectContainer } from '../../../store/redux-container';
import { Channel, onAddLabel, onRemoveLabel, onRemoveReply } from '../../../store/channels';
import { Channel, denormalize, onAddLabel, onRemoveLabel, onRemoveReply } from '../../../store/channels';
import { ChatViewContainer } from '../../chat-view-container/chat-view-container';
import { send as sendMessage } from '../../../store/messages';
import { SendPayload as PayloadSendMessage } from '../../../store/messages/saga';
Expand All @@ -21,9 +21,9 @@ import { Media } from '../../message-input/utils';
import { ConversationHeaderContainer as ConversationHeader } from '../conversation-header/container';

import './styles.scss';
import { rawChannelSelector } from '../../../store/channels/saga';
import { getOtherMembersTypingDisplayJSX } from '../lib/utils';
import { Panel, PanelBody } from '../../layout/panel';
import { denormalizedChannelSelector } from '../../../store/channels/selectors';

export interface PublicProperties {}

Expand Down Expand Up @@ -59,15 +59,16 @@ export class Container extends React.Component<Properties> {
groupManagement,
} = state;

const directMessage = denormalizedChannelSelector(state, activeConversationId);
const directMessage = denormalize(activeConversationId, state);
const channel = rawChannelSelector(activeConversationId)(state);

return {
activeConversationId,
directMessage,
isJoiningConversation,
isSecondarySidekickOpen: groupManagement.isSecondarySidekickOpen,
leaveGroupDialogStatus: groupManagement.leaveGroupDialogStatus,
otherMembersTypingInRoom: directMessage?.otherMembersTyping || [],
otherMembersTypingInRoom: channel?.otherMembersTyping || [],
};
}

Expand Down
Loading

0 comments on commit e44e862

Please sign in to comment.