diff --git a/native/chat/settings/thread-settings-notifications.react.js b/native/chat/settings/thread-settings-notifications.react.js
index 9721ed81a..0a3b21e5b 100644
--- a/native/chat/settings/thread-settings-notifications.react.js
+++ b/native/chat/settings/thread-settings-notifications.react.js
@@ -1,135 +1,298 @@
// @flow
import * as React from 'react';
-import { View } from 'react-native';
+import { View, Text } from 'react-native';
import {
threadSettingsNotificationsCopy,
useThreadSettingsNotifications,
} from 'lib/shared/thread-settings-notifications-utils.js';
import type { ThreadInfo } from 'lib/types/minimally-encoded-thread-permissions-types.js';
import EnumSettingsOption from '../../components/enum-settings-option.react.js';
+import SWMansionIcon from '../../components/swmansion-icon.react.js';
import HeaderRightTextButton from '../../navigation/header-right-text-button.react.js';
import type { NavigationRoute } from '../../navigation/route-names.js';
-import { useStyles } from '../../themes/colors.js';
+import { useStyles, useColors } from '../../themes/colors.js';
import AllNotifsIllustration from '../../vectors/all-notifs-illustration.react.js';
import BadgeNotifsIllustration from '../../vectors/badge-notifs-illustration.react.js';
import MutedNotifsIllustration from '../../vectors/muted-notifs-illustration.react.js';
import type { ChatNavigationProp } from '../chat.react.js';
export type ThreadSettingsNotificationsParams = {
+threadInfo: ThreadInfo,
};
+type NotificationDescriptionProps = {
+ +selected: boolean,
+ +bannerNotifsEnabled: boolean,
+ +badgeCountEnabled: boolean,
+ +livesInFocusedTab: boolean,
+};
+
+function NotificationDescription(
+ props: NotificationDescriptionProps,
+): React.Node {
+ const {
+ selected,
+ bannerNotifsEnabled,
+ badgeCountEnabled,
+ livesInFocusedTab,
+ } = props;
+
+ const styles = useStyles(unboundStyles);
+ const colors = useColors();
+
+ const bannerNotifsDescriptionTextStyles = React.useMemo(() => {
+ const style = [styles.notificationOptionDescriptionText];
+
+ if (selected && !bannerNotifsEnabled) {
+ style.push(styles.notificationOptionDescriptionTextDisabledSelected);
+ } else if (!bannerNotifsEnabled) {
+ style.push(styles.notificationOptionDescriptionTextDisabled);
+ }
+
+ return style;
+ }, [
+ bannerNotifsEnabled,
+ selected,
+ styles.notificationOptionDescriptionText,
+ styles.notificationOptionDescriptionTextDisabled,
+ styles.notificationOptionDescriptionTextDisabledSelected,
+ ]);
+
+ const badgeCountDescriptionTextStyles = React.useMemo(() => {
+ const style = [styles.notificationOptionDescriptionText];
+
+ if (selected && !badgeCountEnabled) {
+ style.push(styles.notificationOptionDescriptionTextDisabledSelected);
+ } else if (!badgeCountEnabled) {
+ style.push(styles.notificationOptionDescriptionTextDisabled);
+ }
+
+ return style;
+ }, [
+ badgeCountEnabled,
+ selected,
+ styles.notificationOptionDescriptionText,
+ styles.notificationOptionDescriptionTextDisabled,
+ styles.notificationOptionDescriptionTextDisabledSelected,
+ ]);
+
+ let bannerNotifsIconColor = colors.panelForegroundSecondaryLabel;
+ if (selected && !bannerNotifsEnabled) {
+ bannerNotifsIconColor = colors.panelInputSecondaryForeground;
+ } else if (!bannerNotifsEnabled) {
+ bannerNotifsIconColor = colors.panelSecondaryForeground;
+ }
+
+ let badgeCountIconColor = colors.panelForegroundSecondaryLabel;
+ if (selected && !badgeCountEnabled) {
+ badgeCountIconColor = colors.panelInputSecondaryForeground;
+ } else if (!badgeCountEnabled) {
+ badgeCountIconColor = colors.panelSecondaryForeground;
+ }
+
+ return (
+ <>
+
+
+
+ {threadSettingsNotificationsCopy.BANNER_NOTIFS}
+
+
+
+
+
+ {threadSettingsNotificationsCopy.BADGE_COUNT}
+
+
+
+
+
+ {livesInFocusedTab
+ ? threadSettingsNotificationsCopy.IN_FOCUSED_TAB
+ : threadSettingsNotificationsCopy.IN_BACKGROUND_TAB}
+
+
+ >
+ );
+}
+
type Props = {
+navigation: ChatNavigationProp<'ThreadSettingsNotifications'>,
+route: NavigationRoute<'ThreadSettingsNotifications'>,
};
function ThreadSettingsNotifications(props: Props): React.Node {
const {
navigation: { setOptions, goBack },
route: {
params: { threadInfo },
},
} = props;
const {
notificationSettings,
onFocusedSelected,
onBadgeOnlySelected,
onBackgroundSelected,
saveButtonDisabled,
onSave,
} = useThreadSettingsNotifications(threadInfo, goBack);
React.useEffect(() => {
setOptions({
headerRight: () => (
),
});
}, [saveButtonDisabled, onSave, setOptions]);
const styles = useStyles(unboundStyles);
const allNotificationsIllustration = React.useMemo(
() => (
),
[styles.notificationOptionIconContainer],
);
const badgeOnlyIllustration = React.useMemo(
() => (
),
[styles.notificationOptionIconContainer],
);
const mutedIllustration = React.useMemo(
() => (
),
[styles.notificationOptionIconContainer],
);
+ const allNotificationsDescription = React.useMemo(
+ () => (
+
+ ),
+ [notificationSettings],
+ );
+
+ const badgeOnlyDescription = React.useMemo(
+ () => (
+
+ ),
+ [notificationSettings],
+ );
+
+ const mutedDescription = React.useMemo(
+ () => (
+
+ ),
+ [notificationSettings],
+ );
+
return (
);
}
const unboundStyles = {
container: {
backgroundColor: 'panelForeground',
},
enumSettingsOptionContainer: {
padding: 8,
},
notificationOptionIconContainer: {
justifyContent: 'center',
marginLeft: 8,
marginRight: 16,
},
+ notificationOptionDescriptionListItem: {
+ flexDirection: 'row',
+ alignItems: 'center',
+ marginTop: 4,
+ },
+ notificationOptionDescriptionText: {
+ color: 'panelForegroundSecondaryLabel',
+ marginLeft: 4,
+ fontSize: 14,
+ },
+ notificationOptionDescriptionTextDisabled: {
+ textDecorationLine: 'line-through',
+ color: 'panelSecondaryForeground',
+ },
+ notificationOptionDescriptionTextDisabledSelected: {
+ color: 'panelInputSecondaryForeground',
+ textDecorationLine: 'line-through',
+ },
};
export default ThreadSettingsNotifications;
diff --git a/native/components/enum-settings-option.react.js b/native/components/enum-settings-option.react.js
index 3ec6c4b9c..4cfd1dff9 100644
--- a/native/components/enum-settings-option.react.js
+++ b/native/components/enum-settings-option.react.js
@@ -1,188 +1,196 @@
// @flow
import * as React from 'react';
import { Text, TouchableOpacity, View } from 'react-native';
import CommIcon from '../components/comm-icon.react.js';
import { useColors, useStyles } from '../themes/colors.js';
type InputType = 'radio' | 'checkbox';
type EnumSettingsOptionProps = {
+icon?: string | React.Node,
+name: string,
- +description: string,
+ +description: string | React.Node,
+enumValue: boolean,
+onEnumValuePress: () => mixed,
+type?: InputType,
+disabled?: boolean,
};
function EnumSettingsOption(props: EnumSettingsOptionProps): React.Node {
const styles = useStyles(unboundStyles);
const colors = useColors();
const {
icon,
name,
description,
enumValue,
onEnumValuePress,
type = 'radio',
disabled,
} = props;
const enumIcon = React.useMemo(() => {
if (!icon) {
return null;
}
if (typeof icon === 'string') {
return (
);
}
return icon;
}, [icon, styles.enumIcon, colors.purpleButton]);
+ const descriptionElement = React.useMemo(() => {
+ if (typeof description === 'string') {
+ return {description};
+ }
+
+ return description;
+ }, [description, styles.enumInfoDescription]);
+
const enumInputStyles = React.useMemo(() => {
const style = [styles.enumInput];
if (disabled) {
style.push(styles.disabled);
} else if (type === 'radio') {
style.push(styles.radio);
} else {
style.push(styles.checkBox);
}
return style;
}, [
disabled,
styles.checkBox,
styles.disabled,
styles.enumInput,
styles.radio,
type,
]);
const enumInputFilledStyles = React.useMemo(() => {
const style = [styles.enumInputFill];
if (type === 'radio') {
style.push(styles.radioFill);
} else {
style.push(styles.checkBoxFill);
}
return style;
}, [styles.checkBoxFill, styles.enumInputFill, styles.radioFill, type]);
const enumInputFill = React.useMemo(
() => (enumValue ? : null),
[enumValue, enumInputFilledStyles],
);
const touchableContainerStyle = React.useMemo(() => {
const style = [styles.touchableContainer];
if (enumValue) {
style.push(styles.touchableContainerSelected);
}
return style;
}, [enumValue, styles.touchableContainer, styles.touchableContainerSelected]);
return (
{enumIcon}
{name}
- {description}
+ {descriptionElement}
{enumInputFill}
);
}
const unboundStyles = {
container: {
backgroundColor: 'panelForeground',
paddingVertical: 4,
paddingHorizontal: 8,
},
touchableContainer: {
flexDirection: 'row',
padding: 12,
},
touchableContainerSelected: {
backgroundColor: 'panelSecondaryForeground',
borderRadius: 8,
},
enumIcon: {
paddingTop: 4,
paddingRight: 24,
},
enumInfoContainer: {
flex: 1,
flexDirection: 'column',
justifyContent: 'space-evenly',
},
enumInfoName: {
color: 'panelForegroundLabel',
fontSize: 18,
lineHeight: 24,
marginBottom: 4,
},
enumInfoDescription: {
color: 'panelForegroundSecondaryLabel',
lineHeight: 18,
},
enumInputContainer: {
padding: 16,
paddingRight: 0,
justifyContent: 'center',
alignItems: 'center',
},
enumInput: {
height: 32,
width: 32,
borderWidth: 1,
borderColor: 'panelSecondaryForegroundBorder',
justifyContent: 'center',
alignItems: 'center',
},
checkBox: {
borderRadius: 3.5,
},
radio: {
borderRadius: 16,
},
enumInputFill: {
height: 20,
width: 20,
backgroundColor: 'panelForegroundSecondaryLabel',
},
checkBoxFill: {
borderRadius: 2.1875,
},
radioFill: {
borderRadius: 10,
},
disabled: {
opacity: 0,
},
};
export default EnumSettingsOption;