{
);
}
}
-
-const StyledLeftPaneContent = styled.div`
- display: flex;
- flex-direction: column;
- flex: 1;
- overflow: hidden;
-`;
diff --git a/ts/components/leftpane/overlay/OverlayClosedGroup.tsx b/ts/components/leftpane/overlay/OverlayClosedGroup.tsx
index 8df5d3cd2..6c606f603 100644
--- a/ts/components/leftpane/overlay/OverlayClosedGroup.tsx
+++ b/ts/components/leftpane/overlay/OverlayClosedGroup.tsx
@@ -18,6 +18,7 @@ import styled from 'styled-components';
import { SessionSearchInput } from '../../SessionSearchInput';
import { getSearchResults, isSearching } from '../../../state/selectors/search';
import { useSet } from '../../../hooks/useSet';
+import { VALIDATION } from '../../../session/constants';
const StyledMemberListNoContacts = styled.div`
font-family: var(--font-font-mono);
@@ -90,6 +91,8 @@ export const OverlayClosedGroup = () => {
}
const contactsToRender = isSearch ? sharedWithResults : privateContactsPubkeys;
+ const disableCreateButton = !selectedMemberIds.length && !groupName.length;
+
return (
@@ -99,7 +102,7 @@ export const OverlayClosedGroup = () => {
placeholder={placeholder}
value={groupName}
isGroup={true}
- maxLength={100}
+ maxLength={VALIDATION.MAX_GROUP_NAME_LENGTH}
onChange={setGroupName}
onPressEnter={onEnterPressed}
dataTestId="new-closed-group-name"
@@ -129,13 +132,13 @@ export const OverlayClosedGroup = () => {
)}
-
+
void
+) {
// guess if this is an open
if (serverUrl.match(openGroupV2CompleteURLRegex)) {
- const groupCreated = await joinOpenGroupV2WithUIEvents(serverUrl, true, false);
+ const groupCreated = await joinOpenGroupV2WithUIEvents(serverUrl, true, false, uiCallback);
return groupCreated;
} else {
ToastUtils.pushToastError('invalidOpenGroupUrl', window.i18n('invalidOpenGroupUrl'));
@@ -31,20 +42,18 @@ export const OverlayCommunity = () => {
const [loading, setLoading] = useState(false);
const [groupUrl, setGroupUrl] = useState('');
+ const overlayModeIsCommunity = useSelector(getOverlayMode) === 'open-group';
+
function closeOverlay() {
dispatch(resetOverlayMode());
}
- async function onEnterPressed() {
+ async function onTryJoinRoom(completeUrl?: string) {
try {
if (loading) {
return;
}
- setLoading(true);
- const groupCreated = await joinOpenGroup(groupUrl);
- if (groupCreated) {
- closeOverlay();
- }
+ await joinOpenGroup(completeUrl || groupUrl, joinSogsUICallback);
} catch (e) {
window.log.warn(e);
} finally {
@@ -52,7 +61,22 @@ export const OverlayCommunity = () => {
}
}
- // FIXME autofocus inputref on mount
+ function joinSogsUICallback(args: JoinSogsRoomUICallbackArgs) {
+ setLoading(args.loadingState === 'started');
+ if (args.conversationKey) {
+ dispatch(
+ markConversationInitialLoadingInProgress({
+ conversationKey: args.conversationKey,
+ isInitialFetchingInProgress: true,
+ })
+ );
+ }
+ if (args.loadingState === 'finished' && overlayModeIsCommunity && args.conversationKey) {
+ closeOverlay();
+ void openConversationWithMessages({ conversationKey: args.conversationKey, messageId: null }); // open to last unread for a session run sogs
+ }
+ }
+
useKey('Escape', closeOverlay);
const title = window.i18n('joinOpenGroup');
@@ -72,20 +96,20 @@ export const OverlayCommunity = () => {
isGroup={true}
maxLength={300}
onChange={setGroupUrl}
- onPressEnter={onEnterPressed}
+ onPressEnter={onTryJoinRoom}
/>
+
+
-
- {groupUrl && (
-
- )}
+
);
};
diff --git a/ts/components/leftpane/overlay/OverlayMessage.tsx b/ts/components/leftpane/overlay/OverlayMessage.tsx
index 6d494b5a7..93a7ede6d 100644
--- a/ts/components/leftpane/overlay/OverlayMessage.tsx
+++ b/ts/components/leftpane/overlay/OverlayMessage.tsx
@@ -45,13 +45,15 @@ export const OverlayMessage = () => {
const subtitle = window.i18n('enterSessionIDOrONSName');
const placeholder = window.i18n('enterSessionIDOfRecipient');
+ const disableNextButton = !pubkeyOrOns || loading;
+
async function openConvoOnceResolved(resolvedSessionID: string) {
const convo = await getConversationController().getOrCreateAndWait(
resolvedSessionID,
ConversationTypeEnum.PRIVATE
);
- // we now want to show a conversation we just started on the leftpane, even if we did not sent a message to it yet
+ // we now want to show a conversation we just started on the leftpane, even if we did not send a message to it yet
if (!convo.isActive() || !convo.isApproved()) {
convo.set({ active_at: Date.now(), isApproved: true });
await convo.commit();
@@ -105,6 +107,7 @@ export const OverlayMessage = () => {
placeholder={placeholder}
onChange={setPubkeyOrOns}
dataTestId="new-session-conversation"
+ onPressEnter={handleMessageButtonClick}
/>
@@ -118,7 +121,8 @@ export const OverlayMessage = () => {
container={true}
justifyContent="space-between"
alignItems="center"
- padding="0 15px 0 0 " // YourSessionIDSelectable already has a left margin of 15px
+ width="100%"
+ padding="0 var(--margins-md)" // YourSessionIDSelectable already has a left margin of 15px
>
@@ -127,7 +131,7 @@ export const OverlayMessage = () => {
buttonColor={SessionButtonColor.Green}
buttonType={SessionButtonType.BrandOutline}
text={buttonText}
- disabled={false}
+ disabled={disableNextButton}
onClick={handleMessageButtonClick}
dataTestId="next-new-conversation-button"
/>
diff --git a/ts/components/leftpane/overlay/SessionJoinableDefaultRooms.tsx b/ts/components/leftpane/overlay/SessionJoinableDefaultRooms.tsx
index 9b757d141..4c782bad1 100644
--- a/ts/components/leftpane/overlay/SessionJoinableDefaultRooms.tsx
+++ b/ts/components/leftpane/overlay/SessionJoinableDefaultRooms.tsx
@@ -1,17 +1,14 @@
-import React, { useCallback, useEffect } from 'react';
+import React, { useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import styled from 'styled-components';
-import {
- joinOpenGroupV2WithUIEvents,
- parseOpenGroupV2,
-} from '../../../session/apis/open_group_api/opengroupV2/JoinOpenGroupV2';
+import { parseOpenGroupV2 } from '../../../session/apis/open_group_api/opengroupV2/JoinOpenGroupV2';
import { sogsV3FetchPreviewBase64 } from '../../../session/apis/open_group_api/sogsv3/sogsV3FetchFile';
import { updateDefaultBase64RoomData } from '../../../state/ducks/defaultRooms';
import { StateType } from '../../../state/reducer';
import { Avatar, AvatarSize } from '../../avatar/Avatar';
import { Flex } from '../../basic/Flex';
-import { PillContainerHoverable, PillTooltipWrapper } from '../../basic/PillContainer';
+import { PillContainerHoverable, StyledPillContainerHoverable } from '../../basic/PillContainer';
import { SessionSpinner } from '../../basic/SessionSpinner';
import { H3 } from '../../basic/Text';
// tslint:disable: no-void-expression
@@ -21,7 +18,7 @@ export type JoinableRoomProps = {
name: string;
roomId: string;
imageId?: string;
- onClick: (completeUrl: string) => void;
+ onClick?: (completeUrl: string) => void;
base64Data?: string;
};
@@ -77,7 +74,7 @@ const SessionJoinableRoomAvatar = (props: JoinableRoomProps) => {
base64Data={props.base64Data}
{...props}
pubkey=""
- onAvatarClick={() => props.onClick(props.completeUrl)}
+ onAvatarClick={() => props.onClick?.(props.completeUrl)}
/>
);
};
@@ -94,64 +91,68 @@ const SessionJoinableRoomName = (props: JoinableRoomProps) => {
};
const SessionJoinableRoomRow = (props: JoinableRoomProps) => {
+ const { onClick, completeUrl } = props;
+ const onClickWithUrl = onClick
+ ? () => {
+ onClick?.(completeUrl);
+ }
+ : undefined;
+
return (
-
- {
- props.onClick(props.completeUrl);
- }}
- margin="5px"
- padding="5px"
- >
+
+
-
+
);
};
-export const SessionJoinableRooms = (props: { onRoomClicked: () => void }) => {
+const JoinableRooms = (props: {
+ alreadyJoining: boolean;
+ onJoinClick?: (completeUrl: string) => void;
+}) => {
const joinableRooms = useSelector((state: StateType) => state.defaultRooms);
- const onRoomClicked = useCallback(
- (loading: boolean) => {
- if (loading) {
- props.onRoomClicked();
- }
- },
- [props.onRoomClicked]
+ return (
+ <>
+ {joinableRooms.rooms.map(r => {
+ return (
+
+ );
+ })}
+ >
);
+};
+
+export const SessionJoinableRooms = (props: {
+ onJoinClick?: (completeUrl: string) => void;
+ alreadyJoining: boolean;
+}) => {
+ const joinableRooms = useSelector((state: StateType) => state.defaultRooms);
if (!joinableRooms.inProgress && !joinableRooms.rooms?.length) {
window?.log?.info('no default joinable rooms yet and not in progress');
return null;
}
- const componentToRender = joinableRooms.inProgress ? (
-
- ) : (
- joinableRooms.rooms.map(r => {
- return (
- {
- void joinOpenGroupV2WithUIEvents(completeUrl, true, false, onRoomClicked);
- }}
- />
- );
- })
- );
-
return (
- {componentToRender}
+ {joinableRooms.inProgress ? (
+
+ ) : (
+
+ )}
);
diff --git a/ts/components/leftpane/overlay/choose-action/ContactRow.tsx b/ts/components/leftpane/overlay/choose-action/ContactRow.tsx
index a1883bc7e..06ae33b37 100644
--- a/ts/components/leftpane/overlay/choose-action/ContactRow.tsx
+++ b/ts/components/leftpane/overlay/choose-action/ContactRow.tsx
@@ -41,7 +41,7 @@ const StyledContactRowName = styled.div`
font-size: var(--font-size-lg);
`;
-const StyledRowContainer = styled.div`
+const StyledRowContainer = styled.button`
display: flex;
align-items: center;
padding: 0 var(--margins-lg);
@@ -64,7 +64,7 @@ const StyledBreak = styled.div`
padding: 0 var(--margins-lg);
color: var(--color-text-subtle);
font-size: var(--font-size-md);
- height: 25px; // should also be changed in rowHeight
+ height: 30px; // should also be changed in rowHeight
border-bottom: 1px var(--color-session-border) solid;
`;
diff --git a/ts/components/leftpane/overlay/choose-action/ContactsListWithBreaks.tsx b/ts/components/leftpane/overlay/choose-action/ContactsListWithBreaks.tsx
index ea3aa6eb1..1fd71411c 100644
--- a/ts/components/leftpane/overlay/choose-action/ContactsListWithBreaks.tsx
+++ b/ts/components/leftpane/overlay/choose-action/ContactsListWithBreaks.tsx
@@ -8,6 +8,7 @@ import {
getDirectContactsByName,
getDirectContactsCount,
} from '../../../../state/selectors/conversations';
+import { leftPaneListWidth } from '../../LeftPane';
import { StyledLeftPaneList } from '../../LeftPaneList';
import { ContactRow, ContactRowBreak } from './ContactRow';
import { StyledChooseActionTitle } from './OverlayChooseAction';
@@ -93,11 +94,11 @@ const ContactListItemSection = () => {
rowCount={length}
rowHeight={
(params: Index) =>
- isString(directContactsByNameWithBreaks[params.index]) ? 25 : 64 // should also be changed in `ContactRowBreak`
+ isString(directContactsByNameWithBreaks[params.index]) ? 30 : 64 // should also be changed in `ContactRowBreak`
}
directContactsByNameWithBreaks={directContactsByNameWithBreaks}
rowRenderer={renderRow}
- width={300} // the same as session-left-pane-width
+ width={leftPaneListWidth}
autoHeight={false}
/>
);
@@ -113,7 +114,9 @@ const ContactsTitle = () => {
return null;
}
- return {window.i18n('contactsHeader')};
+ return (
+ {window.i18n('contactsHeader')}
+ );
};
export const ContactsListWithBreaks = () => {
diff --git a/ts/components/leftpane/overlay/choose-action/OverlayChooseAction.tsx b/ts/components/leftpane/overlay/choose-action/OverlayChooseAction.tsx
index d662f5a78..4b1571e67 100644
--- a/ts/components/leftpane/overlay/choose-action/OverlayChooseAction.tsx
+++ b/ts/components/leftpane/overlay/choose-action/OverlayChooseAction.tsx
@@ -66,15 +66,27 @@ export const OverlayChooseAction = () => {
return (
-
+
{window.i18n('newMessage')}
-
+
{window.i18n('createGroup')}
-
+
{window.i18n('joinOpenGroup')}
diff --git a/ts/components/settings/BlockedList.tsx b/ts/components/settings/BlockedList.tsx
index 9021f1554..e32c80ace 100644
--- a/ts/components/settings/BlockedList.tsx
+++ b/ts/components/settings/BlockedList.tsx
@@ -2,7 +2,7 @@ import React, { useState } from 'react';
// tslint:disable-next-line: no-submodule-imports
import useUpdate from 'react-use/lib/useUpdate';
-import styled, { CSSProperties } from 'styled-components';
+import styled from 'styled-components';
import { useSet } from '../../hooks/useSet';
import { ToastUtils } from '../../session/utils';
import { BlockedNumberController } from '../../util';
@@ -18,14 +18,14 @@ const BlockedEntriesContainer = styled.div`
overflow: auto;
min-height: 40px;
max-height: 100%;
- background: var(--blocked-contact-list-bg);
+ background: var(--color-input-background); // TODO theming update
`;
const BlockedEntriesRoundedContainer = styled.div`
overflow: hidden;
border-radius: 16px;
padding: var(--margins-lg);
- background: var(--blocked-contact-list-bg);
+ background: var(--color-input-background); // TODO theming update
`;
const BlockedContactsSection = styled.div`
@@ -119,9 +119,7 @@ export const BlockedContactsList = () => {
}
return (
-
+
diff --git a/ts/components/settings/SessionNotificationGroupSettings.tsx b/ts/components/settings/SessionNotificationGroupSettings.tsx
index 86d2a854f..e5e96256e 100644
--- a/ts/components/settings/SessionNotificationGroupSettings.tsx
+++ b/ts/components/settings/SessionNotificationGroupSettings.tsx
@@ -57,7 +57,10 @@ export const SessionNotificationGroupSettings = (props: { hasPassword: boolean |
Notifications.addNotification(
{
conversationId: `preview-notification-${Date.now()}`,
- message: items.find(m => m.value === initialItem)?.label || 'Message body',
+ message:
+ items.find(m => m.value === initialItem)?.label ||
+ window?.i18n?.('messageBody') ||
+ 'Message body',
title: window.i18n('notificationPreview'),
iconUrl: null,
isExpiringMessage: false,
diff --git a/ts/components/settings/SessionSettings.tsx b/ts/components/settings/SessionSettings.tsx
index 7cc054aba..d991228be 100644
--- a/ts/components/settings/SessionSettings.tsx
+++ b/ts/components/settings/SessionSettings.tsx
@@ -163,7 +163,7 @@ const SettingInCategory = (props: {
case SessionSettingCategory.Permissions:
return ;
- // those three down there have no options, they are just a button
+ // these three down there have no options, they are just a button
case SessionSettingCategory.ClearData:
case SessionSettingCategory.MessageRequests:
case SessionSettingCategory.RecoveryPhrase:
diff --git a/ts/components/settings/SessionSettingsHeader.tsx b/ts/components/settings/SessionSettingsHeader.tsx
index f303a8b1b..42f8f8c01 100644
--- a/ts/components/settings/SessionSettingsHeader.tsx
+++ b/ts/components/settings/SessionSettingsHeader.tsx
@@ -1,6 +1,5 @@
import React from 'react';
import styled from 'styled-components';
-import { LocalizerKeys } from '../../types/LocalizerKeys';
import { missingCaseError } from '../../util';
import { SessionSettingCategory, SettingsViewProps } from './SessionSettings';
@@ -26,32 +25,30 @@ const StyledHeaderTittle = styled.div`
export const SettingsHeader = (props: Props) => {
const { category } = props;
- let categoryLocalized: LocalizerKeys | null = null;
+ let categoryTitle: string | null = null;
switch (category) {
case SessionSettingCategory.Appearance:
- categoryLocalized = 'appearanceSettingsTitle';
+ categoryTitle = window.i18n('appearanceSettingsTitle');
break;
case SessionSettingCategory.Conversations:
- categoryLocalized = 'conversationsSettingsTitle';
+ categoryTitle = window.i18n('conversationsSettingsTitle');
break;
case SessionSettingCategory.Notifications:
- categoryLocalized = 'notificationsSettingsTitle';
+ categoryTitle = window.i18n('notificationsSettingsTitle');
break;
case SessionSettingCategory.Help:
- categoryLocalized = 'helpSettingsTitle';
+ categoryTitle = window.i18n('helpSettingsTitle');
break;
case SessionSettingCategory.Permissions:
- categoryLocalized = 'permissionsSettingsTitle';
+ categoryTitle = window.i18n('permissionsSettingsTitle');
break;
case SessionSettingCategory.Privacy:
- categoryLocalized = 'privacySettingsTitle';
+ categoryTitle = window.i18n('privacySettingsTitle');
break;
default:
throw missingCaseError('SettingsHeader' as never);
}
- const categoryTitle = window.i18n(categoryLocalized);
-
return (
{categoryTitle}
diff --git a/ts/components/settings/SettingsThemeSwitcher.tsx b/ts/components/settings/SettingsThemeSwitcher.tsx
index b0abfad4f..0ca644a60 100644
--- a/ts/components/settings/SettingsThemeSwitcher.tsx
+++ b/ts/components/settings/SettingsThemeSwitcher.tsx
@@ -159,7 +159,7 @@ const Themes = () => {
};
export const SettingsThemeSwitcher = () => {
- //FIXME store that value somewhere in the theme object
+ //TODO Theming
const [selectedAccent, setSelectedAccent] = useState(undefined);
return (
diff --git a/ts/components/settings/section/CategoryAppearance.tsx b/ts/components/settings/section/CategoryAppearance.tsx
index d665b607a..c593fe806 100644
--- a/ts/components/settings/section/CategoryAppearance.tsx
+++ b/ts/components/settings/section/CategoryAppearance.tsx
@@ -19,7 +19,7 @@ export const SettingsCategoryAppearance = (props: { hasPassword: boolean | null
return (
<>
-
+ {window.sessionFeatureFlags.useSettingsThemeSwitcher && }
{isHideMenuBarSupported() && (
void
+ uiCallback?: (args: JoinSogsRoomUICallbackArgs) => void
): Promise {
try {
const parsedRoom = parseOpenGroupV2(completeUrl);
@@ -142,9 +147,9 @@ export async function joinOpenGroupV2WithUIEvents(
if (showToasts) {
ToastUtils.pushToastInfo('connectingToServer', window.i18n('connectingToServer'));
}
- if (uiCallback) {
- uiCallback(true);
- }
+
+ uiCallback?.({ loadingState: 'started', conversationKey: conversationID });
+
await joinOpenGroupV2(parsedRoom, fromConfigMessage);
const isConvoCreated = getConversationController().get(conversationID);
@@ -155,21 +160,21 @@ export async function joinOpenGroupV2WithUIEvents(
window.i18n('connectToServerSuccess')
);
}
+ uiCallback?.({ loadingState: 'finished', conversationKey: conversationID });
+
return true;
} else {
if (showToasts) {
ToastUtils.pushToastError('connectToServerFail', window.i18n('connectToServerFail'));
}
}
+ uiCallback?.({ loadingState: 'failed', conversationKey: conversationID });
} catch (error) {
window?.log?.warn('got error while joining open group:', error.message);
if (showToasts) {
ToastUtils.pushToastError('connectToServerFail', window.i18n('connectToServerFail'));
}
- } finally {
- if (uiCallback) {
- uiCallback(false);
- }
+ uiCallback?.({ loadingState: 'failed', conversationKey: null });
}
return false;
}
diff --git a/ts/session/apis/open_group_api/opengroupV2/OpenGroupServerPoller.ts b/ts/session/apis/open_group_api/opengroupV2/OpenGroupServerPoller.ts
index 27a0bc550..99e925faa 100644
--- a/ts/session/apis/open_group_api/opengroupV2/OpenGroupServerPoller.ts
+++ b/ts/session/apis/open_group_api/opengroupV2/OpenGroupServerPoller.ts
@@ -20,6 +20,10 @@ import {
roomHasBlindEnabled,
} from '../sogsv3/sogsV3Capabilities';
import { OpenGroupReaction } from '../../../../types/Reaction';
+import {
+ markConversationInitialLoadingInProgress,
+ openConversationWithMessages,
+} from '../../../../state/ducks/conversations';
export type OpenGroupMessageV4 = {
/** AFAIK: indicates the number of the message in the group. e.g. 2nd message will be 1 or 2 */
@@ -317,6 +321,36 @@ export class OpenGroupServerPoller {
// ==> At this point all those results need to trigger conversation updates, so update what we have to update
await handleBatchPollResults(this.serverUrl, batchPollResults, subrequestOptions);
+
+ for (const room of subrequestOptions) {
+ if (room.type === 'messages' && !room.messages?.sinceSeqNo && room.messages?.roomId) {
+ const conversationKey = getOpenGroupV2ConversationId(
+ this.serverUrl,
+ room.messages.roomId
+ );
+
+ global.setTimeout(() => {
+ const stateConversations = window.inboxStore?.getState().conversations;
+ if (
+ stateConversations.conversationLookup?.[conversationKey]?.isInitialFetchingInProgress
+ ) {
+ if (
+ stateConversations.selectedConversation &&
+ conversationKey === stateConversations.selectedConversation
+ ) {
+ void openConversationWithMessages({ conversationKey, messageId: null }).then(() => {
+ window.inboxStore?.dispatch(
+ markConversationInitialLoadingInProgress({
+ conversationKey,
+ isInitialFetchingInProgress: false,
+ })
+ );
+ });
+ }
+ }
+ }, 5000);
+ }
+ }
} catch (e) {
window?.log?.warn('Got error while compact fetch:', e.message);
} finally {
diff --git a/ts/session/constants.ts b/ts/session/constants.ts
index 44d64a627..9517c6a29 100644
--- a/ts/session/constants.ts
+++ b/ts/session/constants.ts
@@ -45,7 +45,7 @@ export const CONVERSATION = {
export const MAX_ATTACHMENT_FILESIZE_BYTES = 6 * 1000 * 1000; // 6MB
export const VALIDATION = {
- MAX_GROUP_NAME_LENGTH: 64,
+ MAX_GROUP_NAME_LENGTH: 30,
CLOSED_GROUP_SIZE_LIMIT: 100,
};
diff --git a/ts/state/ducks/conversations.ts b/ts/state/ducks/conversations.ts
index 178fe8618..0ff54b94d 100644
--- a/ts/state/ducks/conversations.ts
+++ b/ts/state/ducks/conversations.ts
@@ -264,6 +264,7 @@ export interface ReduxConversationType {
currentNotificationSetting?: ConversationNotificationSettingType;
isPinned?: boolean;
+ isInitialFetchingInProgress?: boolean;
isApproved?: boolean;
didApproveMe?: boolean;
@@ -717,10 +718,6 @@ const conversationsSlice = createSlice({
initialMessages: Array;
}>
) {
- if (state.selectedConversation === action.payload.conversationKey) {
- return state;
- }
-
// this is quite hacky, but we don't want to show the showScrollButton if we have only a small amount of messages,
// or if the first unread message is not far from the most recent one.
// this is because when a new message get added, we do not add it to redux depending on the showScrollButton state.
@@ -835,6 +832,20 @@ const conversationsSlice = createSlice({
state.mentionMembers = action.payload;
return state;
},
+ markConversationInitialLoadingInProgress(
+ state: ConversationsStateType,
+ action: PayloadAction<{ conversationKey: string; isInitialFetchingInProgress: boolean }>
+ ) {
+ window?.log?.info(
+ `mark conversation initialLoading ${action.payload.conversationKey}: ${action.payload.isInitialFetchingInProgress}`
+ );
+ if (state.conversationLookup[action.payload.conversationKey]) {
+ state.conversationLookup[action.payload.conversationKey].isInitialFetchingInProgress =
+ action.payload.isInitialFetchingInProgress;
+ }
+
+ return state;
+ },
},
extraReducers: (builder: any) => {
// Add reducers for additional action types here, and handle loading state as needed
@@ -945,7 +956,7 @@ function applyConversationChanged(
selectedConversation,
conversationLookup: {
...conversationLookup,
- [id]: data,
+ [id]: { ...data, isInitialFetchingInProgress: existing.isInitialFetchingInProgress },
},
};
}
@@ -981,6 +992,7 @@ export const {
setNextMessageToPlayId,
updateMentionsMembers,
resetConversationExternal,
+ markConversationInitialLoadingInProgress,
} = actions;
export async function openConversationWithMessages(args: {
diff --git a/ts/state/ducks/section.tsx b/ts/state/ducks/section.tsx
index 89bc0980b..9c0ffcd7f 100644
--- a/ts/state/ducks/section.tsx
+++ b/ts/state/ducks/section.tsx
@@ -92,6 +92,7 @@ export const actions = {
export const initialSectionState: SectionStateType = {
focusedSection: SectionType.Message,
+ focusedSettingsSection: undefined,
isAppFocused: false,
overlayMode: undefined,
};
diff --git a/ts/state/selectors/conversations.ts b/ts/state/selectors/conversations.ts
index 247380d89..f3b1c0b3c 100644
--- a/ts/state/selectors/conversations.ts
+++ b/ts/state/selectors/conversations.ts
@@ -1172,3 +1172,8 @@ export const getOldBottomMessageId = createSelector(
getConversations,
(state: ConversationsStateType): string | null => state.oldBottomMessageId || null
);
+
+export const getIsSelectedConvoInitialLoadingInProgress = createSelector(
+ getSelectedConversation,
+ (convo: ReduxConversationType | undefined): boolean => Boolean(convo?.isInitialFetchingInProgress)
+);
diff --git a/ts/state/smart/SessionConversation.ts b/ts/state/smart/SessionConversation.ts
index f38cf803b..ca9692a6c 100644
--- a/ts/state/smart/SessionConversation.ts
+++ b/ts/state/smart/SessionConversation.ts
@@ -3,6 +3,7 @@ import { mapDispatchToProps } from '../actions';
import { StateType } from '../reducer';
import { getTheme } from '../selectors/theme';
import {
+ getIsSelectedConvoInitialLoadingInProgress,
getLightBoxOptions,
getSelectedConversation,
getSelectedConversationKey,
@@ -29,6 +30,7 @@ const mapStateToProps = (state: StateType) => {
lightBoxOptions: getLightBoxOptions(state),
stagedAttachments: getStagedAttachmentsForCurrentConversation(state),
hasOngoingCallWithFocusedConvo: getHasOngoingCallWithFocusedConvo(state),
+ isSelectedConvoInitialLoadingInProgress: getIsSelectedConvoInitialLoadingInProgress(state),
};
};
diff --git a/ts/themes/SessionTheme.tsx b/ts/themes/SessionTheme.tsx
index 786181b56..98c3dba6f 100644
--- a/ts/themes/SessionTheme.tsx
+++ b/ts/themes/SessionTheme.tsx
@@ -74,7 +74,6 @@ const darkFilterSessionText = 'none';
const darkUnreadBorder = `4px solid ${accentDarkTheme}`;
const darkScrollbarThumb = darkGrayColor;
-const darkScrollbarTrack = '#1b1b1b';
const darkFakeChatBubbleBg = '#212121';
const darkInboxBackground = '#171717';
@@ -150,7 +149,6 @@ export const switchHtmlToDarkTheme = () => {
document.documentElement.style.setProperty('--border-unread', darkUnreadBorder);
document.documentElement.style.setProperty('--color-scroll-bar-thumb', darkScrollbarThumb);
- document.documentElement.style.setProperty('--color-scroll-bar-track', darkScrollbarTrack);
document.documentElement.style.setProperty(
'--color-fake-chat-bubble-background',
darkFakeChatBubbleBg
@@ -225,7 +223,6 @@ const lightFilterSessionText = 'brightness(0) saturate(100%)';
const lightUnreadBorder = `4px solid ${accentLightTheme}`;
const lightScrollbarThumb = darkGrayColor;
-const lightScrollbarTrack = '#fcfcfc';
const lightFakeChatBubbleBg = '#f5f5f5';
const lightInboxBackground = whiteColor;
@@ -307,7 +304,6 @@ export const switchHtmlToLightTheme = () => {
document.documentElement.style.setProperty('--border-unread', lightUnreadBorder);
document.documentElement.style.setProperty('--color-scroll-bar-thumb', lightScrollbarThumb);
- document.documentElement.style.setProperty('--color-scroll-bar-track', lightScrollbarTrack);
document.documentElement.style.setProperty(
'--color-fake-chat-bubble-background',
lightFakeChatBubbleBg
@@ -445,7 +441,6 @@ export const SessionGlobalStyles = createGlobalStyle`
--color-pill-divider-text: ${lightColorPillDividerText};
--color-input-background: ${lightInputBackground};
--color-scroll-bar-thumb: ${lightScrollbarThumb};
- --color-scroll-bar-track: ${lightScrollbarTrack};
--color-fake-chat-bubble-background: ${lightFakeChatBubbleBg};
--color-inbox-background: ${lightInboxBackground};
--color-left-pane-overlay-background: ${lightLeftPaneOverlayBg};
diff --git a/ts/types/LocalizerKeys.ts b/ts/types/LocalizerKeys.ts
index e6d317dfb..d004aa636 100644
--- a/ts/types/LocalizerKeys.ts
+++ b/ts/types/LocalizerKeys.ts
@@ -67,6 +67,7 @@ export type LocalizerKeys =
| 'timerOption_1_hour'
| 'youGotKickedFromGroup'
| 'cannotRemoveCreatorFromGroupDesc'
+ | 'contactAvatarAlt'
| 'incomingError'
| 'notificationsSettingsTitle'
| 'conversationsSettingsTitle'
@@ -75,6 +76,7 @@ export type LocalizerKeys =
| 'from'
| 'requestsSubtitle'
| 'thisMonth'
+ | 'chooseAnAction'
| 'next'
| 'addModerators'
| 'sessionMessenger'
@@ -122,7 +124,6 @@ export type LocalizerKeys =
| 'deleteJustForMe'
| 'changeAccountPasswordTitle'
| 'onionPathIndicatorDescription'
- | 'pruningOpengroupDialogSubMessage'
| 'mediaPermissionsTitle'
| 'replyingToMessage'
| 'welcomeToYourSession'
@@ -176,6 +177,7 @@ export type LocalizerKeys =
| 'copyOpenGroupURL'
| 'setPasswordInvalid'
| 'timerOption_30_seconds_abbreviated'
+ | 'createConversationNewContact'
| 'removeResidueMembers'
| 'areYouSureDeleteEntireAccount'
| 'noGivenPassword'
@@ -256,7 +258,6 @@ export type LocalizerKeys =
| 'goToSupportPage'
| 'passwordsDoNotMatch'
| 'createClosedGroupNamePrompt'
- | 'pruningOpengroupDialogMessage'
| 'audioMessageAutoplayDescription'
| 'leaveAndRemoveForEveryone'
| 'previewThumbnail'
@@ -267,6 +268,7 @@ export type LocalizerKeys =
| 'reactionPopupOne'
| 'imageCaptionIconAlt'
| 'sendRecoveryPhraseTitle'
+ | 'joinACommunity'
| 'multipleJoinedTheGroup'
| 'messageRequestAcceptedOursNoName'
| 'databaseError'
@@ -335,8 +337,7 @@ export type LocalizerKeys =
| 'respondingToRequestWarning'
| 'error'
| 'clearAllData'
- | 'pruningOpengroupDialogTitle'
- | 'contactAvatarAlt'
+ | 'createConversationNewGroup'
| 'disappearingMessages'
| 'autoUpdateNewVersionTitle'
| 'linkPreviewDescription'
@@ -390,6 +391,7 @@ export type LocalizerKeys =
| 'changeAccountPasswordDescription'
| 'notificationSettingsDialog'
| 'invalidOldPassword'
+ | 'messageBody'
| 'audioMessageAutoplayTitle'
| 'removePasswordInvalid'
| 'password'
diff --git a/ts/util/blockedNumberController.ts b/ts/util/blockedNumberController.ts
index e49a1424e..17616ae95 100644
--- a/ts/util/blockedNumberController.ts
+++ b/ts/util/blockedNumberController.ts
@@ -88,7 +88,7 @@ export class BlockedNumberController {
}
/**
- * Unblock all thope users.
+ * Unblock all these users.
* This will only unblock the primary device of the user.
*
* @param user The user to unblock.
diff --git a/ts/window.d.ts b/ts/window.d.ts
index 8071c232d..6e55cbb27 100644
--- a/ts/window.d.ts
+++ b/ts/window.d.ts
@@ -6,6 +6,7 @@ import { Store } from 'redux';
import { ConversationCollection, ConversationModel } from './models/conversation';
import { ConversationType } from './state/ducks/conversations';
+import { StateType } from './state/reducer';
export interface LibTextsecure {
messaging: boolean;
@@ -21,11 +22,7 @@ declare global {
CONSTANTS: any;
Events: any;
Lodash: any;
- SessionSnodeAPI: any;
Session: any;
- StubAppDotNetApi: any;
- StringView: any;
- StubMessageAPI: any;
Whisper: any;
clearLocalData: any;
clipboard: any;
@@ -38,6 +35,7 @@ declare global {
sessionFeatureFlags: {
useOnionRequests: boolean;
useTestNet: boolean;
+ useSettingsThemeSwitcher: boolean;
debug: {
debugFileServerRequests: boolean;
debugNonSnodeRequests: boolean;