forked from Ivasoft/mattermost-mobile
MM-39711 - Gekidou Settings Push Notification functionality (#6373)
* adding nav hooks * added save button * capturing value from OptionItem * notification - saving in progress * tested API * corrections after review * Update en.json * Update notification_push.tsx * ts fixes * minor improvement Co-authored-by: Elias Nahum <nahumhbl@gmail.com>
This commit is contained in:
@@ -6,14 +6,16 @@ import withObservables from '@nozbe/with-observables';
|
||||
|
||||
import {observeConfigBooleanValue} from '@queries/servers/system';
|
||||
import {observeIsCRTEnabled} from '@queries/servers/thread';
|
||||
import {observeCurrentUser} from '@queries/servers/user';
|
||||
import {WithDatabaseArgs} from '@typings/database/database';
|
||||
|
||||
import NotificationPush from './notification_push';
|
||||
|
||||
const enhanced = withObservables([], ({database}: WithDatabaseArgs) => {
|
||||
return {
|
||||
sendPushNotifications: observeConfigBooleanValue(database, 'SendPushNotifications'),
|
||||
currentUser: observeCurrentUser(database),
|
||||
isCRTEnabled: observeIsCRTEnabled(database),
|
||||
sendPushNotifications: observeConfigBooleanValue(database, 'SendPushNotifications'),
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
@@ -1,17 +1,26 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React, {useState} from 'react';
|
||||
import React, {useCallback, useEffect, useMemo, useState} from 'react';
|
||||
import {useIntl} from 'react-intl';
|
||||
import {ScrollView} from 'react-native';
|
||||
import {Edge, SafeAreaView} from 'react-native-safe-area-context';
|
||||
|
||||
import {updateMe} from '@actions/remote/user';
|
||||
import {useServerUrl} from '@context/server';
|
||||
import {useTheme} from '@context/theme';
|
||||
import useAndroidHardwareBackHandler from '@hooks/android_back_handler';
|
||||
import useNavButtonPressed from '@hooks/navigation_button_pressed';
|
||||
import {popTopScreen, setButtons} from '@screens/navigation';
|
||||
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
|
||||
import {getNotificationProps} from '@utils/user';
|
||||
|
||||
import MobileSendPush from './push_send';
|
||||
import MobilePushStatus from './push_status';
|
||||
import MobilePushThread from './push_thread';
|
||||
|
||||
import type UserModel from '@typings/database/models/servers/user';
|
||||
|
||||
const getStyleSheet = makeStyleSheetFromTheme((theme) => {
|
||||
return {
|
||||
container: {
|
||||
@@ -27,31 +36,78 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => {
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
const edges: Edge[] = ['left', 'right'];
|
||||
|
||||
const SAVE_NOTIF_BUTTON_ID = 'SAVE_NOTIF_BUTTON_ID';
|
||||
|
||||
type NotificationMobileProps = {
|
||||
componentId: string;
|
||||
currentUser: UserModel;
|
||||
isCRTEnabled: boolean;
|
||||
sendPushNotifications: boolean;
|
||||
};
|
||||
const NotificationPush = ({isCRTEnabled, sendPushNotifications}: NotificationMobileProps) => {
|
||||
const theme = useTheme();
|
||||
const [pushStatus, setPushStatus] = useState<PushStatus>('online');
|
||||
const [pushPref, setPushPref] = useState<PushStatus>('online');
|
||||
const [pushThread, setPushThreadPref] = useState<PushStatus>('online');
|
||||
const NotificationPush = ({componentId, currentUser, isCRTEnabled, sendPushNotifications}: NotificationMobileProps) => {
|
||||
const serverUrl = useServerUrl();
|
||||
|
||||
const notifyProps = useMemo(() => getNotificationProps(currentUser), [currentUser.notifyProps]);
|
||||
|
||||
const [pushSend, setPushSend] = useState<PushStatus>(notifyProps.push);
|
||||
const [pushStatus, setPushStatus] = useState<PushStatus>(notifyProps.push_status);
|
||||
const [pushThread, setPushThreadPref] = useState<PushStatus>(notifyProps?.push_threads || 'all');
|
||||
|
||||
const intl = useIntl();
|
||||
const theme = useTheme();
|
||||
const styles = getStyleSheet(theme);
|
||||
|
||||
const setMobilePushStatus = (status: PushStatus) => {
|
||||
setPushStatus(status);
|
||||
};
|
||||
const onMobilePushThreadChanged = useCallback(() => {
|
||||
setPushThreadPref(pushThread === 'all' ? 'mention' : 'all');
|
||||
}, [pushThread]);
|
||||
|
||||
const setMobilePushPref = (status: PushStatus) => {
|
||||
setPushPref(status);
|
||||
};
|
||||
const saveButton = useMemo(() => {
|
||||
return {
|
||||
id: SAVE_NOTIF_BUTTON_ID,
|
||||
enabled: false,
|
||||
showAsAction: 'always' as const,
|
||||
testID: 'notification_settings.save.button',
|
||||
color: theme.sidebarHeaderTextColor,
|
||||
text: intl.formatMessage({id: 'settings.save', defaultMessage: 'Save'}),
|
||||
};
|
||||
}, [theme.sidebarHeaderTextColor]);
|
||||
|
||||
const onMobilePushThreadChanged = (status: PushStatus) => {
|
||||
setPushThreadPref(status);
|
||||
};
|
||||
const close = useCallback(() => popTopScreen(componentId), [componentId]);
|
||||
|
||||
const saveNotificationSettings = useCallback(() => {
|
||||
const notify_props = {...notifyProps, push: pushSend, push_status: pushStatus, push_threads: pushThread};
|
||||
updateMe(serverUrl, {notify_props} as unknown as UserNotifyProps);
|
||||
close();
|
||||
}, [serverUrl, notifyProps, pushSend, pushStatus, pushThread, close]);
|
||||
|
||||
useEffect(() => {
|
||||
const p = pushSend !== notifyProps.push;
|
||||
const pT = pushThread !== notifyProps.push_threads;
|
||||
const pS = pushStatus !== notifyProps.push_status;
|
||||
|
||||
const enabled = p || pT || pS;
|
||||
|
||||
const buttons = {
|
||||
rightButtons: [{
|
||||
...saveButton,
|
||||
enabled,
|
||||
}],
|
||||
};
|
||||
setButtons(componentId, buttons);
|
||||
}, [
|
||||
componentId,
|
||||
notifyProps,
|
||||
pushSend,
|
||||
pushStatus,
|
||||
pushThread,
|
||||
]);
|
||||
|
||||
useNavButtonPressed(SAVE_NOTIF_BUTTON_ID, componentId, saveNotificationSettings, [saveNotificationSettings]);
|
||||
|
||||
useAndroidHardwareBackHandler(componentId, close);
|
||||
|
||||
return (
|
||||
<SafeAreaView
|
||||
@@ -65,20 +121,20 @@ const NotificationPush = ({isCRTEnabled, sendPushNotifications}: NotificationMob
|
||||
alwaysBounceVertical={false}
|
||||
>
|
||||
<MobileSendPush
|
||||
pushStatus={pushSend}
|
||||
sendPushNotifications={sendPushNotifications}
|
||||
pushStatus={pushPref}
|
||||
setMobilePushPref={setMobilePushPref}
|
||||
setMobilePushPref={setPushSend}
|
||||
/>
|
||||
{isCRTEnabled && pushPref === 'mention' && (
|
||||
{isCRTEnabled && pushSend === 'mention' && (
|
||||
<MobilePushThread
|
||||
pushThread={pushThread}
|
||||
onMobilePushThreadChanged={onMobilePushThreadChanged}
|
||||
/>
|
||||
)}
|
||||
{sendPushNotifications && pushPref !== 'none' && (
|
||||
{sendPushNotifications && pushSend !== 'none' && (
|
||||
<MobilePushStatus
|
||||
pushStatus={pushStatus}
|
||||
setMobilePushStatus={setMobilePushStatus}
|
||||
setMobilePushStatus={setPushStatus}
|
||||
/>
|
||||
)}
|
||||
</ScrollView>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React from 'react';
|
||||
import React, {useCallback} from 'react';
|
||||
import {useIntl} from 'react-intl';
|
||||
import {Platform, ScrollView, View} from 'react-native';
|
||||
import {Edge, SafeAreaView} from 'react-native-safe-area-context';
|
||||
@@ -37,6 +37,16 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => {
|
||||
});
|
||||
const edges: Edge[] = ['left', 'right'];
|
||||
|
||||
const mentionTexts = {
|
||||
crtOn: {
|
||||
id: t('notification_settings.mentions'),
|
||||
defaultMessage: 'Mentions',
|
||||
},
|
||||
crtOff: {
|
||||
id: t('notification_settings.mentions_replies'),
|
||||
defaultMessage: 'Mentions and Replies',
|
||||
},
|
||||
};
|
||||
type NotificationsProps = {
|
||||
isCRTEnabled: boolean;
|
||||
enableAutoResponder: boolean;
|
||||
@@ -46,14 +56,7 @@ const Notifications = ({isCRTEnabled, enableAutoResponder}: NotificationsProps)
|
||||
const styles = getStyleSheet(theme);
|
||||
const intl = useIntl();
|
||||
|
||||
let mentionsI18nId = t('notification_settings.mentions_replies');
|
||||
let mentionsI18nDefault = 'Mentions and Replies';
|
||||
if (isCRTEnabled) {
|
||||
mentionsI18nId = t('notification_settings.mentions');
|
||||
mentionsI18nDefault = 'Mentions';
|
||||
}
|
||||
|
||||
const goToNotificationSettingsMentions = () => {
|
||||
const goToNotificationSettingsMentions = useCallback(() => {
|
||||
const screen = Screens.SETTINGS_NOTIFICATION_MENTION;
|
||||
|
||||
const id = isCRTEnabled ? t('notification_settings.mentions') : t('notification_settings.mentions_replies');
|
||||
@@ -61,9 +64,9 @@ const Notifications = ({isCRTEnabled, enableAutoResponder}: NotificationsProps)
|
||||
const title = intl.formatMessage({id, defaultMessage});
|
||||
|
||||
goToScreen(screen, title);
|
||||
};
|
||||
}, [isCRTEnabled]);
|
||||
|
||||
const goToNotificationSettingsPush = () => {
|
||||
const goToNotificationSettingsPush = useCallback(() => {
|
||||
const screen = Screens.SETTINGS_NOTIFICATION_PUSH;
|
||||
const title = intl.formatMessage({
|
||||
id: 'notification_settings.push_notification',
|
||||
@@ -71,16 +74,16 @@ const Notifications = ({isCRTEnabled, enableAutoResponder}: NotificationsProps)
|
||||
});
|
||||
|
||||
goToScreen(screen, title);
|
||||
};
|
||||
}, []);
|
||||
|
||||
const goToNotificationAutoResponder = () => {
|
||||
const goToNotificationAutoResponder = useCallback(() => {
|
||||
const screen = Screens.SETTINGS_NOTIFICATION_AUTO_RESPONDER;
|
||||
const title = intl.formatMessage({
|
||||
id: 'notification_settings.auto_responder',
|
||||
defaultMessage: 'Automatic Replies',
|
||||
});
|
||||
goToScreen(screen, title);
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<SafeAreaView
|
||||
@@ -94,8 +97,8 @@ const Notifications = ({isCRTEnabled, enableAutoResponder}: NotificationsProps)
|
||||
>
|
||||
<View style={styles.divider}/>
|
||||
<SettingOption
|
||||
defaultMessage={mentionsI18nDefault}
|
||||
i18nId={mentionsI18nId}
|
||||
defaultMessage={isCRTEnabled ? mentionTexts.crtOn.defaultMessage : mentionTexts.crtOff.defaultMessage}
|
||||
i18nId={isCRTEnabled ? mentionTexts.crtOn.id : mentionTexts.crtOff.id}
|
||||
onPress={goToNotificationSettingsMentions}
|
||||
optionName='mentions'
|
||||
/>
|
||||
|
||||
@@ -307,16 +307,17 @@ export function getNotificationProps(user: UserModel) {
|
||||
}
|
||||
|
||||
const props: UserNotifyProps = {
|
||||
email: 'true',
|
||||
mark_unread: 'all',
|
||||
channel: 'true',
|
||||
comments: 'any',
|
||||
desktop: 'all',
|
||||
desktop_sound: 'true',
|
||||
email: 'true',
|
||||
first_name: (!user || !user.firstName) ? 'false' : 'true',
|
||||
mark_unread: 'all',
|
||||
mention_keys: user ? `${user.username},@${user.username}` : '',
|
||||
push: 'mention',
|
||||
push_status: 'online',
|
||||
push_threads: 'all',
|
||||
};
|
||||
|
||||
return props;
|
||||
|
||||
1
types/api/users.d.ts
vendored
1
types/api/users.d.ts
vendored
@@ -16,6 +16,7 @@ type UserNotifyProps = {
|
||||
push: 'default' | 'all' | 'mention' | 'none';
|
||||
push_status: 'ooo' | 'offline' | 'away' | 'dnd' | 'online';
|
||||
user_id?: string;
|
||||
push_threads?: 'all' | 'mention';
|
||||
};
|
||||
|
||||
type UserProfile = {
|
||||
|
||||
2
types/screens/settings.d.ts
vendored
2
types/screens/settings.d.ts
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
type PushStatus = 'away' | 'online' | 'offline' | 'none' | 'mention' | 'all';
|
||||
type PushStatus = 'away' | 'online' | 'offline' | 'none' | 'mention' | 'all' | 'ooo' | 'dnd' | 'default' ;
|
||||
|
||||
Reference in New Issue
Block a user