Merge branch 'develop' into pinned
This commit is contained in:
commit
9f813c1803
|
@ -96,5 +96,6 @@ export const VIDEO_CONF = createRequestTypes('VIDEO_CONF', [
|
||||||
'ACCEPT_CALL',
|
'ACCEPT_CALL',
|
||||||
'SET_CALLING'
|
'SET_CALLING'
|
||||||
]);
|
]);
|
||||||
|
export const TROUBLESHOOTING_NOTIFICATION = createRequestTypes('TROUBLESHOOTING_NOTIFICATION', ['INIT', 'SET']);
|
||||||
export const SUPPORTED_VERSIONS = createRequestTypes('SUPPORTED_VERSIONS', ['SET']);
|
export const SUPPORTED_VERSIONS = createRequestTypes('SUPPORTED_VERSIONS', ['SET']);
|
||||||
export const IN_APP_FEEDBACK = createRequestTypes('IN_APP_FEEDBACK', ['SET', 'REMOVE', 'CLEAR']);
|
export const IN_APP_FEEDBACK = createRequestTypes('IN_APP_FEEDBACK', ['SET', 'REMOVE', 'CLEAR']);
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
import { Action } from 'redux';
|
||||||
|
|
||||||
|
import { TROUBLESHOOTING_NOTIFICATION } from './actionsTypes';
|
||||||
|
import { ITroubleshootingNotification } from '../reducers/troubleshootingNotification';
|
||||||
|
|
||||||
|
type TSetTroubleshootingNotification = Action & { payload: Partial<ITroubleshootingNotification> };
|
||||||
|
|
||||||
|
export type TActionTroubleshootingNotification = Action & TSetTroubleshootingNotification;
|
||||||
|
|
||||||
|
export function initTroubleshootingNotification(): Action {
|
||||||
|
return {
|
||||||
|
type: TROUBLESHOOTING_NOTIFICATION.INIT
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function setTroubleshootingNotification(payload: Partial<ITroubleshootingNotification>): TSetTroubleshootingNotification {
|
||||||
|
return {
|
||||||
|
type: TROUBLESHOOTING_NOTIFICATION.SET,
|
||||||
|
payload
|
||||||
|
};
|
||||||
|
}
|
|
@ -36,7 +36,7 @@ export const VideoConferenceBaseContainer = ({ variant, children }: VideoConfMes
|
||||||
},
|
},
|
||||||
issue: {
|
issue: {
|
||||||
icon: 'phone-issue',
|
icon: 'phone-issue',
|
||||||
color: colors.statusFontOnWarning,
|
color: colors.statusFontWarning,
|
||||||
backgroundColor: colors.statusBackgroundWarning,
|
backgroundColor: colors.statusBackgroundWarning,
|
||||||
label: i18n.t('Call_issue')
|
label: i18n.t('Call_issue')
|
||||||
}
|
}
|
||||||
|
|
|
@ -110,6 +110,7 @@ export interface ISubscription {
|
||||||
threads: RelationModified<TThreadModel>;
|
threads: RelationModified<TThreadModel>;
|
||||||
threadMessages: RelationModified<TThreadMessageModel>;
|
threadMessages: RelationModified<TThreadMessageModel>;
|
||||||
uploads: RelationModified<TUploadModel>;
|
uploads: RelationModified<TUploadModel>;
|
||||||
|
disableNotifications?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type TSubscriptionModel = ISubscription &
|
export type TSubscriptionModel = ISubscription &
|
||||||
|
|
|
@ -40,6 +40,8 @@ import { IEnterpriseModules } from '../../reducers/enterpriseModules';
|
||||||
import { IVideoConf } from '../../reducers/videoConf';
|
import { IVideoConf } from '../../reducers/videoConf';
|
||||||
import { TActionUsersRoles } from '../../actions/usersRoles';
|
import { TActionUsersRoles } from '../../actions/usersRoles';
|
||||||
import { TUsersRoles } from '../../reducers/usersRoles';
|
import { TUsersRoles } from '../../reducers/usersRoles';
|
||||||
|
import { ITroubleshootingNotification } from '../../reducers/troubleshootingNotification';
|
||||||
|
import { TActionTroubleshootingNotification } from '../../actions/troubleshootingNotification';
|
||||||
import { ISupportedVersionsState } from '../../reducers/supportedVersions';
|
import { ISupportedVersionsState } from '../../reducers/supportedVersions';
|
||||||
import { IInAppFeedbackState } from '../../reducers/inAppFeedback';
|
import { IInAppFeedbackState } from '../../reducers/inAppFeedback';
|
||||||
|
|
||||||
|
@ -67,6 +69,7 @@ export interface IApplicationState {
|
||||||
roles: IRoles;
|
roles: IRoles;
|
||||||
videoConf: IVideoConf;
|
videoConf: IVideoConf;
|
||||||
usersRoles: TUsersRoles;
|
usersRoles: TUsersRoles;
|
||||||
|
troubleshootingNotification: ITroubleshootingNotification;
|
||||||
supportedVersions: ISupportedVersionsState;
|
supportedVersions: ISupportedVersionsState;
|
||||||
inAppFeedback: IInAppFeedbackState;
|
inAppFeedback: IInAppFeedbackState;
|
||||||
}
|
}
|
||||||
|
@ -90,5 +93,6 @@ export type TApplicationActions = TActionActiveUsers &
|
||||||
TActionEnterpriseModules &
|
TActionEnterpriseModules &
|
||||||
TActionVideoConf &
|
TActionVideoConf &
|
||||||
TActionUsersRoles &
|
TActionUsersRoles &
|
||||||
|
TActionTroubleshootingNotification &
|
||||||
TActionSupportedVersions &
|
TActionSupportedVersions &
|
||||||
TInAppFeedbackAction;
|
TInAppFeedbackAction;
|
||||||
|
|
|
@ -17,7 +17,7 @@ import { E2eEndpoints } from './e2e';
|
||||||
import { SubscriptionsEndpoints } from './subscriptions';
|
import { SubscriptionsEndpoints } from './subscriptions';
|
||||||
import { VideoConferenceEndpoints } from './videoConference';
|
import { VideoConferenceEndpoints } from './videoConference';
|
||||||
import { CommandsEndpoints } from './commands';
|
import { CommandsEndpoints } from './commands';
|
||||||
import { PushTokenEndpoints } from './pushToken';
|
import { PushEndpoints } from './push';
|
||||||
import { DirectoryEndpoint } from './directory';
|
import { DirectoryEndpoint } from './directory';
|
||||||
import { AutoTranslateEndpoints } from './autotranslate';
|
import { AutoTranslateEndpoints } from './autotranslate';
|
||||||
import { ModerationEndpoints } from './moderation';
|
import { ModerationEndpoints } from './moderation';
|
||||||
|
@ -41,7 +41,7 @@ export type Endpoints = ChannelsEndpoints &
|
||||||
SubscriptionsEndpoints &
|
SubscriptionsEndpoints &
|
||||||
VideoConferenceEndpoints &
|
VideoConferenceEndpoints &
|
||||||
CommandsEndpoints &
|
CommandsEndpoints &
|
||||||
PushTokenEndpoints &
|
PushEndpoints &
|
||||||
DirectoryEndpoint &
|
DirectoryEndpoint &
|
||||||
AutoTranslateEndpoints &
|
AutoTranslateEndpoints &
|
||||||
ModerationEndpoints;
|
ModerationEndpoints;
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
type TPushInfo = {
|
||||||
|
pushGatewayEnabled: boolean;
|
||||||
|
defaultPushGateway: boolean;
|
||||||
|
success: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type PushEndpoints = {
|
||||||
|
'push.token': {
|
||||||
|
POST: (params: { value: string; type: string; appName: string }) => {
|
||||||
|
result: {
|
||||||
|
id: string;
|
||||||
|
token: string;
|
||||||
|
appName: string;
|
||||||
|
userId: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
'push.info': {
|
||||||
|
GET: () => TPushInfo;
|
||||||
|
};
|
||||||
|
'push.test': {
|
||||||
|
POST: () => { tokensCount: number };
|
||||||
|
};
|
||||||
|
};
|
|
@ -1,12 +0,0 @@
|
||||||
export type PushTokenEndpoints = {
|
|
||||||
'push.token': {
|
|
||||||
POST: (params: { value: string; type: string; appName: string }) => {
|
|
||||||
result: {
|
|
||||||
id: string;
|
|
||||||
token: string;
|
|
||||||
appName: string;
|
|
||||||
userId: string;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
|
@ -24,6 +24,7 @@
|
||||||
"All_users_in_the_channel_can_write_new_messages": "All users in the channel can write new messages",
|
"All_users_in_the_channel_can_write_new_messages": "All users in the channel can write new messages",
|
||||||
"All_users_in_the_team_can_write_new_messages": "All users in the team can write new messages",
|
"All_users_in_the_team_can_write_new_messages": "All users in the team can write new messages",
|
||||||
"Allow_Reactions": "Allow reactions",
|
"Allow_Reactions": "Allow reactions",
|
||||||
|
"Allow_push_notifications_for_rocket_chat": "Allow push notifications for Rocket.Chat",
|
||||||
"Also_send_thread_message_to_channel_behavior": "Also send thread message to channel",
|
"Also_send_thread_message_to_channel_behavior": "Also send thread message to channel",
|
||||||
"Announcement": "Announcement",
|
"Announcement": "Announcement",
|
||||||
"App_users_are_not_allowed_to_log_in_directly": "App users are not allowed to log in directly.",
|
"App_users_are_not_allowed_to_log_in_directly": "App users are not allowed to log in directly.",
|
||||||
|
@ -102,6 +103,7 @@
|
||||||
"Code_block": "Code block",
|
"Code_block": "Code block",
|
||||||
"Code_or_password_invalid": "Code or password invalid",
|
"Code_or_password_invalid": "Code or password invalid",
|
||||||
"Collaborative": "Collaborative",
|
"Collaborative": "Collaborative",
|
||||||
|
"Community_edition_push_quota": "Community push quota",
|
||||||
"Condensed": "Condensed",
|
"Condensed": "Condensed",
|
||||||
"Confirm": "Confirm",
|
"Confirm": "Confirm",
|
||||||
"Confirmation": "Confirmation",
|
"Confirmation": "Confirmation",
|
||||||
|
@ -134,6 +136,8 @@
|
||||||
"Create_a_new_workspace": "Create a new workspace",
|
"Create_a_new_workspace": "Create a new workspace",
|
||||||
"Create_account": "Create an account",
|
"Create_account": "Create an account",
|
||||||
"Created_snippet": "created a snippet",
|
"Created_snippet": "created a snippet",
|
||||||
|
"Custom_push_gateway_connected_description": "Your workspace uses a custom push notification gateway. Check with your workspace administrator for any issues.",
|
||||||
|
"Custom_push_gateway_connection": "Custom gateway connection",
|
||||||
"DELETE": "DELETE",
|
"DELETE": "DELETE",
|
||||||
"Dark": "Dark",
|
"Dark": "Dark",
|
||||||
"Dark_level": "Dark level",
|
"Dark_level": "Dark level",
|
||||||
|
@ -156,6 +160,9 @@
|
||||||
"Description": "Description",
|
"Description": "Description",
|
||||||
"Desktop_Alert_info": "These notifications are delivered in desktop",
|
"Desktop_Alert_info": "These notifications are delivered in desktop",
|
||||||
"Desktop_Notifications": "Desktop notifications",
|
"Desktop_Notifications": "Desktop notifications",
|
||||||
|
"Device_notification_settings": "Device notification settings",
|
||||||
|
"Device_notifications_alert_description": "Please go to your settings app and enable notifications for Rocket.Chat",
|
||||||
|
"Device_notifications_alert_title": "Notifications disabled",
|
||||||
"Direct_Messages": "Direct messages",
|
"Direct_Messages": "Direct messages",
|
||||||
"Direct_message": "Direct message",
|
"Direct_message": "Direct message",
|
||||||
"Direct_message_someone": "Direct message someone",
|
"Direct_message_someone": "Direct message someone",
|
||||||
|
@ -174,6 +181,7 @@
|
||||||
"Do_you_have_a_certificate": "Do you have a certificate?",
|
"Do_you_have_a_certificate": "Do you have a certificate?",
|
||||||
"Do_you_have_an_account": "Do you have an account?",
|
"Do_you_have_an_account": "Do you have an account?",
|
||||||
"Do_you_really_want_to_key_this_room_question_mark": "Do you really want to {{key}} this room?",
|
"Do_you_really_want_to_key_this_room_question_mark": "Do you really want to {{key}} this room?",
|
||||||
|
"Documentation": "Documentation",
|
||||||
"Dont_Have_An_Account": "Don't you have an account?",
|
"Dont_Have_An_Account": "Don't you have an account?",
|
||||||
"Dont_activate": "Don't activate now",
|
"Dont_activate": "Don't activate now",
|
||||||
"Downloaded_file": "Downloaded file",
|
"Downloaded_file": "Downloaded file",
|
||||||
|
@ -387,6 +395,7 @@
|
||||||
"No_channels_in_team": "No Channels on this team",
|
"No_channels_in_team": "No Channels on this team",
|
||||||
"No_discussions": "No discussions",
|
"No_discussions": "No discussions",
|
||||||
"No_files": "No files",
|
"No_files": "No files",
|
||||||
|
"No_further_action_is_needed": "No further action is needed",
|
||||||
"No_label_provided": "No {{label}} provided.",
|
"No_label_provided": "No {{label}} provided.",
|
||||||
"No_limit": "No limit",
|
"No_limit": "No limit",
|
||||||
"No_match_found": "No match found.",
|
"No_match_found": "No match found.",
|
||||||
|
@ -404,6 +413,8 @@
|
||||||
"Nothing": "Nothing",
|
"Nothing": "Nothing",
|
||||||
"Nothing_to_save": "Nothing to save!",
|
"Nothing_to_save": "Nothing to save!",
|
||||||
"Notification_Preferences": "Notification preferences",
|
"Notification_Preferences": "Notification preferences",
|
||||||
|
"Notification_delay": "Notification delay",
|
||||||
|
"Notification_delay_description": "There are factors that can contribute to delayed notifications. Learn more in Rocket.Chat's docs.",
|
||||||
"Notifications": "Notifications",
|
"Notifications": "Notifications",
|
||||||
"Notify_active_in_this_room": "Notify active users in this room",
|
"Notify_active_in_this_room": "Notify active users in this room",
|
||||||
"Notify_all_in_this_room": "Notify all in this room",
|
"Notify_all_in_this_room": "Notify all in this room",
|
||||||
|
@ -461,6 +472,10 @@
|
||||||
"Public": "Public",
|
"Public": "Public",
|
||||||
"Push_Notifications": "Push notifications",
|
"Push_Notifications": "Push notifications",
|
||||||
"Push_Notifications_Alert_Info": "These notifications are delivered to you when the app is not open",
|
"Push_Notifications_Alert_Info": "These notifications are delivered to you when the app is not open",
|
||||||
|
"Push_Troubleshooting": "Push Troubleshooting",
|
||||||
|
"Push_gateway_connected_description": "Send a push notification to yourself to check if the gateway is working",
|
||||||
|
"Push_gateway_connection": "Push gateway connection",
|
||||||
|
"Push_gateway_not_connected_description": "We're not able to connect to the push gateway. If this issue persists please check with your workspace administrator.",
|
||||||
"Queued_chats": "Queued chats",
|
"Queued_chats": "Queued chats",
|
||||||
"Quote": "Quote",
|
"Quote": "Quote",
|
||||||
"RESET": "RESET",
|
"RESET": "RESET",
|
||||||
|
@ -605,6 +620,7 @@
|
||||||
"Team_not_found": "Team not found",
|
"Team_not_found": "Team not found",
|
||||||
"Teams": "Teams",
|
"Teams": "Teams",
|
||||||
"Terms_of_Service": " Terms of service ",
|
"Terms_of_Service": " Terms of service ",
|
||||||
|
"Test_push_notification": "Test push notification",
|
||||||
"The_maximum_number_of_users_has_been_reached": "The maximum number of users has been reached.",
|
"The_maximum_number_of_users_has_been_reached": "The maximum number of users has been reached.",
|
||||||
"The_room_does_not_exist": "The room does not exist or you may not have access permission",
|
"The_room_does_not_exist": "The room does not exist or you may not have access permission",
|
||||||
"The_user_will_be_able_to_type_in_roomName": "The user will be able to type in {{roomName}}",
|
"The_user_will_be_able_to_type_in_roomName": "The user will be able to type in {{roomName}}",
|
||||||
|
@ -625,6 +641,7 @@
|
||||||
"Token_expired": "Your session has expired. Please log in again.",
|
"Token_expired": "Your session has expired. Please log in again.",
|
||||||
"Topic": "Topic",
|
"Topic": "Topic",
|
||||||
"Translate": "Translate",
|
"Translate": "Translate",
|
||||||
|
"Troubleshooting": "Troubleshooting",
|
||||||
"Try_again": "Try again",
|
"Try_again": "Try again",
|
||||||
"Two_Factor_Authentication": "Two-factor authentication",
|
"Two_Factor_Authentication": "Two-factor authentication",
|
||||||
"Type_message": "Type message",
|
"Type_message": "Type message",
|
||||||
|
@ -690,6 +707,8 @@
|
||||||
"Wi_Fi_and_mobile_data": "Wi-Fi and mobile data",
|
"Wi_Fi_and_mobile_data": "Wi-Fi and mobile data",
|
||||||
"Without_Servers": "Without workspaces",
|
"Without_Servers": "Without workspaces",
|
||||||
"Workspace_URL_Example": "Ex. your-company.rocket.chat",
|
"Workspace_URL_Example": "Ex. your-company.rocket.chat",
|
||||||
|
"Workspace_consumption": "Workspace consumption",
|
||||||
|
"Workspace_consumption_description": "There’s a set amount of push notifications per month",
|
||||||
"Workspaces": "Workspaces",
|
"Workspaces": "Workspaces",
|
||||||
"Would_like_to_place_on_hold": "Would you like to place this chat on hold?",
|
"Would_like_to_place_on_hold": "Would you like to place this chat on hold?",
|
||||||
"Would_you_like_to_return_the_inquiry": "Would you like to return the inquiry?",
|
"Would_you_like_to_return_the_inquiry": "Would you like to return the inquiry?",
|
||||||
|
@ -720,6 +739,7 @@
|
||||||
"Your_invite_link_will_expire_on__date__or_after__usesLeft__uses": "Your invite link will expire on {{date}} or after {{usesLeft}} uses.",
|
"Your_invite_link_will_expire_on__date__or_after__usesLeft__uses": "Your invite link will expire on {{date}} or after {{usesLeft}} uses.",
|
||||||
"Your_invite_link_will_never_expire": "Your invite link will never expire.",
|
"Your_invite_link_will_never_expire": "Your invite link will never expire.",
|
||||||
"Your_password_is": "Your password is",
|
"Your_password_is": "Your password is",
|
||||||
|
"Your_push_was_sent_to_s_devices": "Your push was sent to {{s}} devices",
|
||||||
"Your_workspace": "Your workspace",
|
"Your_workspace": "Your workspace",
|
||||||
"__count__empty_room_will_be_removed_automatically": "{{count}} empty room will be deleted.",
|
"__count__empty_room_will_be_removed_automatically": "{{count}} empty room will be deleted.",
|
||||||
"__count__empty_rooms_will_be_removed_automatically": "{{count}} empty rooms will be deleted.",
|
"__count__empty_rooms_will_be_removed_automatically": "{{count}} empty rooms will be deleted.",
|
||||||
|
@ -761,6 +781,7 @@
|
||||||
"error-invalid-file-type": "Invalid file type",
|
"error-invalid-file-type": "Invalid file type",
|
||||||
"error-invalid-password": "Invalid password",
|
"error-invalid-password": "Invalid password",
|
||||||
"error-invalid-room-name": "{{room_name}} is not a valid room name",
|
"error-invalid-room-name": "{{room_name}} is not a valid room name",
|
||||||
|
"error-no-tokens-for-this-user": "There are no tokens for this user",
|
||||||
"error-not-allowed": "Not allowed",
|
"error-not-allowed": "Not allowed",
|
||||||
"error-not-permission-to-upload-file": "You don't have permission to upload files",
|
"error-not-permission-to-upload-file": "You don't have permission to upload files",
|
||||||
"error-save-image": "Error while saving image",
|
"error-save-image": "Error while saving image",
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
"All_users_in_the_channel_can_write_new_messages": "Todos usuários no canal podem enviar mensagens novas",
|
"All_users_in_the_channel_can_write_new_messages": "Todos usuários no canal podem enviar mensagens novas",
|
||||||
"All_users_in_the_team_can_write_new_messages": "Todos usuários no canal podem enviar mensagens novas",
|
"All_users_in_the_team_can_write_new_messages": "Todos usuários no canal podem enviar mensagens novas",
|
||||||
"Allow_Reactions": "Permitir reagir",
|
"Allow_Reactions": "Permitir reagir",
|
||||||
|
"Allow_push_notifications_for_rocket_chat": "Permitir notificações push para Rocket.Chat",
|
||||||
"Also_send_thread_message_to_channel_behavior": "Também enviar mensagem do tópico para o canal",
|
"Also_send_thread_message_to_channel_behavior": "Também enviar mensagem do tópico para o canal",
|
||||||
"Announcement": "Anúncio",
|
"Announcement": "Anúncio",
|
||||||
"App_users_are_not_allowed_to_log_in_directly": "Usuários do aplicativo não estão autorizados a fazer login diretamente.",
|
"App_users_are_not_allowed_to_log_in_directly": "Usuários do aplicativo não estão autorizados a fazer login diretamente.",
|
||||||
|
@ -55,7 +56,7 @@
|
||||||
"Call_issue": "Chamada com problemas",
|
"Call_issue": "Chamada com problemas",
|
||||||
"Call_ongoing": "Chamada em andamento",
|
"Call_ongoing": "Chamada em andamento",
|
||||||
"Call_rejected": "Chamada rejeitada",
|
"Call_rejected": "Chamada rejeitada",
|
||||||
"Call_started": "Chamada iniciada",
|
"Call_started": "Chamada Iniciada",
|
||||||
"Call_was_not_answered": "A chamada não foi atendida",
|
"Call_was_not_answered": "A chamada não foi atendida",
|
||||||
"Calling": "Chamando",
|
"Calling": "Chamando",
|
||||||
"Cancel": "Cancelar",
|
"Cancel": "Cancelar",
|
||||||
|
@ -99,6 +100,7 @@
|
||||||
"Close_emoji_selector": "Fechar seletor de emojis",
|
"Close_emoji_selector": "Fechar seletor de emojis",
|
||||||
"Code_or_password_invalid": "Código ou senha inválido",
|
"Code_or_password_invalid": "Código ou senha inválido",
|
||||||
"Collaborative": "Colaborativo",
|
"Collaborative": "Colaborativo",
|
||||||
|
"Community_edition_push_quota": "Cota de notificações push community edition",
|
||||||
"Condensed": "Condensado",
|
"Condensed": "Condensado",
|
||||||
"Confirm": "Confirmar",
|
"Confirm": "Confirmar",
|
||||||
"Confirmation": "Confirmação",
|
"Confirmation": "Confirmação",
|
||||||
|
@ -131,6 +133,8 @@
|
||||||
"Create_a_new_workspace": "Criar nova área de trabalho",
|
"Create_a_new_workspace": "Criar nova área de trabalho",
|
||||||
"Create_account": "Criar conta",
|
"Create_account": "Criar conta",
|
||||||
"Created_snippet": "criou um snippet",
|
"Created_snippet": "criou um snippet",
|
||||||
|
"Custom_push_gateway_connected_description": "Seu workspace utiliza um gateway de notificação push personalizado. Verifique com o administrador do seu workspace se há algum problema.",
|
||||||
|
"Custom_push_gateway_connection": "Conexão personalizada com o gateway",
|
||||||
"DELETE": "EXCLUIR",
|
"DELETE": "EXCLUIR",
|
||||||
"Dark": "Escuro",
|
"Dark": "Escuro",
|
||||||
"Dark_level": "Nível escuro",
|
"Dark_level": "Nível escuro",
|
||||||
|
@ -153,6 +157,9 @@
|
||||||
"Description": "Descrição",
|
"Description": "Descrição",
|
||||||
"Desktop_Alert_info": "Essas notificações são entregues a você na área de trabalho",
|
"Desktop_Alert_info": "Essas notificações são entregues a você na área de trabalho",
|
||||||
"Desktop_Notifications": "Notificações da área de trabalho",
|
"Desktop_Notifications": "Notificações da área de trabalho",
|
||||||
|
"Device_notification_settings": "Configurações de notificações do dispositivo",
|
||||||
|
"Device_notifications_alert_description": "Por favor, vá para o aplicativo de configurações e habilite as notificações para o Rocket.Chat.",
|
||||||
|
"Device_notifications_alert_title": "Notificações desativadas",
|
||||||
"Direct_Messages": "Mensagens diretas",
|
"Direct_Messages": "Mensagens diretas",
|
||||||
"Direct_message": "Mensagem direta",
|
"Direct_message": "Mensagem direta",
|
||||||
"Direct_message_someone": "Enviar mensagem direta para alguém",
|
"Direct_message_someone": "Enviar mensagem direta para alguém",
|
||||||
|
@ -171,6 +178,7 @@
|
||||||
"Do_you_have_a_certificate": "Você tem um certificado?",
|
"Do_you_have_a_certificate": "Você tem um certificado?",
|
||||||
"Do_you_have_an_account": "Você tem uma conta?",
|
"Do_you_have_an_account": "Você tem uma conta?",
|
||||||
"Do_you_really_want_to_key_this_room_question_mark": "Você quer realmente {{key}} esta sala?",
|
"Do_you_really_want_to_key_this_room_question_mark": "Você quer realmente {{key}} esta sala?",
|
||||||
|
"Documentation": "Documentação",
|
||||||
"Dont_Have_An_Account": "Não tem uma conta?",
|
"Dont_Have_An_Account": "Não tem uma conta?",
|
||||||
"Dont_activate": "Não ativar agora",
|
"Dont_activate": "Não ativar agora",
|
||||||
"Downloaded_file": "Arquivo baixado",
|
"Downloaded_file": "Arquivo baixado",
|
||||||
|
@ -267,6 +275,7 @@
|
||||||
"Jitsi_authentication_before_making_calls_admin": "Jitsi pode exigir autenticação antes de fazer chamadas. Para saber mais sobre as políticas deles, visite o site do Jitsi. Você também pode atualizar o aplicativo padrão para chamadas de vídeo nas preferências.",
|
"Jitsi_authentication_before_making_calls_admin": "Jitsi pode exigir autenticação antes de fazer chamadas. Para saber mais sobre as políticas deles, visite o site do Jitsi. Você também pode atualizar o aplicativo padrão para chamadas de vídeo nas preferências.",
|
||||||
"Jitsi_authentication_before_making_calls_ask_admin": "Se você acredita que há problemas com o Jitsi e sua autenticação, peça ajuda a um administrador do espaço de trabalho.",
|
"Jitsi_authentication_before_making_calls_ask_admin": "Se você acredita que há problemas com o Jitsi e sua autenticação, peça ajuda a um administrador do espaço de trabalho.",
|
||||||
"Jitsi_may_require_authentication": "O Jitsi pode exigir autenticação",
|
"Jitsi_may_require_authentication": "O Jitsi pode exigir autenticação",
|
||||||
|
"Jitsi_may_requires_authentication": "Jitsi pode exigir autenticação",
|
||||||
"Join": "Entrar",
|
"Join": "Entrar",
|
||||||
"Join_Code": "Insira o código da sala",
|
"Join_Code": "Insira o código da sala",
|
||||||
"Join_our_open_workspace": "Entrar na nossa workspace pública",
|
"Join_our_open_workspace": "Entrar na nossa workspace pública",
|
||||||
|
@ -381,6 +390,7 @@
|
||||||
"No_channels_in_team": "Nenhum canal nesta equipe",
|
"No_channels_in_team": "Nenhum canal nesta equipe",
|
||||||
"No_discussions": "Sem discussões",
|
"No_discussions": "Sem discussões",
|
||||||
"No_files": "Não há arquivos",
|
"No_files": "Não há arquivos",
|
||||||
|
"No_further_action_is_needed": "Nenhuma ação adicional é necessária",
|
||||||
"No_label_provided": "Sem {{label}}.",
|
"No_label_provided": "Sem {{label}}.",
|
||||||
"No_limit": "Sem limite",
|
"No_limit": "Sem limite",
|
||||||
"No_match_found": "Nenhum resultado encontrado.",
|
"No_match_found": "Nenhum resultado encontrado.",
|
||||||
|
@ -397,6 +407,8 @@
|
||||||
"Nothing": "Nada",
|
"Nothing": "Nada",
|
||||||
"Nothing_to_save": "Nada para salvar!",
|
"Nothing_to_save": "Nada para salvar!",
|
||||||
"Notification_Preferences": "Preferências de notificação",
|
"Notification_Preferences": "Preferências de notificação",
|
||||||
|
"Notification_delay": "Atraso de notificação",
|
||||||
|
"Notification_delay_description": "Existem fatores que podem contribuir para atrasos nas notificações. Saiba mais na documentação do Rocket.Chat.",
|
||||||
"Notifications": "Notificações",
|
"Notifications": "Notificações",
|
||||||
"Notify_active_in_this_room": "Notificar usuários ativos nesta sala",
|
"Notify_active_in_this_room": "Notificar usuários ativos nesta sala",
|
||||||
"Notify_all_in_this_room": "Notificar todos nesta sala",
|
"Notify_all_in_this_room": "Notificar todos nesta sala",
|
||||||
|
@ -452,6 +464,10 @@
|
||||||
"Public": "Público",
|
"Public": "Público",
|
||||||
"Push_Notifications": "Notificações push",
|
"Push_Notifications": "Notificações push",
|
||||||
"Push_Notifications_Alert_Info": "Essas notificações são entregues a você quando o aplicativo não está aberto",
|
"Push_Notifications_Alert_Info": "Essas notificações são entregues a você quando o aplicativo não está aberto",
|
||||||
|
"Push_Troubleshooting": "Solucionar Problemas de Push",
|
||||||
|
"Push_gateway_connected_description": "Envie uma notificação push para si mesmo para verificar se o gateway está funcionando.",
|
||||||
|
"Push_gateway_connection": "Conexão com o gateway de push",
|
||||||
|
"Push_gateway_not_connected_description": "Não conseguimos conectar ao gateway de push. Se esse problema persistir, por favor, verifique com o administrador do seu workspace.",
|
||||||
"Queued_chats": "Bate-papos na fila",
|
"Queued_chats": "Bate-papos na fila",
|
||||||
"Quote": "Citar",
|
"Quote": "Citar",
|
||||||
"RESET": "RESETAR",
|
"RESET": "RESETAR",
|
||||||
|
@ -593,6 +609,7 @@
|
||||||
"Team_not_found": "Time não encontrado",
|
"Team_not_found": "Time não encontrado",
|
||||||
"Teams": "Times",
|
"Teams": "Times",
|
||||||
"Terms_of_Service": " Termos de serviço ",
|
"Terms_of_Service": " Termos de serviço ",
|
||||||
|
"Test_push_notification": "Testar notificação push",
|
||||||
"The_maximum_number_of_users_has_been_reached": "O número máximo de usuários foi atingido.",
|
"The_maximum_number_of_users_has_been_reached": "O número máximo de usuários foi atingido.",
|
||||||
"The_room_does_not_exist": "A sala não existe ou você pode não ter permissão de acesso",
|
"The_room_does_not_exist": "A sala não existe ou você pode não ter permissão de acesso",
|
||||||
"The_user_will_be_able_to_type_in_roomName": "O usuário poderá digitar em {{roomName}}",
|
"The_user_will_be_able_to_type_in_roomName": "O usuário poderá digitar em {{roomName}}",
|
||||||
|
@ -678,6 +695,8 @@
|
||||||
"Wi_Fi_and_mobile_data": "Wi-Fi e dados móveis",
|
"Wi_Fi_and_mobile_data": "Wi-Fi e dados móveis",
|
||||||
"Without_Servers": "Sem workspaces",
|
"Without_Servers": "Sem workspaces",
|
||||||
"Workspace_URL_Example": "Ex. sua-empresa.rocket.chat",
|
"Workspace_URL_Example": "Ex. sua-empresa.rocket.chat",
|
||||||
|
"Workspace_consumption": "Consumo do workspace",
|
||||||
|
"Workspace_consumption_description": "Existe uma quantidade definida de notificações push por mês",
|
||||||
"Workspaces": "Workspaces",
|
"Workspaces": "Workspaces",
|
||||||
"Would_like_to_place_on_hold": "Gostaria de colocar essa conversa em espera?",
|
"Would_like_to_place_on_hold": "Gostaria de colocar essa conversa em espera?",
|
||||||
"Would_you_like_to_return_the_inquiry": "Deseja retornar a consulta?",
|
"Would_you_like_to_return_the_inquiry": "Deseja retornar a consulta?",
|
||||||
|
@ -708,6 +727,7 @@
|
||||||
"Your_invite_link_will_expire_on__date__or_after__usesLeft__uses": "Seu link de convite irá vencer em {{date}} ou depois de {{usesLeft}} usos.",
|
"Your_invite_link_will_expire_on__date__or_after__usesLeft__uses": "Seu link de convite irá vencer em {{date}} ou depois de {{usesLeft}} usos.",
|
||||||
"Your_invite_link_will_never_expire": "Seu link de convite nunca irá vencer.",
|
"Your_invite_link_will_never_expire": "Seu link de convite nunca irá vencer.",
|
||||||
"Your_password_is": "Sua senha é",
|
"Your_password_is": "Sua senha é",
|
||||||
|
"Your_push_was_sent_to_s_devices": "A sua notificação foi enviada para {{s}} dispositivos",
|
||||||
"Your_workspace": "Sua workspace",
|
"Your_workspace": "Sua workspace",
|
||||||
"__count__empty_room_will_be_removed_automatically": "{{count}} sala vazia será excluída.",
|
"__count__empty_room_will_be_removed_automatically": "{{count}} sala vazia será excluída.",
|
||||||
"__count__empty_rooms_will_be_removed_automatically": "{{count}} salas vazias serão excluídas.",
|
"__count__empty_rooms_will_be_removed_automatically": "{{count}} salas vazias serão excluídas.",
|
||||||
|
@ -749,6 +769,7 @@
|
||||||
"error-invalid-file-type": "Tipo de arquivo inválido",
|
"error-invalid-file-type": "Tipo de arquivo inválido",
|
||||||
"error-invalid-password": "Senha inválida",
|
"error-invalid-password": "Senha inválida",
|
||||||
"error-invalid-room-name": "{{room_name}} não é um nome de sala válido",
|
"error-invalid-room-name": "{{room_name}} não é um nome de sala válido",
|
||||||
|
"error-no-tokens-for-this-user": "Não existem tokens para este usuário",
|
||||||
"error-not-allowed": "Não permitido",
|
"error-not-allowed": "Não permitido",
|
||||||
"error-not-permission-to-upload-file": "Você não tem permissão para enviar arquivos",
|
"error-not-permission-to-upload-file": "Você não tem permissão para enviar arquivos",
|
||||||
"error-save-image": "Erro ao salvar imagem",
|
"error-save-image": "Erro ao salvar imagem",
|
||||||
|
|
|
@ -287,7 +287,6 @@ export const colors = {
|
||||||
gray100: '#CBCED1',
|
gray100: '#CBCED1',
|
||||||
n900: '#1F2329',
|
n900: '#1F2329',
|
||||||
statusBackgroundWarning: '#FFECAD',
|
statusBackgroundWarning: '#FFECAD',
|
||||||
statusFontOnWarning: '#B88D00',
|
|
||||||
overlayColor: '#1F2329CC',
|
overlayColor: '#1F2329CC',
|
||||||
taskBoxColor: '#9297a2',
|
taskBoxColor: '#9297a2',
|
||||||
...mentions,
|
...mentions,
|
||||||
|
@ -369,7 +368,6 @@ export const colors = {
|
||||||
gray100: '#CBCED1',
|
gray100: '#CBCED1',
|
||||||
n900: '#FFFFFF',
|
n900: '#FFFFFF',
|
||||||
statusBackgroundWarning: '#FFECAD',
|
statusBackgroundWarning: '#FFECAD',
|
||||||
statusFontOnWarning: '#B88D00',
|
|
||||||
overlayColor: '#1F2329CC',
|
overlayColor: '#1F2329CC',
|
||||||
taskBoxColor: '#9297a2',
|
taskBoxColor: '#9297a2',
|
||||||
...mentions,
|
...mentions,
|
||||||
|
@ -451,7 +449,6 @@ export const colors = {
|
||||||
gray100: '#CBCED1',
|
gray100: '#CBCED1',
|
||||||
n900: '#FFFFFF',
|
n900: '#FFFFFF',
|
||||||
statusBackgroundWarning: '#FFECAD',
|
statusBackgroundWarning: '#FFECAD',
|
||||||
statusFontOnWarning: '#B88D00',
|
|
||||||
overlayColor: '#1F2329CC',
|
overlayColor: '#1F2329CC',
|
||||||
taskBoxColor: '#9297a2',
|
taskBoxColor: '#9297a2',
|
||||||
...mentions,
|
...mentions,
|
||||||
|
|
|
@ -145,6 +145,8 @@ export default class Subscription extends Model {
|
||||||
|
|
||||||
@json('source', sanitizer) source;
|
@json('source', sanitizer) source;
|
||||||
|
|
||||||
|
@field('disable_notifications') disableNotifications;
|
||||||
|
|
||||||
asPlain() {
|
asPlain() {
|
||||||
return {
|
return {
|
||||||
_id: this._id,
|
_id: this._id,
|
||||||
|
@ -207,7 +209,8 @@ export default class Subscription extends Model {
|
||||||
teamMain: this.teamMain,
|
teamMain: this.teamMain,
|
||||||
onHold: this.onHold,
|
onHold: this.onHold,
|
||||||
usersCount: this.usersCount,
|
usersCount: this.usersCount,
|
||||||
source: this.source
|
source: this.source,
|
||||||
|
disableNotifications: this.disableNotifications
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -284,6 +284,15 @@ export default schemaMigrations({
|
||||||
columns: [{ name: 'unmuted', type: 'string', isOptional: true }]
|
columns: [{ name: 'unmuted', type: 'string', isOptional: true }]
|
||||||
})
|
})
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
toVersion: 24,
|
||||||
|
steps: [
|
||||||
|
addColumns({
|
||||||
|
table: 'subscriptions',
|
||||||
|
columns: [{ name: 'disable_notifications', type: 'boolean', isOptional: true }]
|
||||||
|
})
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { appSchema, tableSchema } from '@nozbe/watermelondb';
|
import { appSchema, tableSchema } from '@nozbe/watermelondb';
|
||||||
|
|
||||||
export default appSchema({
|
export default appSchema({
|
||||||
version: 23,
|
version: 24,
|
||||||
tables: [
|
tables: [
|
||||||
tableSchema({
|
tableSchema({
|
||||||
name: 'subscriptions',
|
name: 'subscriptions',
|
||||||
|
@ -66,7 +66,8 @@ export default appSchema({
|
||||||
{ name: 'source', type: 'string', isOptional: true },
|
{ name: 'source', type: 'string', isOptional: true },
|
||||||
{ name: 'hide_mention_status', type: 'boolean', isOptional: true },
|
{ name: 'hide_mention_status', type: 'boolean', isOptional: true },
|
||||||
{ name: 'users_count', type: 'number', isOptional: true },
|
{ name: 'users_count', type: 'number', isOptional: true },
|
||||||
{ name: 'unmuted', type: 'string', isOptional: true }
|
{ name: 'unmuted', type: 'string', isOptional: true },
|
||||||
|
{ name: 'disable_notifications', type: 'boolean', isOptional: true }
|
||||||
]
|
]
|
||||||
}),
|
}),
|
||||||
tableSchema({
|
tableSchema({
|
||||||
|
|
|
@ -60,7 +60,8 @@ export const SUPPORTED_PERMISSIONS = [
|
||||||
'view-canned-responses',
|
'view-canned-responses',
|
||||||
'mobile-upload-file',
|
'mobile-upload-file',
|
||||||
'delete-own-message',
|
'delete-own-message',
|
||||||
'call-management'
|
'call-management',
|
||||||
|
'test-push-notifications'
|
||||||
] as const;
|
] as const;
|
||||||
|
|
||||||
export async function setPermissions(): Promise<void> {
|
export async function setPermissions(): Promise<void> {
|
||||||
|
|
|
@ -5,12 +5,17 @@ import I18n from '../../../i18n';
|
||||||
export const showErrorAlert = (message: string, title?: string, onPress = () => {}): void =>
|
export const showErrorAlert = (message: string, title?: string, onPress = () => {}): void =>
|
||||||
Alert.alert(title || '', message, [{ text: 'OK', onPress }], { cancelable: true });
|
Alert.alert(title || '', message, [{ text: 'OK', onPress }], { cancelable: true });
|
||||||
|
|
||||||
export const showErrorAlertWithEMessage = (e: any): void => {
|
export const showErrorAlertWithEMessage = (e: any, title?: string): void => {
|
||||||
const messageError =
|
let errorMessage: string = e?.data?.error;
|
||||||
e.data && e.data.error.includes('[error-too-many-requests]')
|
|
||||||
? I18n.t('error-too-many-requests', { seconds: e.data.error.replace(/\D/g, '') })
|
if (errorMessage.includes('[error-too-many-requests]')) {
|
||||||
: e.data.errorType;
|
const seconds = errorMessage.replace(/\D/g, '');
|
||||||
showErrorAlert(messageError);
|
errorMessage = I18n.t('error-too-many-requests', { seconds });
|
||||||
|
} else {
|
||||||
|
errorMessage = I18n.isTranslated(errorMessage) ? I18n.t(errorMessage) : errorMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
showErrorAlert(errorMessage, title);
|
||||||
};
|
};
|
||||||
|
|
||||||
interface IShowConfirmationAlert {
|
interface IShowConfirmationAlert {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import EJSON from 'ejson';
|
import EJSON from 'ejson';
|
||||||
|
|
||||||
|
import { appInit } from '../../actions/app';
|
||||||
import { deepLinkingClickCallPush, deepLinkingOpen } from '../../actions/deepLinking';
|
import { deepLinkingClickCallPush, deepLinkingOpen } from '../../actions/deepLinking';
|
||||||
import { INotification, SubscriptionType } from '../../definitions';
|
import { INotification, SubscriptionType } from '../../definitions';
|
||||||
import { isFDroidBuild } from '../constants';
|
import { isFDroidBuild } from '../constants';
|
||||||
|
@ -18,39 +19,43 @@ interface IEjson {
|
||||||
export const onNotification = (push: INotification): void => {
|
export const onNotification = (push: INotification): void => {
|
||||||
const identifier = String(push?.payload?.action?.identifier);
|
const identifier = String(push?.payload?.action?.identifier);
|
||||||
if (identifier === 'ACCEPT_ACTION' || identifier === 'DECLINE_ACTION') {
|
if (identifier === 'ACCEPT_ACTION' || identifier === 'DECLINE_ACTION') {
|
||||||
if (push.payload) {
|
if (push?.payload && push?.payload?.ejson) {
|
||||||
const notification = EJSON.parse(push.payload.ejson);
|
const notification = EJSON.parse(push?.payload?.ejson);
|
||||||
store.dispatch(deepLinkingClickCallPush({ ...notification, event: identifier === 'ACCEPT_ACTION' ? 'accept' : 'decline' }));
|
store.dispatch(deepLinkingClickCallPush({ ...notification, event: identifier === 'ACCEPT_ACTION' ? 'accept' : 'decline' }));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (push.payload) {
|
if (push?.payload) {
|
||||||
try {
|
try {
|
||||||
const notification = push.payload;
|
const notification = push?.payload;
|
||||||
const { rid, name, sender, type, host, messageId }: IEjson = EJSON.parse(notification.ejson);
|
if (notification.ejson) {
|
||||||
|
const { rid, name, sender, type, host, messageId }: IEjson = EJSON.parse(notification.ejson);
|
||||||
|
|
||||||
const types: Record<string, string> = {
|
const types: Record<string, string> = {
|
||||||
c: 'channel',
|
c: 'channel',
|
||||||
d: 'direct',
|
d: 'direct',
|
||||||
p: 'group',
|
p: 'group',
|
||||||
l: 'channels'
|
l: 'channels'
|
||||||
};
|
};
|
||||||
let roomName = type === SubscriptionType.DIRECT ? sender.username : name;
|
let roomName = type === SubscriptionType.DIRECT ? sender.username : name;
|
||||||
if (type === SubscriptionType.OMNICHANNEL) {
|
if (type === SubscriptionType.OMNICHANNEL) {
|
||||||
roomName = sender.name;
|
roomName = sender.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
const params = {
|
||||||
|
host,
|
||||||
|
rid,
|
||||||
|
messageId,
|
||||||
|
path: `${types[type]}/${roomName}`
|
||||||
|
};
|
||||||
|
store.dispatch(deepLinkingOpen(params));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const params = {
|
|
||||||
host,
|
|
||||||
rid,
|
|
||||||
messageId,
|
|
||||||
path: `${types[type]}/${roomName}`
|
|
||||||
};
|
|
||||||
store.dispatch(deepLinkingOpen(params));
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn(e);
|
console.warn(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
store.dispatch(appInit());
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getDeviceToken = (): string => deviceToken;
|
export const getDeviceToken = (): string => deviceToken;
|
||||||
|
|
|
@ -105,13 +105,15 @@ const displayVideoConferenceNotification = async (notification: NotificationData
|
||||||
const setBackgroundNotificationHandler = () => {
|
const setBackgroundNotificationHandler = () => {
|
||||||
createChannel();
|
createChannel();
|
||||||
messaging().setBackgroundMessageHandler(async message => {
|
messaging().setBackgroundMessageHandler(async message => {
|
||||||
const notification: NotificationData = ejson.parse(message?.data?.ejson as string);
|
if (message?.data?.ejson) {
|
||||||
if (notification?.notificationType === VIDEO_CONF_TYPE) {
|
const notification: NotificationData = ejson.parse(message?.data?.ejson as string);
|
||||||
if (notification.status === 0) {
|
if (notification?.notificationType === VIDEO_CONF_TYPE) {
|
||||||
await displayVideoConferenceNotification(notification);
|
if (notification.status === 0) {
|
||||||
} else if (notification.status === 4) {
|
await displayVideoConferenceNotification(notification);
|
||||||
const id = `${notification.rid}${notification.caller?._id}`.replace(/[^A-Za-z0-9]/g, '');
|
} else if (notification.status === 4) {
|
||||||
await notifee.cancelNotification(id);
|
const id = `${notification.rid}${notification.caller?._id}`.replace(/[^A-Za-z0-9]/g, '');
|
||||||
|
await notifee.cancelNotification(id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -905,6 +905,12 @@ export const removePushToken = (): Promise<boolean | void> => {
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// RC 6.6.0
|
||||||
|
export const pushTest = () => sdk.post('push.test');
|
||||||
|
|
||||||
|
// RC 6.5.0
|
||||||
|
export const pushInfo = () => sdk.get('push.info');
|
||||||
|
|
||||||
export const sendEmailCode = () => {
|
export const sendEmailCode = () => {
|
||||||
const { username } = reduxStore.getState().login.user as IUser;
|
const { username } = reduxStore.getState().login.user as IUser;
|
||||||
// RC 3.1.0
|
// RC 3.1.0
|
||||||
|
|
|
@ -23,6 +23,7 @@ import permissions from './permissions';
|
||||||
import roles from './roles';
|
import roles from './roles';
|
||||||
import videoConf from './videoConf';
|
import videoConf from './videoConf';
|
||||||
import usersRoles from './usersRoles';
|
import usersRoles from './usersRoles';
|
||||||
|
import troubleshootingNotification from './troubleshootingNotification';
|
||||||
import supportedVersions from './supportedVersions';
|
import supportedVersions from './supportedVersions';
|
||||||
import inAppFeedback from './inAppFeedback';
|
import inAppFeedback from './inAppFeedback';
|
||||||
|
|
||||||
|
@ -50,6 +51,7 @@ export default combineReducers({
|
||||||
roles,
|
roles,
|
||||||
videoConf,
|
videoConf,
|
||||||
usersRoles,
|
usersRoles,
|
||||||
|
troubleshootingNotification,
|
||||||
supportedVersions,
|
supportedVersions,
|
||||||
inAppFeedback
|
inAppFeedback
|
||||||
});
|
});
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
import { setTroubleshootingNotification, initTroubleshootingNotification } from '../actions/troubleshootingNotification';
|
||||||
|
import { mockedStore } from './mockedStore';
|
||||||
|
import { ITroubleshootingNotification, initialState } from './troubleshootingNotification';
|
||||||
|
|
||||||
|
describe('test troubleshootingNotification reducer', () => {
|
||||||
|
it('should return initial state', () => {
|
||||||
|
const state = mockedStore.getState().troubleshootingNotification;
|
||||||
|
expect(state).toEqual(initialState);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return correctly the value after call initTroubleshootingNotification action', () => {
|
||||||
|
mockedStore.dispatch(initTroubleshootingNotification());
|
||||||
|
const state = mockedStore.getState().troubleshootingNotification;
|
||||||
|
expect(state).toEqual(initialState);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return correctly value after call troubleshootingNotification action', () => {
|
||||||
|
const payload: ITroubleshootingNotification = {
|
||||||
|
deviceNotificationEnabled: true,
|
||||||
|
issuesWithNotifications: false,
|
||||||
|
defaultPushGateway: true,
|
||||||
|
pushGatewayEnabled: true,
|
||||||
|
consumptionPercentage: 0,
|
||||||
|
isCommunityEdition: false
|
||||||
|
};
|
||||||
|
mockedStore.dispatch(setTroubleshootingNotification(payload));
|
||||||
|
const state = mockedStore.getState().troubleshootingNotification;
|
||||||
|
expect(state).toEqual(payload);
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,32 @@
|
||||||
|
import { TROUBLESHOOTING_NOTIFICATION } from '../actions/actionsTypes';
|
||||||
|
import { TActionTroubleshootingNotification } from '../actions/troubleshootingNotification';
|
||||||
|
|
||||||
|
export interface ITroubleshootingNotification {
|
||||||
|
deviceNotificationEnabled: boolean;
|
||||||
|
pushGatewayEnabled: boolean;
|
||||||
|
defaultPushGateway: boolean;
|
||||||
|
issuesWithNotifications: boolean;
|
||||||
|
consumptionPercentage: number;
|
||||||
|
isCommunityEdition: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const initialState: ITroubleshootingNotification = {
|
||||||
|
deviceNotificationEnabled: false,
|
||||||
|
pushGatewayEnabled: false,
|
||||||
|
defaultPushGateway: false,
|
||||||
|
issuesWithNotifications: false,
|
||||||
|
consumptionPercentage: 0,
|
||||||
|
isCommunityEdition: false
|
||||||
|
};
|
||||||
|
|
||||||
|
export default (state = initialState, action: TActionTroubleshootingNotification): ITroubleshootingNotification => {
|
||||||
|
switch (action.type) {
|
||||||
|
case TROUBLESHOOTING_NOTIFICATION.SET:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
...action.payload
|
||||||
|
};
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
};
|
|
@ -14,6 +14,7 @@ import inviteLinks from './inviteLinks';
|
||||||
import createDiscussion from './createDiscussion';
|
import createDiscussion from './createDiscussion';
|
||||||
import encryption from './encryption';
|
import encryption from './encryption';
|
||||||
import videoConf from './videoConf';
|
import videoConf from './videoConf';
|
||||||
|
import troubleshootingNotification from './troubleshootingNotification';
|
||||||
|
|
||||||
const root = function* root() {
|
const root = function* root() {
|
||||||
yield all([
|
yield all([
|
||||||
|
@ -30,7 +31,8 @@ const root = function* root() {
|
||||||
createDiscussion(),
|
createDiscussion(),
|
||||||
inquiry(),
|
inquiry(),
|
||||||
encryption(),
|
encryption(),
|
||||||
videoConf()
|
videoConf(),
|
||||||
|
troubleshootingNotification()
|
||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ import { inviteLinksRequest } from '../actions/inviteLinks';
|
||||||
import { showErrorAlert } from '../lib/methods/helpers/info';
|
import { showErrorAlert } from '../lib/methods/helpers/info';
|
||||||
import { localAuthenticate } from '../lib/methods/helpers/localAuthentication';
|
import { localAuthenticate } from '../lib/methods/helpers/localAuthentication';
|
||||||
import { encryptionInit, encryptionStop } from '../actions/encryption';
|
import { encryptionInit, encryptionStop } from '../actions/encryption';
|
||||||
|
import { initTroubleshootingNotification } from '../actions/troubleshootingNotification';
|
||||||
import UserPreferences from '../lib/methods/userPreferences';
|
import UserPreferences from '../lib/methods/userPreferences';
|
||||||
import { inquiryRequest, inquiryReset } from '../ee/omnichannel/actions/inquiry';
|
import { inquiryRequest, inquiryReset } from '../ee/omnichannel/actions/inquiry';
|
||||||
import { isOmnichannelStatusAvailable } from '../ee/omnichannel/lib';
|
import { isOmnichannelStatusAvailable } from '../ee/omnichannel/lib';
|
||||||
|
@ -236,6 +237,7 @@ const handleLoginSuccess = function* handleLoginSuccess({ user }) {
|
||||||
yield put(inviteLinksRequest(inviteLinkToken));
|
yield put(inviteLinksRequest(inviteLinkToken));
|
||||||
}
|
}
|
||||||
yield showSupportedVersionsWarning(server);
|
yield showSupportedVersionsWarning(server);
|
||||||
|
yield put(initTroubleshootingNotification());
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log(e);
|
log(e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
import { Action } from 'redux';
|
||||||
|
import { call, takeLatest, put } from 'typed-redux-saga';
|
||||||
|
import notifee, { AuthorizationStatus } from '@notifee/react-native';
|
||||||
|
|
||||||
|
import { TROUBLESHOOTING_NOTIFICATION } from '../actions/actionsTypes';
|
||||||
|
import { setTroubleshootingNotification } from '../actions/troubleshootingNotification';
|
||||||
|
import { pushInfo } from '../lib/services/restApi';
|
||||||
|
import log from '../lib/methods/helpers/log';
|
||||||
|
import { appSelector } from '../lib/hooks';
|
||||||
|
import { compareServerVersion } from '../lib/methods/helpers';
|
||||||
|
|
||||||
|
interface IGenericAction extends Action {
|
||||||
|
type: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
function* init() {
|
||||||
|
const serverVersion = yield* appSelector(state => state.server.version);
|
||||||
|
let deviceNotificationEnabled = false;
|
||||||
|
let defaultPushGateway = false;
|
||||||
|
let pushGatewayEnabled = false;
|
||||||
|
try {
|
||||||
|
const { authorizationStatus } = yield* call(notifee.getNotificationSettings);
|
||||||
|
deviceNotificationEnabled = authorizationStatus > AuthorizationStatus.DENIED;
|
||||||
|
} catch (e) {
|
||||||
|
log(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (compareServerVersion(serverVersion, 'greaterThanOrEqualTo', '6.5.0')) {
|
||||||
|
const pushInfoResult = yield* call(pushInfo);
|
||||||
|
if (pushInfoResult.success) {
|
||||||
|
pushGatewayEnabled = pushInfoResult.pushGatewayEnabled;
|
||||||
|
defaultPushGateway = pushInfoResult.defaultPushGateway;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
log(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
const issuesWithNotifications =
|
||||||
|
!deviceNotificationEnabled || (compareServerVersion(serverVersion, 'greaterThanOrEqualTo', '6.6.0') && !pushGatewayEnabled);
|
||||||
|
yield put(
|
||||||
|
setTroubleshootingNotification({
|
||||||
|
deviceNotificationEnabled,
|
||||||
|
defaultPushGateway,
|
||||||
|
pushGatewayEnabled,
|
||||||
|
issuesWithNotifications
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function* root(): Generator {
|
||||||
|
yield takeLatest<IGenericAction>(TROUBLESHOOTING_NOTIFICATION.INIT, init);
|
||||||
|
}
|
|
@ -42,6 +42,7 @@ import DisplayPrefsView from '../views/DisplayPrefsView';
|
||||||
// Settings Stack
|
// Settings Stack
|
||||||
import SettingsView from '../views/SettingsView';
|
import SettingsView from '../views/SettingsView';
|
||||||
import SecurityPrivacyView from '../views/SecurityPrivacyView';
|
import SecurityPrivacyView from '../views/SecurityPrivacyView';
|
||||||
|
import PushTroubleshootView from '../views/PushTroubleshootView';
|
||||||
import E2EEncryptionSecurityView from '../views/E2EEncryptionSecurityView';
|
import E2EEncryptionSecurityView from '../views/E2EEncryptionSecurityView';
|
||||||
import LanguageView from '../views/LanguageView';
|
import LanguageView from '../views/LanguageView';
|
||||||
import ThemeView from '../views/ThemeView';
|
import ThemeView from '../views/ThemeView';
|
||||||
|
@ -118,6 +119,7 @@ const ChatsStackNavigator = () => {
|
||||||
<ChatsStack.Screen name='AutoTranslateView' component={AutoTranslateView} />
|
<ChatsStack.Screen name='AutoTranslateView' component={AutoTranslateView} />
|
||||||
<ChatsStack.Screen name='DirectoryView' component={DirectoryView} options={DirectoryView.navigationOptions} />
|
<ChatsStack.Screen name='DirectoryView' component={DirectoryView} options={DirectoryView.navigationOptions} />
|
||||||
<ChatsStack.Screen name='NotificationPrefView' component={NotificationPrefView} />
|
<ChatsStack.Screen name='NotificationPrefView' component={NotificationPrefView} />
|
||||||
|
<ChatsStack.Screen name='PushTroubleshootView' component={PushTroubleshootView} />
|
||||||
<ChatsStack.Screen name='ForwardLivechatView' component={ForwardLivechatView} />
|
<ChatsStack.Screen name='ForwardLivechatView' component={ForwardLivechatView} />
|
||||||
<ChatsStack.Screen name='CloseLivechatView' component={CloseLivechatView} />
|
<ChatsStack.Screen name='CloseLivechatView' component={CloseLivechatView} />
|
||||||
<ChatsStack.Screen name='LivechatEditView' component={LivechatEditView} options={LivechatEditView.navigationOptions} />
|
<ChatsStack.Screen name='LivechatEditView' component={LivechatEditView} options={LivechatEditView.navigationOptions} />
|
||||||
|
@ -155,6 +157,7 @@ const ProfileStackNavigator = () => {
|
||||||
<ProfileStack.Screen name='UserPreferencesView' component={UserPreferencesView} />
|
<ProfileStack.Screen name='UserPreferencesView' component={UserPreferencesView} />
|
||||||
<ProfileStack.Screen name='ChangeAvatarView' component={ChangeAvatarView} />
|
<ProfileStack.Screen name='ChangeAvatarView' component={ChangeAvatarView} />
|
||||||
<ProfileStack.Screen name='UserNotificationPrefView' component={UserNotificationPrefView} />
|
<ProfileStack.Screen name='UserNotificationPrefView' component={UserNotificationPrefView} />
|
||||||
|
<ProfileStack.Screen name='PushTroubleshootView' component={PushTroubleshootView} />
|
||||||
<ProfileStack.Screen name='PickerView' component={PickerView} />
|
<ProfileStack.Screen name='PickerView' component={PickerView} />
|
||||||
</ProfileStack.Navigator>
|
</ProfileStack.Navigator>
|
||||||
);
|
);
|
||||||
|
@ -171,6 +174,7 @@ const SettingsStackNavigator = () => {
|
||||||
>
|
>
|
||||||
<SettingsStack.Screen name='SettingsView' component={SettingsView} />
|
<SettingsStack.Screen name='SettingsView' component={SettingsView} />
|
||||||
<SettingsStack.Screen name='SecurityPrivacyView' component={SecurityPrivacyView} />
|
<SettingsStack.Screen name='SecurityPrivacyView' component={SecurityPrivacyView} />
|
||||||
|
<SettingsStack.Screen name='PushTroubleshootView' component={PushTroubleshootView} />
|
||||||
<SettingsStack.Screen name='E2EEncryptionSecurityView' component={E2EEncryptionSecurityView} />
|
<SettingsStack.Screen name='E2EEncryptionSecurityView' component={E2EEncryptionSecurityView} />
|
||||||
<SettingsStack.Screen name='LanguageView' component={LanguageView} />
|
<SettingsStack.Screen name='LanguageView' component={LanguageView} />
|
||||||
<SettingsStack.Screen name='ThemeView' component={ThemeView} />
|
<SettingsStack.Screen name='ThemeView' component={ThemeView} />
|
||||||
|
|
|
@ -27,6 +27,7 @@ import MessagesView from '../../views/MessagesView';
|
||||||
import AutoTranslateView from '../../views/AutoTranslateView';
|
import AutoTranslateView from '../../views/AutoTranslateView';
|
||||||
import DirectoryView from '../../views/DirectoryView';
|
import DirectoryView from '../../views/DirectoryView';
|
||||||
import NotificationPrefView from '../../views/NotificationPreferencesView';
|
import NotificationPrefView from '../../views/NotificationPreferencesView';
|
||||||
|
import PushTroubleshootView from '../../views/PushTroubleshootView';
|
||||||
import ForwardLivechatView from '../../views/ForwardLivechatView';
|
import ForwardLivechatView from '../../views/ForwardLivechatView';
|
||||||
import ForwardMessageView from '../../views/ForwardMessageView';
|
import ForwardMessageView from '../../views/ForwardMessageView';
|
||||||
import CloseLivechatView from '../../views/CloseLivechatView';
|
import CloseLivechatView from '../../views/CloseLivechatView';
|
||||||
|
@ -187,6 +188,7 @@ const ModalStackNavigator = React.memo(({ navigation }: INavigation) => {
|
||||||
<ModalStack.Screen name='SecurityPrivacyView' component={SecurityPrivacyView} />
|
<ModalStack.Screen name='SecurityPrivacyView' component={SecurityPrivacyView} />
|
||||||
<ModalStack.Screen name='MediaAutoDownloadView' component={MediaAutoDownloadView} />
|
<ModalStack.Screen name='MediaAutoDownloadView' component={MediaAutoDownloadView} />
|
||||||
<ModalStack.Screen name='E2EEncryptionSecurityView' component={E2EEncryptionSecurityView} />
|
<ModalStack.Screen name='E2EEncryptionSecurityView' component={E2EEncryptionSecurityView} />
|
||||||
|
<ModalStack.Screen name='PushTroubleshootView' component={PushTroubleshootView} />
|
||||||
<ModalStack.Screen name='SupportedVersionsWarning' component={SupportedVersionsWarning} />
|
<ModalStack.Screen name='SupportedVersionsWarning' component={SupportedVersionsWarning} />
|
||||||
</ModalStack.Navigator>
|
</ModalStack.Navigator>
|
||||||
</ModalContainer>
|
</ModalContainer>
|
||||||
|
|
|
@ -196,6 +196,7 @@ export type ModalStackParamList = {
|
||||||
SecurityPrivacyView: undefined;
|
SecurityPrivacyView: undefined;
|
||||||
MediaAutoDownloadView: undefined;
|
MediaAutoDownloadView: undefined;
|
||||||
E2EEncryptionSecurityView: undefined;
|
E2EEncryptionSecurityView: undefined;
|
||||||
|
PushTroubleshootView: undefined;
|
||||||
SupportedVersionsWarning: {
|
SupportedVersionsWarning: {
|
||||||
showCloseButton?: boolean;
|
showCloseButton?: boolean;
|
||||||
};
|
};
|
||||||
|
|
|
@ -122,6 +122,7 @@ export type ChatsStackParamList = {
|
||||||
rid: string;
|
rid: string;
|
||||||
room: TSubscriptionModel;
|
room: TSubscriptionModel;
|
||||||
};
|
};
|
||||||
|
PushTroubleshootView: undefined;
|
||||||
CloseLivechatView: {
|
CloseLivechatView: {
|
||||||
rid: string;
|
rid: string;
|
||||||
departmentId?: string;
|
departmentId?: string;
|
||||||
|
@ -188,6 +189,7 @@ export type ProfileStackParamList = {
|
||||||
ProfileView: undefined;
|
ProfileView: undefined;
|
||||||
UserPreferencesView: undefined;
|
UserPreferencesView: undefined;
|
||||||
UserNotificationPrefView: undefined;
|
UserNotificationPrefView: undefined;
|
||||||
|
PushTroubleshootView: undefined;
|
||||||
ChangeAvatarView: {
|
ChangeAvatarView: {
|
||||||
context: TChangeAvatarViewContext;
|
context: TChangeAvatarViewContext;
|
||||||
titleHeader?: string;
|
titleHeader?: string;
|
||||||
|
@ -207,6 +209,7 @@ export type SettingsStackParamList = {
|
||||||
ProfileView: undefined;
|
ProfileView: undefined;
|
||||||
DisplayPrefsView: undefined;
|
DisplayPrefsView: undefined;
|
||||||
MediaAutoDownloadView: undefined;
|
MediaAutoDownloadView: undefined;
|
||||||
|
PushTroubleshootView: undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type AdminPanelStackParamList = {
|
export type AdminPanelStackParamList = {
|
||||||
|
|
|
@ -26,10 +26,12 @@ const LOGIN_SUBMIT_ERRORS = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const handleLoginErrors = (error: keyof typeof LOGIN_SUBMIT_ERRORS): string => {
|
export const handleLoginErrors = (error: keyof typeof LOGIN_SUBMIT_ERRORS): string => {
|
||||||
const errorKey = Object.keys(LOGIN_SUBMIT_ERRORS).find(key => error.includes(key)) as keyof typeof LOGIN_SUBMIT_ERRORS;
|
if (typeof error === 'string') {
|
||||||
const e = errorKey ? LOGIN_SUBMIT_ERRORS[errorKey].i18n : 'Login_error';
|
const errorKey = Object.keys(LOGIN_SUBMIT_ERRORS).find(key => error?.includes(key)) as keyof typeof LOGIN_SUBMIT_ERRORS;
|
||||||
if (i18n.isTranslated(e)) {
|
const e = errorKey ? LOGIN_SUBMIT_ERRORS[errorKey]?.i18n : 'Login_error';
|
||||||
return i18n.t(e);
|
if (i18n.isTranslated(e)) {
|
||||||
|
return i18n.t(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return i18n.t('Login_error');
|
return i18n.t('Login_error');
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { RouteProp, useNavigation, useRoute } from '@react-navigation/core';
|
import { RouteProp, useNavigation, useRoute } from '@react-navigation/core';
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { Switch, Text } from 'react-native';
|
import { Switch, Text } from 'react-native';
|
||||||
|
import { StackNavigationProp } from '@react-navigation/stack';
|
||||||
|
|
||||||
import { TActionSheetOptionsItem, useActionSheet } from '../../containers/ActionSheet';
|
import { TActionSheetOptionsItem, useActionSheet } from '../../containers/ActionSheet';
|
||||||
import { CustomIcon } from '../../containers/CustomIcon';
|
import { CustomIcon } from '../../containers/CustomIcon';
|
||||||
|
@ -91,8 +92,11 @@ const RenderSwitch = ({ preference, room, onChangeValue }: IBaseParams) => {
|
||||||
const NotificationPreferencesView = (): React.ReactElement => {
|
const NotificationPreferencesView = (): React.ReactElement => {
|
||||||
const route = useRoute<RouteProp<ChatsStackParamList, 'NotificationPrefView'>>();
|
const route = useRoute<RouteProp<ChatsStackParamList, 'NotificationPrefView'>>();
|
||||||
const { rid, room } = route.params;
|
const { rid, room } = route.params;
|
||||||
const navigation = useNavigation();
|
const navigation = useNavigation<StackNavigationProp<ChatsStackParamList, 'NotificationPrefView'>>();
|
||||||
const serverVersion = useAppSelector(state => state.server.version);
|
const { serverVersion, isMasterDetail } = useAppSelector(state => ({
|
||||||
|
serverVersion: state.server.version,
|
||||||
|
isMasterDetail: state.app.isMasterDetail
|
||||||
|
}));
|
||||||
const [hideUnreadStatus, setHideUnreadStatus] = useState(room.hideUnreadStatus);
|
const [hideUnreadStatus, setHideUnreadStatus] = useState(room.hideUnreadStatus);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -108,6 +112,14 @@ const NotificationPreferencesView = (): React.ReactElement => {
|
||||||
});
|
});
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const navigateToPushTroubleshootView = () => {
|
||||||
|
if (isMasterDetail) {
|
||||||
|
navigation.navigate('ModalStackNavigator', { screen: 'PushTroubleshootView' });
|
||||||
|
} else {
|
||||||
|
navigation.navigate('PushTroubleshootView');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const saveNotificationSettings = async (key: TUnionOptionsRoomNotifications, params: IRoomNotifications, onError: Function) => {
|
const saveNotificationSettings = async (key: TUnionOptionsRoomNotifications, params: IRoomNotifications, onError: Function) => {
|
||||||
try {
|
try {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
|
@ -202,6 +214,13 @@ const NotificationPreferencesView = (): React.ReactElement => {
|
||||||
onChangeValue={saveNotificationSettings}
|
onChangeValue={saveNotificationSettings}
|
||||||
/>
|
/>
|
||||||
<List.Separator />
|
<List.Separator />
|
||||||
|
<List.Item
|
||||||
|
title='Troubleshooting'
|
||||||
|
onPress={navigateToPushTroubleshootView}
|
||||||
|
testID='notification-preference-view-troubleshooting'
|
||||||
|
showActionIndicator
|
||||||
|
/>
|
||||||
|
<List.Separator />
|
||||||
<List.Info info='Push_Notifications_Alert_Info' />
|
<List.Info info='Push_Notifications_Alert_Info' />
|
||||||
</List.Section>
|
</List.Section>
|
||||||
<List.Section title='Email'>
|
<List.Section title='Email'>
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { Alert, StyleSheet, Text } from 'react-native';
|
||||||
|
|
||||||
|
import * as List from '../../../containers/List';
|
||||||
|
import i18n from '../../../i18n';
|
||||||
|
import { useAppSelector } from '../../../lib/hooks';
|
||||||
|
import { useTheme } from '../../../theme';
|
||||||
|
import sharedStyles from '../../Styles';
|
||||||
|
|
||||||
|
const WARNING_MINIMUM_VALUE = 70;
|
||||||
|
const WARNING_MAXIMUM_VALUE = 90;
|
||||||
|
|
||||||
|
export default function CommunityEditionPushQuota(): React.ReactElement | null {
|
||||||
|
const { colors } = useTheme();
|
||||||
|
const { consumptionPercentage, isCommunityEdition } = useAppSelector(state => ({
|
||||||
|
isCommunityEdition: state.troubleshootingNotification.isCommunityEdition,
|
||||||
|
consumptionPercentage: state.troubleshootingNotification.consumptionPercentage
|
||||||
|
}));
|
||||||
|
|
||||||
|
if (!isCommunityEdition) return null;
|
||||||
|
|
||||||
|
const percentage = `${Math.floor(consumptionPercentage)}%`;
|
||||||
|
|
||||||
|
let percentageColor = colors.statusFontSuccess;
|
||||||
|
if (consumptionPercentage > WARNING_MINIMUM_VALUE && consumptionPercentage < WARNING_MAXIMUM_VALUE) {
|
||||||
|
percentageColor = colors.statusFontWarning;
|
||||||
|
}
|
||||||
|
if (consumptionPercentage >= WARNING_MAXIMUM_VALUE) {
|
||||||
|
percentageColor = colors.statusFontDanger;
|
||||||
|
}
|
||||||
|
|
||||||
|
const alertWorkspaceConsumption = () => {
|
||||||
|
Alert.alert(i18n.t('Push_consumption_alert_title'), i18n.t('Push_consumption_alert_description'));
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<List.Section title='Community_edition_push_quota'>
|
||||||
|
<List.Separator />
|
||||||
|
<List.Item
|
||||||
|
title='Workspace_consumption'
|
||||||
|
testID='push-troubleshoot-view-workspace-consumption'
|
||||||
|
onPress={alertWorkspaceConsumption}
|
||||||
|
right={() => <Text style={[styles.pickerText, { color: percentageColor }]}>{percentage}</Text>}
|
||||||
|
/>
|
||||||
|
<List.Separator />
|
||||||
|
<List.Info info='Workspace_consumption_description' />
|
||||||
|
</List.Section>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
pickerText: {
|
||||||
|
...sharedStyles.textRegular,
|
||||||
|
fontSize: 16
|
||||||
|
}
|
||||||
|
});
|
|
@ -0,0 +1,52 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { StyleSheet, View } from 'react-native';
|
||||||
|
|
||||||
|
import { Header } from '../../../containers/List';
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
marginBottom: 16
|
||||||
|
},
|
||||||
|
headerContainer: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
alignItems: 'center'
|
||||||
|
},
|
||||||
|
statusContainer: {
|
||||||
|
width: 10,
|
||||||
|
height: 10,
|
||||||
|
borderRadius: 5,
|
||||||
|
marginRight: 12
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
interface ICustomListSection {
|
||||||
|
children: (React.ReactElement | null)[] | React.ReactElement | null;
|
||||||
|
title: string;
|
||||||
|
translateTitle?: boolean;
|
||||||
|
statusColor?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CustomHeader = ({
|
||||||
|
title,
|
||||||
|
translateTitle,
|
||||||
|
statusColor
|
||||||
|
}: {
|
||||||
|
title: string;
|
||||||
|
translateTitle?: boolean;
|
||||||
|
statusColor?: string;
|
||||||
|
}) => (
|
||||||
|
<View style={styles.headerContainer}>
|
||||||
|
<Header {...{ title, translateTitle }} />
|
||||||
|
{statusColor ? <View style={[styles.statusContainer, { backgroundColor: statusColor }]} /> : null}
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
|
||||||
|
const CustomListSection = ({ children, title, translateTitle, statusColor }: ICustomListSection) => (
|
||||||
|
<View style={styles.container}>
|
||||||
|
{title ? <CustomHeader {...{ title, translateTitle, statusColor }} /> : null}
|
||||||
|
{children}
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
|
||||||
|
export default CustomListSection;
|
|
@ -0,0 +1,50 @@
|
||||||
|
import notifee from '@notifee/react-native';
|
||||||
|
import React from 'react';
|
||||||
|
import { Linking } from 'react-native';
|
||||||
|
|
||||||
|
import * as List from '../../../containers/List';
|
||||||
|
import i18n from '../../../i18n';
|
||||||
|
import { useAppSelector } from '../../../lib/hooks';
|
||||||
|
import { isIOS, showErrorAlert } from '../../../lib/methods/helpers';
|
||||||
|
import { useTheme } from '../../../theme';
|
||||||
|
import CustomListSection from './CustomListSection';
|
||||||
|
|
||||||
|
export default function DeviceNotificationSettings(): React.ReactElement {
|
||||||
|
const { colors } = useTheme();
|
||||||
|
const { deviceNotificationEnabled } = useAppSelector(state => ({
|
||||||
|
deviceNotificationEnabled: state.troubleshootingNotification.deviceNotificationEnabled
|
||||||
|
}));
|
||||||
|
|
||||||
|
const goToNotificationSettings = () => {
|
||||||
|
if (isIOS) {
|
||||||
|
Linking.openURL('app-settings:');
|
||||||
|
} else {
|
||||||
|
notifee.openNotificationSettings();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const alertDeviceNotificationSettings = () => {
|
||||||
|
if (deviceNotificationEnabled) return;
|
||||||
|
showErrorAlert(
|
||||||
|
i18n.t('Device_notifications_alert_description'),
|
||||||
|
i18n.t('Device_notifications_alert_title'),
|
||||||
|
goToNotificationSettings
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<CustomListSection
|
||||||
|
title='Device_notification_settings'
|
||||||
|
statusColor={!deviceNotificationEnabled ? colors.userPresenceBusy : colors.userPresenceOnline}
|
||||||
|
>
|
||||||
|
<List.Separator />
|
||||||
|
<List.Item
|
||||||
|
title={!deviceNotificationEnabled ? 'Allow_push_notifications_for_rocket_chat' : 'No_further_action_is_needed'}
|
||||||
|
onPress={alertDeviceNotificationSettings}
|
||||||
|
testID='push-troubleshoot-view-allow-push-notifications'
|
||||||
|
disabled={deviceNotificationEnabled}
|
||||||
|
/>
|
||||||
|
<List.Separator />
|
||||||
|
</CustomListSection>
|
||||||
|
);
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { Linking } from 'react-native';
|
||||||
|
|
||||||
|
import * as List from '../../../containers/List';
|
||||||
|
import { useTheme } from '../../../theme';
|
||||||
|
|
||||||
|
export default function NotificationDelay(): React.ReactElement {
|
||||||
|
const { colors } = useTheme();
|
||||||
|
|
||||||
|
const openNotificationDocumentation = () => Linking.openURL('https://go.rocket.chat/i/push-notifications');
|
||||||
|
|
||||||
|
return (
|
||||||
|
<List.Section title='Notification_delay'>
|
||||||
|
<List.Separator />
|
||||||
|
<List.Item
|
||||||
|
title='Documentation'
|
||||||
|
onPress={openNotificationDocumentation}
|
||||||
|
right={() => <List.Icon size={32} name='new-window' color={colors.fontAnnotation} />}
|
||||||
|
testID='push-troubleshoot-view-notification-delay'
|
||||||
|
/>
|
||||||
|
<List.Separator />
|
||||||
|
<List.Info info='Notification_delay_description' />
|
||||||
|
</List.Section>
|
||||||
|
);
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
import React, { useState } from 'react';
|
||||||
|
import { Alert } from 'react-native';
|
||||||
|
|
||||||
|
import * as List from '../../../containers/List';
|
||||||
|
import i18n from '../../../i18n';
|
||||||
|
import { useAppSelector, usePermissions } from '../../../lib/hooks';
|
||||||
|
import { compareServerVersion, showErrorAlertWithEMessage } from '../../../lib/methods/helpers';
|
||||||
|
import { Services } from '../../../lib/services';
|
||||||
|
import { useTheme } from '../../../theme';
|
||||||
|
import CustomListSection from './CustomListSection';
|
||||||
|
|
||||||
|
export default function PushGatewayConnection(): React.ReactElement | null {
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
const { colors } = useTheme();
|
||||||
|
const [testPushNotificationsPermission] = usePermissions(['test-push-notifications']);
|
||||||
|
const { defaultPushGateway, pushGatewayEnabled, serverVersion } = useAppSelector(state => ({
|
||||||
|
pushGatewayEnabled: state.troubleshootingNotification.pushGatewayEnabled,
|
||||||
|
defaultPushGateway: state.troubleshootingNotification.defaultPushGateway,
|
||||||
|
foreground: state.app.foreground,
|
||||||
|
serverVersion: state.server.version
|
||||||
|
}));
|
||||||
|
|
||||||
|
if (!compareServerVersion(serverVersion, 'greaterThanOrEqualTo', '6.6.0')) return null;
|
||||||
|
|
||||||
|
const handleTestPushNotification = async () => {
|
||||||
|
setLoading(true);
|
||||||
|
try {
|
||||||
|
const result = await Services.pushTest();
|
||||||
|
if (result.success) {
|
||||||
|
Alert.alert(i18n.t('Test_push_notification'), i18n.t('Your_push_was_sent_to_s_devices', { s: result.tokensCount }));
|
||||||
|
}
|
||||||
|
} catch (error: any) {
|
||||||
|
showErrorAlertWithEMessage(error, i18n.t('Test_push_notification'));
|
||||||
|
}
|
||||||
|
setLoading(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
let infoColor = 'Push_gateway_not_connected_description';
|
||||||
|
let statusColor = colors.userPresenceBusy;
|
||||||
|
if (pushGatewayEnabled) {
|
||||||
|
statusColor = colors.userPresenceOnline;
|
||||||
|
infoColor = 'Push_gateway_connected_description';
|
||||||
|
}
|
||||||
|
if (pushGatewayEnabled && !defaultPushGateway) {
|
||||||
|
statusColor = colors.badgeBackgroundLevel3;
|
||||||
|
infoColor = 'Custom_push_gateway_connected_description';
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<CustomListSection
|
||||||
|
title={!defaultPushGateway ? 'Custom_push_gateway_connection' : 'Push_gateway_connection'}
|
||||||
|
statusColor={statusColor}
|
||||||
|
>
|
||||||
|
<List.Separator />
|
||||||
|
<List.Item
|
||||||
|
title='Test_push_notification'
|
||||||
|
disabled={!pushGatewayEnabled || !testPushNotificationsPermission || loading}
|
||||||
|
onPress={handleTestPushNotification}
|
||||||
|
testID='push-troubleshoot-view-push-gateway-connection'
|
||||||
|
/>
|
||||||
|
<List.Separator />
|
||||||
|
<List.Info info={infoColor} />
|
||||||
|
</CustomListSection>
|
||||||
|
);
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
import { useFocusEffect } from '@react-navigation/native';
|
||||||
|
import { StackNavigationProp } from '@react-navigation/stack';
|
||||||
|
import React, { useCallback, useEffect } from 'react';
|
||||||
|
import { useDispatch } from 'react-redux';
|
||||||
|
|
||||||
|
import { initTroubleshootingNotification } from '../../actions/troubleshootingNotification';
|
||||||
|
import * as List from '../../containers/List';
|
||||||
|
import SafeAreaView from '../../containers/SafeAreaView';
|
||||||
|
import StatusBar from '../../containers/StatusBar';
|
||||||
|
import I18n from '../../i18n';
|
||||||
|
import { SettingsStackParamList } from '../../stacks/types';
|
||||||
|
// import CommunityEditionPushQuota from './components/CommunityEditionPushQuota';
|
||||||
|
import DeviceNotificationSettings from './components/DeviceNotificationSettings';
|
||||||
|
import NotificationDelay from './components/NotificationDelay';
|
||||||
|
import PushGatewayConnection from './components/PushGatewayConnection';
|
||||||
|
|
||||||
|
interface IPushTroubleshootViewProps {
|
||||||
|
navigation: StackNavigationProp<SettingsStackParamList, 'PushTroubleshootView'>;
|
||||||
|
}
|
||||||
|
|
||||||
|
const PushTroubleshootView = ({ navigation }: IPushTroubleshootViewProps): JSX.Element => {
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
|
useFocusEffect(
|
||||||
|
useCallback(() => {
|
||||||
|
dispatch(initTroubleshootingNotification());
|
||||||
|
}, [])
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
navigation.setOptions({
|
||||||
|
title: I18n.t('Push_Troubleshooting')
|
||||||
|
});
|
||||||
|
}, [navigation]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<SafeAreaView testID='push-troubleshoot-view'>
|
||||||
|
<StatusBar />
|
||||||
|
<List.Container testID='push-troubleshoot-view-list'>
|
||||||
|
<DeviceNotificationSettings />
|
||||||
|
{/* <CommunityEditionPushQuota /> */}
|
||||||
|
<PushGatewayConnection />
|
||||||
|
<NotificationDelay />
|
||||||
|
</List.Container>
|
||||||
|
</SafeAreaView>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default PushTroubleshootView;
|
|
@ -21,6 +21,7 @@ import { getUserSelector } from '../../selectors/login';
|
||||||
import { TNavigation } from '../../stacks/stackType';
|
import { TNavigation } from '../../stacks/stackType';
|
||||||
import { ChatsStackParamList } from '../../stacks/types';
|
import { ChatsStackParamList } from '../../stacks/types';
|
||||||
import HeaderCallButton from './components/HeaderCallButton';
|
import HeaderCallButton from './components/HeaderCallButton';
|
||||||
|
import { TColors, TSupportedThemes, withTheme } from '../../theme';
|
||||||
|
|
||||||
interface IRightButtonsProps extends Pick<ISubscription, 't'> {
|
interface IRightButtonsProps extends Pick<ISubscription, 't'> {
|
||||||
userId?: string;
|
userId?: string;
|
||||||
|
@ -43,6 +44,10 @@ interface IRightButtonsProps extends Pick<ISubscription, 't'> {
|
||||||
showActionSheet: Function;
|
showActionSheet: Function;
|
||||||
departmentId?: string;
|
departmentId?: string;
|
||||||
rid?: string;
|
rid?: string;
|
||||||
|
theme?: TSupportedThemes;
|
||||||
|
colors?: TColors;
|
||||||
|
issuesWithNotifications: boolean;
|
||||||
|
notificationsDisabled?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IRigthButtonsState {
|
interface IRigthButtonsState {
|
||||||
|
@ -55,6 +60,7 @@ interface IRigthButtonsState {
|
||||||
class RightButtonsContainer extends Component<IRightButtonsProps, IRigthButtonsState> {
|
class RightButtonsContainer extends Component<IRightButtonsProps, IRigthButtonsState> {
|
||||||
private threadSubscription?: Subscription;
|
private threadSubscription?: Subscription;
|
||||||
private subSubscription?: Subscription;
|
private subSubscription?: Subscription;
|
||||||
|
private room?: TSubscriptionModel;
|
||||||
|
|
||||||
constructor(props: IRightButtonsProps) {
|
constructor(props: IRightButtonsProps) {
|
||||||
super(props);
|
super(props);
|
||||||
|
@ -80,8 +86,8 @@ class RightButtonsContainer extends Component<IRightButtonsProps, IRigthButtonsS
|
||||||
if (rid) {
|
if (rid) {
|
||||||
try {
|
try {
|
||||||
const subCollection = db.get('subscriptions');
|
const subCollection = db.get('subscriptions');
|
||||||
const subRecord = await subCollection.find(rid);
|
this.room = await subCollection.find(rid);
|
||||||
this.observeSubscription(subRecord);
|
this.observeSubscription(this.room);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log("Can't find subscription to observe.");
|
console.log("Can't find subscription to observe.");
|
||||||
}
|
}
|
||||||
|
@ -90,7 +96,7 @@ class RightButtonsContainer extends Component<IRightButtonsProps, IRigthButtonsS
|
||||||
|
|
||||||
shouldComponentUpdate(nextProps: IRightButtonsProps, nextState: IRigthButtonsState) {
|
shouldComponentUpdate(nextProps: IRightButtonsProps, nextState: IRigthButtonsState) {
|
||||||
const { isFollowingThread, tunread, tunreadUser, tunreadGroup } = this.state;
|
const { isFollowingThread, tunread, tunreadUser, tunreadGroup } = this.state;
|
||||||
const { teamId, status, joined, omnichannelPermissions } = this.props;
|
const { teamId, status, joined, omnichannelPermissions, theme, issuesWithNotifications, notificationsDisabled } = this.props;
|
||||||
if (nextProps.teamId !== teamId) {
|
if (nextProps.teamId !== teamId) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -100,9 +106,18 @@ class RightButtonsContainer extends Component<IRightButtonsProps, IRigthButtonsS
|
||||||
if (nextProps.joined !== joined) {
|
if (nextProps.joined !== joined) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (nextProps.theme !== theme) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if (nextState.isFollowingThread !== isFollowingThread) {
|
if (nextState.isFollowingThread !== isFollowingThread) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (nextProps.issuesWithNotifications !== issuesWithNotifications) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (nextProps.notificationsDisabled !== notificationsDisabled) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if (!dequal(nextProps.omnichannelPermissions, omnichannelPermissions)) {
|
if (!dequal(nextProps.omnichannelPermissions, omnichannelPermissions)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -288,6 +303,31 @@ class RightButtonsContainer extends Component<IRightButtonsProps, IRigthButtonsS
|
||||||
showActionSheet({ options });
|
showActionSheet({ options });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
navigateToNotificationOrPushTroubleshoot = () => {
|
||||||
|
const { room } = this;
|
||||||
|
const { rid, navigation, isMasterDetail, issuesWithNotifications } = this.props;
|
||||||
|
|
||||||
|
if (!rid || !room) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!issuesWithNotifications && room) {
|
||||||
|
if (isMasterDetail) {
|
||||||
|
navigation.navigate('ModalStackNavigator', {
|
||||||
|
screen: 'NotificationPrefView',
|
||||||
|
params: { rid, room }
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
navigation.navigate('NotificationPrefView', { rid, room });
|
||||||
|
}
|
||||||
|
} else if (isMasterDetail) {
|
||||||
|
navigation.navigate('ModalStackNavigator', {
|
||||||
|
screen: 'PushTroubleshootView'
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
navigation.navigate('PushTroubleshootView');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
goSearchView = () => {
|
goSearchView = () => {
|
||||||
logEvent(events.ROOM_GO_SEARCH);
|
logEvent(events.ROOM_GO_SEARCH);
|
||||||
const { rid, t, navigation, isMasterDetail, encrypted } = this.props;
|
const { rid, t, navigation, isMasterDetail, encrypted } = this.props;
|
||||||
|
@ -321,7 +361,7 @@ class RightButtonsContainer extends Component<IRightButtonsProps, IRigthButtonsS
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { isFollowingThread, tunread, tunreadUser, tunreadGroup } = this.state;
|
const { isFollowingThread, tunread, tunreadUser, tunreadGroup } = this.state;
|
||||||
const { t, tmid, threadsEnabled, rid } = this.props;
|
const { t, tmid, threadsEnabled, rid, colors, issuesWithNotifications, notificationsDisabled } = this.props;
|
||||||
|
|
||||||
if (t === 'l') {
|
if (t === 'l') {
|
||||||
if (!this.isOmnichannelPreview()) {
|
if (!this.isOmnichannelPreview()) {
|
||||||
|
@ -346,6 +386,14 @@ class RightButtonsContainer extends Component<IRightButtonsProps, IRigthButtonsS
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<HeaderButton.Container>
|
<HeaderButton.Container>
|
||||||
|
{issuesWithNotifications || notificationsDisabled ? (
|
||||||
|
<HeaderButton.Item
|
||||||
|
color={issuesWithNotifications ? colors!.fontDanger : colors!.headerTintColor}
|
||||||
|
iconName='notification-disabled'
|
||||||
|
onPress={this.navigateToNotificationOrPushTroubleshoot}
|
||||||
|
testID='room-view-push-troubleshoot'
|
||||||
|
/>
|
||||||
|
) : null}
|
||||||
{rid ? <HeaderCallButton rid={rid} /> : null}
|
{rid ? <HeaderCallButton rid={rid} /> : null}
|
||||||
{threadsEnabled ? (
|
{threadsEnabled ? (
|
||||||
<HeaderButton.Item
|
<HeaderButton.Item
|
||||||
|
@ -365,7 +413,8 @@ const mapStateToProps = (state: IApplicationState) => ({
|
||||||
userId: getUserSelector(state).id,
|
userId: getUserSelector(state).id,
|
||||||
threadsEnabled: state.settings.Threads_enabled as boolean,
|
threadsEnabled: state.settings.Threads_enabled as boolean,
|
||||||
isMasterDetail: state.app.isMasterDetail,
|
isMasterDetail: state.app.isMasterDetail,
|
||||||
livechatRequestComment: state.settings.Livechat_request_comment_when_closing_conversation as boolean
|
livechatRequestComment: state.settings.Livechat_request_comment_when_closing_conversation as boolean,
|
||||||
|
issuesWithNotifications: state.troubleshootingNotification.issuesWithNotifications
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(mapStateToProps)(RightButtonsContainer);
|
export default connect(mapStateToProps)(withTheme(RightButtonsContainer));
|
||||||
|
|
|
@ -456,7 +456,7 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
|
||||||
const t = room?.t;
|
const t = room?.t;
|
||||||
const teamMain = 'teamMain' in room ? room?.teamMain : false;
|
const teamMain = 'teamMain' in room ? room?.teamMain : false;
|
||||||
const omnichannelPermissions = { canForwardGuest, canReturnQueue, canPlaceLivechatOnHold };
|
const omnichannelPermissions = { canForwardGuest, canReturnQueue, canPlaceLivechatOnHold };
|
||||||
|
const iSubRoom = room as ISubscription;
|
||||||
navigation.setOptions({
|
navigation.setOptions({
|
||||||
headerShown: true,
|
headerShown: true,
|
||||||
headerTitleAlign: 'left',
|
headerTitleAlign: 'left',
|
||||||
|
@ -513,6 +513,7 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
|
||||||
toggleFollowThread={this.toggleFollowThread}
|
toggleFollowThread={this.toggleFollowThread}
|
||||||
showActionSheet={this.showActionSheet}
|
showActionSheet={this.showActionSheet}
|
||||||
departmentId={departmentId}
|
departmentId={departmentId}
|
||||||
|
notificationsDisabled={iSubRoom?.disableNotifications}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
|
@ -92,6 +92,7 @@ interface IRoomsListViewProps {
|
||||||
createPrivateChannelPermission: [];
|
createPrivateChannelPermission: [];
|
||||||
createDiscussionPermission: [];
|
createDiscussionPermission: [];
|
||||||
serverVersion: string;
|
serverVersion: string;
|
||||||
|
issuesWithNotifications: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IRoomsListViewState {
|
interface IRoomsListViewState {
|
||||||
|
@ -146,6 +147,7 @@ const shouldUpdateProps = [
|
||||||
'createPublicChannelPermission',
|
'createPublicChannelPermission',
|
||||||
'createPrivateChannelPermission',
|
'createPrivateChannelPermission',
|
||||||
'createDiscussionPermission',
|
'createDiscussionPermission',
|
||||||
|
'issuesWithNotifications',
|
||||||
'supportedVersionsStatus'
|
'supportedVersionsStatus'
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -200,7 +202,6 @@ class RoomsListView extends React.Component<IRoomsListViewProps, IRoomsListViewS
|
||||||
const { navigation, dispatch } = this.props;
|
const { navigation, dispatch } = this.props;
|
||||||
this.handleHasPermission();
|
this.handleHasPermission();
|
||||||
this.mounted = true;
|
this.mounted = true;
|
||||||
|
|
||||||
this.unsubscribeFocus = navigation.addListener('focus', () => {
|
this.unsubscribeFocus = navigation.addListener('focus', () => {
|
||||||
this.animated = true;
|
this.animated = true;
|
||||||
// Check if there were changes with sort preference, then call getSubscription to remount the list
|
// Check if there were changes with sort preference, then call getSubscription to remount the list
|
||||||
|
@ -334,6 +335,7 @@ class RoomsListView extends React.Component<IRoomsListViewProps, IRoomsListViewS
|
||||||
createDiscussionPermission,
|
createDiscussionPermission,
|
||||||
showAvatar,
|
showAvatar,
|
||||||
displayMode,
|
displayMode,
|
||||||
|
issuesWithNotifications,
|
||||||
supportedVersionsStatus
|
supportedVersionsStatus
|
||||||
} = this.props;
|
} = this.props;
|
||||||
const { item } = this.state;
|
const { item } = this.state;
|
||||||
|
@ -358,6 +360,7 @@ class RoomsListView extends React.Component<IRoomsListViewProps, IRoomsListViewS
|
||||||
insets.left !== prevProps.insets.left ||
|
insets.left !== prevProps.insets.left ||
|
||||||
insets.right !== prevProps.insets.right ||
|
insets.right !== prevProps.insets.right ||
|
||||||
notificationPresenceCap !== prevProps.notificationPresenceCap ||
|
notificationPresenceCap !== prevProps.notificationPresenceCap ||
|
||||||
|
issuesWithNotifications !== prevProps.issuesWithNotifications ||
|
||||||
supportedVersionsStatus !== prevProps.supportedVersionsStatus
|
supportedVersionsStatus !== prevProps.supportedVersionsStatus
|
||||||
) {
|
) {
|
||||||
this.setHeader();
|
this.setHeader();
|
||||||
|
@ -411,7 +414,8 @@ class RoomsListView extends React.Component<IRoomsListViewProps, IRoomsListViewS
|
||||||
|
|
||||||
getHeader = (): StackNavigationOptions => {
|
getHeader = (): StackNavigationOptions => {
|
||||||
const { searching, canCreateRoom } = this.state;
|
const { searching, canCreateRoom } = this.state;
|
||||||
const { navigation, isMasterDetail, notificationPresenceCap, supportedVersionsStatus, theme } = this.props;
|
const { navigation, isMasterDetail, notificationPresenceCap, issuesWithNotifications, supportedVersionsStatus, theme } =
|
||||||
|
this.props;
|
||||||
if (searching) {
|
if (searching) {
|
||||||
return {
|
return {
|
||||||
headerTitleAlign: 'left',
|
headerTitleAlign: 'left',
|
||||||
|
@ -458,6 +462,14 @@ class RoomsListView extends React.Component<IRoomsListViewProps, IRoomsListViewS
|
||||||
headerTitle: () => <RoomsListHeaderView />,
|
headerTitle: () => <RoomsListHeaderView />,
|
||||||
headerRight: () => (
|
headerRight: () => (
|
||||||
<HeaderButton.Container>
|
<HeaderButton.Container>
|
||||||
|
{issuesWithNotifications ? (
|
||||||
|
<HeaderButton.Item
|
||||||
|
iconName='notification-disabled'
|
||||||
|
onPress={this.navigateToPushTroubleshootView}
|
||||||
|
testID='rooms-list-view-push-troubleshoot'
|
||||||
|
color={themes[theme].fontDanger}
|
||||||
|
/>
|
||||||
|
) : null}
|
||||||
{canCreateRoom ? (
|
{canCreateRoom ? (
|
||||||
<HeaderButton.Item
|
<HeaderButton.Item
|
||||||
iconName='create'
|
iconName='create'
|
||||||
|
@ -775,6 +787,15 @@ class RoomsListView extends React.Component<IRoomsListViewProps, IRoomsListViewS
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
navigateToPushTroubleshootView = () => {
|
||||||
|
const { navigation, isMasterDetail } = this.props;
|
||||||
|
if (isMasterDetail) {
|
||||||
|
navigation.navigate('ModalStackNavigator', { screen: 'PushTroubleshootView' });
|
||||||
|
} else {
|
||||||
|
navigation.navigate('PushTroubleshootView');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
goQueue = () => {
|
goQueue = () => {
|
||||||
logEvent(events.RL_GO_QUEUE);
|
logEvent(events.RL_GO_QUEUE);
|
||||||
const { navigation, isMasterDetail, inquiryEnabled } = this.props;
|
const { navigation, isMasterDetail, inquiryEnabled } = this.props;
|
||||||
|
@ -1008,7 +1029,8 @@ const mapStateToProps = (state: IApplicationState) => ({
|
||||||
createPublicChannelPermission: state.permissions['create-c'],
|
createPublicChannelPermission: state.permissions['create-c'],
|
||||||
createPrivateChannelPermission: state.permissions['create-p'],
|
createPrivateChannelPermission: state.permissions['create-p'],
|
||||||
createDiscussionPermission: state.permissions['start-discussion'],
|
createDiscussionPermission: state.permissions['start-discussion'],
|
||||||
serverVersion: state.server.version
|
serverVersion: state.server.version,
|
||||||
|
issuesWithNotifications: state.troubleshootingNotification.issuesWithNotifications
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(mapStateToProps)(withDimensions(withTheme(withSafeAreaInsets(RoomsListView))));
|
export default connect(mapStateToProps)(withDimensions(withTheme(withSafeAreaInsets(RoomsListView))));
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import React, { useEffect, useLayoutEffect, useState } from 'react';
|
import React, { useEffect, useLayoutEffect, useState } from 'react';
|
||||||
import { Switch } from 'react-native';
|
import { Switch } from 'react-native';
|
||||||
import { StackNavigationProp } from '@react-navigation/stack';
|
import { StackNavigationProp } from '@react-navigation/stack';
|
||||||
import { useNavigation } from '@react-navigation/native';
|
import { CompositeNavigationProp, useNavigation } from '@react-navigation/native';
|
||||||
|
|
||||||
import StatusBar from '../../containers/StatusBar';
|
import StatusBar from '../../containers/StatusBar';
|
||||||
import * as List from '../../containers/List';
|
import * as List from '../../containers/List';
|
||||||
|
@ -15,16 +15,25 @@ import { Services } from '../../lib/services';
|
||||||
import { useAppSelector } from '../../lib/hooks';
|
import { useAppSelector } from '../../lib/hooks';
|
||||||
import ListPicker from './ListPicker';
|
import ListPicker from './ListPicker';
|
||||||
import log from '../../lib/methods/helpers/log';
|
import log from '../../lib/methods/helpers/log';
|
||||||
|
import { MasterDetailInsideStackParamList } from '../../stacks/MasterDetailStack/types';
|
||||||
import { useUserPreferences } from '../../lib/methods';
|
import { useUserPreferences } from '../../lib/methods';
|
||||||
import { NOTIFICATION_IN_APP_VIBRATION, SWITCH_TRACK_COLOR } from '../../lib/constants';
|
import { NOTIFICATION_IN_APP_VIBRATION, SWITCH_TRACK_COLOR } from '../../lib/constants';
|
||||||
|
|
||||||
|
type TNavigation = CompositeNavigationProp<
|
||||||
|
StackNavigationProp<ProfileStackParamList, 'UserNotificationPrefView'>,
|
||||||
|
StackNavigationProp<MasterDetailInsideStackParamList>
|
||||||
|
>;
|
||||||
|
|
||||||
const UserNotificationPreferencesView = () => {
|
const UserNotificationPreferencesView = () => {
|
||||||
const [inAppVibration, setInAppVibration] = useUserPreferences<boolean>(NOTIFICATION_IN_APP_VIBRATION, true);
|
const [inAppVibration, setInAppVibration] = useUserPreferences<boolean>(NOTIFICATION_IN_APP_VIBRATION, true);
|
||||||
const [preferences, setPreferences] = useState({} as INotificationPreferences);
|
const [preferences, setPreferences] = useState({} as INotificationPreferences);
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
|
|
||||||
const navigation = useNavigation<StackNavigationProp<ProfileStackParamList, 'UserNotificationPrefView'>>();
|
const navigation = useNavigation<TNavigation>();
|
||||||
const userId = useAppSelector(state => getUserSelector(state).id);
|
const { userId, isMasterDetail } = useAppSelector(state => ({
|
||||||
|
userId: getUserSelector(state).id,
|
||||||
|
isMasterDetail: state.app.isMasterDetail
|
||||||
|
}));
|
||||||
|
|
||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
navigation.setOptions({
|
navigation.setOptions({
|
||||||
|
@ -62,6 +71,14 @@ const UserNotificationPreferencesView = () => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const navigateToPushTroubleshootView = () => {
|
||||||
|
if (isMasterDetail) {
|
||||||
|
navigation.navigate('ModalStackNavigator', { screen: 'PushTroubleshootView' });
|
||||||
|
} else {
|
||||||
|
navigation.navigate('PushTroubleshootView');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const toggleInAppVibration = () => {
|
const toggleInAppVibration = () => {
|
||||||
setInAppVibration(!inAppVibration);
|
setInAppVibration(!inAppVibration);
|
||||||
};
|
};
|
||||||
|
@ -97,6 +114,13 @@ const UserNotificationPreferencesView = () => {
|
||||||
value={preferences.pushNotifications}
|
value={preferences.pushNotifications}
|
||||||
/>
|
/>
|
||||||
<List.Separator />
|
<List.Separator />
|
||||||
|
<List.Item
|
||||||
|
title='Troubleshooting'
|
||||||
|
onPress={navigateToPushTroubleshootView}
|
||||||
|
testID='user-notification-preference-view-troubleshooting'
|
||||||
|
showActionIndicator
|
||||||
|
/>
|
||||||
|
<List.Separator />
|
||||||
<List.Info info='Push_Notifications_Alert_Info' />
|
<List.Info info='Push_Notifications_Alert_Info' />
|
||||||
</List.Section>
|
</List.Section>
|
||||||
|
|
||||||
|
|
|
@ -534,6 +534,11 @@ PODS:
|
||||||
- React-Core
|
- React-Core
|
||||||
- RNMathView (1.0.0):
|
- RNMathView (1.0.0):
|
||||||
- iosMath
|
- iosMath
|
||||||
|
- RNNotifee (7.8.0):
|
||||||
|
- React-Core
|
||||||
|
- RNNotifee/NotifeeCore (= 7.8.0)
|
||||||
|
- RNNotifee/NotifeeCore (7.8.0):
|
||||||
|
- React-Core
|
||||||
- RNReanimated (2.8.0):
|
- RNReanimated (2.8.0):
|
||||||
- DoubleConversion
|
- DoubleConversion
|
||||||
- FBLazyVector
|
- FBLazyVector
|
||||||
|
@ -666,6 +671,7 @@ DEPENDENCIES:
|
||||||
- RNImageCropPicker (from `../node_modules/react-native-image-crop-picker`)
|
- RNImageCropPicker (from `../node_modules/react-native-image-crop-picker`)
|
||||||
- RNLocalize (from `../node_modules/react-native-localize`)
|
- RNLocalize (from `../node_modules/react-native-localize`)
|
||||||
- RNMathView (from `../node_modules/react-native-math-view/ios`)
|
- RNMathView (from `../node_modules/react-native-math-view/ios`)
|
||||||
|
- "RNNotifee (from `../node_modules/@notifee/react-native`)"
|
||||||
- RNReanimated (from `../node_modules/react-native-reanimated`)
|
- RNReanimated (from `../node_modules/react-native-reanimated`)
|
||||||
- RNRootView (from `../node_modules/rn-root-view`)
|
- RNRootView (from `../node_modules/rn-root-view`)
|
||||||
- RNScreens (from `../node_modules/react-native-screens`)
|
- RNScreens (from `../node_modules/react-native-screens`)
|
||||||
|
@ -857,6 +863,8 @@ EXTERNAL SOURCES:
|
||||||
:path: "../node_modules/react-native-localize"
|
:path: "../node_modules/react-native-localize"
|
||||||
RNMathView:
|
RNMathView:
|
||||||
:path: "../node_modules/react-native-math-view/ios"
|
:path: "../node_modules/react-native-math-view/ios"
|
||||||
|
RNNotifee:
|
||||||
|
:path: "../node_modules/@notifee/react-native"
|
||||||
RNReanimated:
|
RNReanimated:
|
||||||
:path: "../node_modules/react-native-reanimated"
|
:path: "../node_modules/react-native-reanimated"
|
||||||
RNRootView:
|
RNRootView:
|
||||||
|
@ -972,6 +980,7 @@ SPEC CHECKSUMS:
|
||||||
RNImageCropPicker: 97289cd94fb01ab79db4e5c92938be4d0d63415d
|
RNImageCropPicker: 97289cd94fb01ab79db4e5c92938be4d0d63415d
|
||||||
RNLocalize: 82a569022724d35461e2dc5b5d015a13c3ca995b
|
RNLocalize: 82a569022724d35461e2dc5b5d015a13c3ca995b
|
||||||
RNMathView: 4c8a3c081fa671ab3136c51fa0bdca7ffb708bd5
|
RNMathView: 4c8a3c081fa671ab3136c51fa0bdca7ffb708bd5
|
||||||
|
RNNotifee: f3c01b391dd8e98e67f539f9a35a9cbcd3bae744
|
||||||
RNReanimated: 64573e25e078ae6bec03b891586d50b9ec284393
|
RNReanimated: 64573e25e078ae6bec03b891586d50b9ec284393
|
||||||
RNRootView: 895a4813dedeaca82db2fa868ca1c333d790e494
|
RNRootView: 895a4813dedeaca82db2fa868ca1c333d790e494
|
||||||
RNScreens: fa9b582d85ae5d62c91c66003b5278458fed7aaa
|
RNScreens: fa9b582d85ae5d62c91c66003b5278458fed7aaa
|
||||||
|
|
|
@ -19,11 +19,6 @@ module.exports = {
|
||||||
platforms: {
|
platforms: {
|
||||||
ios: null
|
ios: null
|
||||||
}
|
}
|
||||||
},
|
|
||||||
'@notifee/react-native': {
|
|
||||||
platforms: {
|
|
||||||
ios: null
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue