diff --git a/_locales/en/messages.json b/_locales/en/messages.json
index 15d48eebe..ff578d86e 100644
--- a/_locales/en/messages.json
+++ b/_locales/en/messages.json
@@ -416,5 +416,9 @@
"pinConversationLimitToastDescription": "You can only pin $number$ conversations",
"latestUnreadIsAbove": "First unread message is above",
"sendRecoveryPhraseTitle": "Sending Recovery Phrase",
- "sendRecoveryPhraseMessage": "You are attempting to send your recovery phrase which can be used to access your account. Are you sure you want to send this message?"
+ "sendRecoveryPhraseMessage": "You are attempting to send your recovery phrase which can be used to access your account. Are you sure you want to send this message?",
+ "all": "All",
+ "mentionsOnly": "Mentions only",
+ "disabled": "Disabled",
+ "notificationSubtitle": "Notifications - $setting$"
}
diff --git a/ts/components/ConversationListItem.tsx b/ts/components/ConversationListItem.tsx
index 93a0eb2c7..8098b6944 100644
--- a/ts/components/ConversationListItem.tsx
+++ b/ts/components/ConversationListItem.tsx
@@ -30,11 +30,11 @@ import { getFirstUnreadMessageIdInConversation } from '../data/data';
import { ConversationNotificationSettingType } from '../models/conversation';
// tslint:disable-next-line: no-empty-interface
-export interface ConversationListItemProps extends ReduxConversationType { }
+export interface ConversationListItemProps extends ReduxConversationType {}
export const StyledConversationListItemIconWrapper = styled.div`
svg {
- margin: 2px 2px;
+ margin: 0px 2px;
}
display: flex;
@@ -71,7 +71,7 @@ const HeaderItem = (props: {
conversationId,
profileName,
name,
- currentNotificationSetting
+ currentNotificationSetting,
} = props;
const theme = useTheme();
@@ -93,31 +93,34 @@ const HeaderItem = (props: {
/>
) : null;
-
const NotificationSettingIcon = () => {
if (!isMessagesSection) {
return null;
}
switch (currentNotificationSetting) {
- case ('all'):
+ case 'all':
return null;
- case ('disabled'):
- return
- case ('mentions_only'):
- return
+ case 'disabled':
+ return (
+
+ );
+ case 'mentions_only':
+ return (
+
+ );
default:
return null;
}
- }
+ };
return (
@@ -137,7 +140,7 @@ const HeaderItem = (props: {
{pinIcon}
-
+
{unreadCountDiv}
{atSymbol}
diff --git a/ts/components/conversation/ConversationHeader.tsx b/ts/components/conversation/ConversationHeader.tsx
index d9cc42b81..96c4dba1b 100644
--- a/ts/components/conversation/ConversationHeader.tsx
+++ b/ts/components/conversation/ConversationHeader.tsx
@@ -7,12 +7,13 @@ import { SessionIconButton, SessionIconSize, SessionIconType } from '../session/
import { SessionButton, SessionButtonColor, SessionButtonType } from '../session/SessionButton';
import { ConversationAvatar } from '../session/usingClosedConversationDetails';
import { MemoConversationHeaderMenu } from '../session/menu/ConversationHeaderMenu';
-import { contextMenu } from 'react-contexify';
-import { useTheme } from 'styled-components';
+import { contextMenu, theme } from 'react-contexify';
+import styled, { useTheme } from 'styled-components';
import { ConversationNotificationSettingType } from '../../models/conversation';
import {
getConversationHeaderProps,
getConversationHeaderTitleProps,
+ getCurrentNotificationSettingText,
getSelectedConversation,
getSelectedMessageIds,
isMessageDetailView,
@@ -74,7 +75,6 @@ const SelectionOverlay = (props: {
}) => {
const { onDeleteSelectedMessages, onCloseOverlay, isPublic } = props;
const { i18n } = window;
- const theme = useTheme();
const isServerDeletable = isPublic;
const deleteMessageButtonText = i18n(isServerDeletable ? 'deleteForEveryone' : 'delete');
@@ -86,7 +86,7 @@ const SelectionOverlay = (props: {
iconType={SessionIconType.Exit}
iconSize={SessionIconSize.Medium}
onClick={onCloseOverlay}
- theme={theme}
+ theme={useTheme()}
/>
@@ -104,7 +104,6 @@ const SelectionOverlay = (props: {
const TripleDotsMenu = (props: { triggerId: string; showBackButton: boolean }) => {
const { showBackButton } = props;
- const theme = useTheme();
if (showBackButton) {
return <>>;
}
@@ -121,7 +120,7 @@ const TripleDotsMenu = (props: { triggerId: string; showBackButton: boolean }) =
);
@@ -175,7 +174,6 @@ const AvatarHeader = (props: {
const BackButton = (props: { onGoBack: () => void; showBackButton: boolean }) => {
const { onGoBack, showBackButton } = props;
- const theme = useTheme();
if (!showBackButton) {
return null;
}
@@ -186,11 +184,29 @@ const BackButton = (props: { onGoBack: () => void; showBackButton: boolean }) =>
iconSize={SessionIconSize.Large}
iconRotation={90}
onClick={onGoBack}
- theme={theme}
+ theme={useTheme()}
/>
);
};
+interface StyledSubtitleContainerProps {
+ margin?: string;
+}
+export const StyledSubtitleContainer = styled.div`
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+
+ span {
+ margin-bottom: ${(p: StyledSubtitleContainerProps) => p.margin || '5px'};
+ }
+
+ span:last-child {
+ margin-bottom: 0;
+ }
+`;
+
export type ConversationHeaderTitleProps = {
phoneNumber: string;
profileName?: string;
@@ -201,6 +217,7 @@ export type ConversationHeaderTitleProps = {
subscriberCount?: number;
isKickedFromGroup: boolean;
name?: string;
+ currentNotificationSetting?: ConversationNotificationSettingType;
};
const ConversationHeaderTitle = () => {
@@ -245,21 +262,36 @@ const ConversationHeaderTitle = () => {
text = i18n('members', [count]);
}
- const textEl =
- text === '' || isKickedFromGroup ? null : (
- {text}
- );
-
+ const notificationSetting = useSelector(getCurrentNotificationSettingText);
+ const notificationSubtitle = notificationSetting
+ ? window.i18n('notificationSubtitle', notificationSetting)
+ : null;
const title = profileName || name || phoneNumber;
return (
{title}
- {textEl}
+
+ {isKickedFromGroup ? null : }
+
+
);
};
+/**
+ * The subtitle beneath a conversation title when looking at a conversation screen.
+ * @param props props for subtitle. Text to be displayed
+ * @returns JSX Element of the subtitle of conversation header
+ */
+export const ConversationHeaderSubtitle = (props: { text?: string | null }): JSX.Element | null => {
+ const { text } = props;
+ if (!text) {
+ return null;
+ }
+ return {text};
+};
+
export const ConversationHeaderWithDetails = () => {
const headerProps = useSelector(getConversationHeaderProps);
diff --git a/ts/components/session/icon/Icons.tsx b/ts/components/session/icon/Icons.tsx
index c5d6d64d7..e82f6866e 100644
--- a/ts/components/session/icon/Icons.tsx
+++ b/ts/components/session/icon/Icons.tsx
@@ -1,7 +1,7 @@
export enum SessionIconType {
AddUser = 'addUser',
Arrow = 'arrow',
- Bell= 'bell',
+ Bell = 'bell',
Caret = 'caret',
ChatBubble = 'chatBubble',
Check = 'check',
@@ -83,7 +83,8 @@ export const icons = {
ratio: 1,
},
[SessionIconType.Bell]: {
- path: 'M68.16 6.889c18.129 3.653 31.889 19.757 31.889 38.921 0 22.594-2.146 39.585 20.592 54.716H0c22.8-15.173 20.647-32.49 20.647-54.716 0-19.267 13.91-35.439 32.182-38.979 1.054-9.14 14.345-9.096 15.331.058zm8.551 102.301c-1.398 7.785-8.205 13.688-16.392 13.688s-14.992-5.902-16.393-13.688h32.785z',
+ path:
+ 'M68.16 6.889c18.129 3.653 31.889 19.757 31.889 38.921 0 22.594-2.146 39.585 20.592 54.716H0c22.8-15.173 20.647-32.49 20.647-54.716 0-19.267 13.91-35.439 32.182-38.979 1.054-9.14 14.345-9.096 15.331.058zm8.551 102.301c-1.398 7.785-8.205 13.688-16.392 13.688s-14.992-5.902-16.393-13.688h32.785z',
viewBox: '0 0 120.641 122.878',
ratio: 1,
},
@@ -223,7 +224,7 @@ export const icons = {
},
[SessionIconType.Mute]: {
path:
- "M7.02 28.81h28.65c.6 0 1.09.49 1.09 1.09v44.09L17.76 93H7c-3.85 0-7-3.15-7-7V35.83c0-3.86 3.16-7.02 7.02-7.02zM111.29 6.02l11.59 11.59-93.17 93.17-11.59-11.59 93.17-93.17zM42.33 27.67C59.03 18.51 75.73 9.35 92.42.19c1.6-.88 3.32 1.49 3.32 3.32v11.5L41.66 69.1V28.34c0-.37.35-.49.67-.67zm53.41 23.99v65.6c0 1.92-1.82 4.45-3.5 3.5L50.29 97.11l45.45-45.45z",
+ 'M7.02 28.81h28.65c.6 0 1.09.49 1.09 1.09v44.09L17.76 93H7c-3.85 0-7-3.15-7-7V35.83c0-3.86 3.16-7.02 7.02-7.02zM111.29 6.02l11.59 11.59-93.17 93.17-11.59-11.59 93.17-93.17zM42.33 27.67C59.03 18.51 75.73 9.35 92.42.19c1.6-.88 3.32 1.49 3.32 3.32v11.5L41.66 69.1V28.34c0-.37.35-.49.67-.67zm53.41 23.99v65.6c0 1.92-1.82 4.45-3.5 3.5L50.29 97.11l45.45-45.45z',
viewBox: '0 0 122.88 120.97',
ratio: 1,
},
diff --git a/ts/components/session/settings/SessionSettings.tsx b/ts/components/session/settings/SessionSettings.tsx
index 8b5d07e29..029a1d294 100644
--- a/ts/components/session/settings/SessionSettings.tsx
+++ b/ts/components/session/settings/SessionSettings.tsx
@@ -253,11 +253,13 @@ class SettingsViewInner extends React.Component {
return (
v{window.versionInfo.version}
-
+
+
+
{window.versionInfo.commitHash}
);
diff --git a/ts/state/selectors/conversations.ts b/ts/state/selectors/conversations.ts
index f24683956..7be618d2d 100644
--- a/ts/state/selectors/conversations.ts
+++ b/ts/state/selectors/conversations.ts
@@ -238,9 +238,31 @@ export const getConversationHeaderTitleProps = createSelector(getSelectedConvers
name: state.name,
subscriberCount: state.subscriberCount,
isGroup: state.type === 'group',
+ currentNotificationSetting: state.currentNotificationSetting,
};
});
+/**
+ * Returns the formatted text for notification setting.
+ */
+export const getCurrentNotificationSettingText = createSelector(getSelectedConversation, (state):
+ | string
+ | undefined => {
+ if (!state) {
+ return undefined;
+ }
+ switch (state.currentNotificationSetting) {
+ case 'all':
+ return window.i18n('all');
+ case 'mentions_only':
+ return window.i18n('mentionsOnly');
+ case 'disabled':
+ return window.i18n('disabled');
+ default:
+ return window.i18n('all');
+ }
+});
+
export const getConversationHeaderProps = createSelector(getSelectedConversation, (state):
| ConversationHeaderProps
| undefined => {