diff --git a/app/actions/actionsTypes.js b/app/actions/actionsTypes.js index 0790b7ba..70555acb 100644 --- a/app/actions/actionsTypes.js +++ b/app/actions/actionsTypes.js @@ -53,8 +53,6 @@ export const LOGOUT = 'LOGOUT'; // logout is always success export const SNIPPETED_MESSAGES = createRequestTypes('SNIPPETED_MESSAGES', ['OPEN', 'READY', 'CLOSE', 'MESSAGES_RECEIVED']); export const DEEP_LINKING = createRequestTypes('DEEP_LINKING', ['OPEN']); export const SORT_PREFERENCES = createRequestTypes('SORT_PREFERENCES', ['SET_ALL', 'SET']); -export const TOGGLE_CRASH_REPORT = 'TOGGLE_CRASH_REPORT'; -export const TOGGLE_ANALYTICS_EVENTS = 'TOGGLE_ANALYTICS_EVENTS'; export const SET_CUSTOM_EMOJIS = 'SET_CUSTOM_EMOJIS'; export const SET_ACTIVE_USERS = 'SET_ACTIVE_USERS'; export const USERS_TYPING = createRequestTypes('USERS_TYPING', ['ADD', 'REMOVE', 'CLEAR']); diff --git a/app/actions/crashReport.js b/app/actions/crashReport.js deleted file mode 100644 index 8577b33e..00000000 --- a/app/actions/crashReport.js +++ /dev/null @@ -1,15 +0,0 @@ -import * as types from './actionsTypes'; - -export function toggleCrashReport(value) { - return { - type: types.TOGGLE_CRASH_REPORT, - payload: value - }; -} - -export function toggleAnalyticsEvents(value) { - return { - type: types.TOGGLE_ANALYTICS_EVENTS, - payload: value - }; -} diff --git a/app/index.js b/app/index.js index efcf1557..54985c3c 100644 --- a/app/index.js +++ b/app/index.js @@ -19,7 +19,7 @@ import { deepLinkingOpen } from './actions/deepLinking'; import parseQuery from './lib/methods/helpers/parseQuery'; import { initializePushNotifications, onNotification } from './notifications/push'; import store from './lib/createStore'; -import { loggerConfig, analytics } from './utils/log'; +import { toggleAnalyticsEventsReport, toggleCrashErrorsReport } from './utils/log'; import { ThemeContext } from './theme'; import { DimensionsContext } from './dimensions'; import RocketChat, { THEME_PREFERENCES_KEY } from './lib/rocketchat'; @@ -188,11 +188,11 @@ export default class Root extends React.Component { initCrashReport = () => { RocketChat.getAllowCrashReport() .then((allowCrashReport) => { - if (!allowCrashReport) { - loggerConfig.autoNotify = false; - loggerConfig.registerBeforeSendCallback(() => false); - analytics().setAnalyticsCollectionEnabled(false); - } + toggleCrashErrorsReport(allowCrashReport); + }); + RocketChat.getAllowAnalyticsEvents() + .then((allowAnalyticsEvents) => { + toggleAnalyticsEventsReport(allowAnalyticsEvents); }); } diff --git a/app/reducers/crashReport.js b/app/reducers/crashReport.js deleted file mode 100644 index 8465897e..00000000 --- a/app/reducers/crashReport.js +++ /dev/null @@ -1,25 +0,0 @@ -import { TOGGLE_CRASH_REPORT, TOGGLE_ANALYTICS_EVENTS } from '../actions/actionsTypes'; - -const initialState = { - allowCrashReport: false, - allowAnalyticsEvents: false -}; - - -export default (state = initialState, action) => { - switch (action.type) { - case TOGGLE_CRASH_REPORT: - return { - ...state, - allowCrashReport: action.payload - }; - - case TOGGLE_ANALYTICS_EVENTS: - return { - ...state, - allowAnalyticsEvents: action.payload - }; - default: - return state; - } -}; diff --git a/app/reducers/index.js b/app/reducers/index.js index eb8f09d8..c0f5a995 100644 --- a/app/reducers/index.js +++ b/app/reducers/index.js @@ -10,7 +10,6 @@ import createChannel from './createChannel'; import app from './app'; import sortPreferences from './sortPreferences'; import share from './share'; -import crashReport from './crashReport'; import customEmojis from './customEmojis'; import activeUsers from './activeUsers'; import usersTyping from './usersTyping'; @@ -35,7 +34,6 @@ export default combineReducers({ rooms, sortPreferences, share, - crashReport, customEmojis, activeUsers, usersTyping, diff --git a/app/sagas/init.js b/app/sagas/init.js index 57bc3342..f8cce680 100644 --- a/app/sagas/init.js +++ b/app/sagas/init.js @@ -4,7 +4,6 @@ import RNBootSplash from 'react-native-bootsplash'; import UserPreferences from '../lib/userPreferences'; import { selectServerRequest } from '../actions/server'; import { setAllPreferences } from '../actions/sortPreferences'; -import { toggleCrashReport, toggleAnalyticsEvents } from '../actions/crashReport'; import { APP } from '../actions/actionsTypes'; import RocketChat from '../lib/rocketchat'; import log from '../utils/log'; @@ -15,12 +14,6 @@ import { appStart, ROOT_OUTSIDE, appReady } from '../actions/app'; export const initLocalSettings = function* initLocalSettings() { const sortPreferences = yield RocketChat.getSortPreferences(); yield put(setAllPreferences(sortPreferences)); - - const allowCrashReport = yield RocketChat.getAllowCrashReport(); - yield put(toggleCrashReport(allowCrashReport)); - - const allowAnalyticsEvents = yield RocketChat.getAllowAnalyticsEvents(); - yield put(toggleAnalyticsEvents(allowAnalyticsEvents)); }; const restore = function* restore() { diff --git a/app/utils/log/index.js b/app/utils/log/index.js index 361ce705..266f4bd4 100644 --- a/app/utils/log/index.js +++ b/app/utils/log/index.js @@ -5,10 +5,24 @@ import events from './events'; const analytics = firebaseAnalytics || ''; let bugsnag = ''; let crashlytics; +let reportCrashErrors = true; +let reportAnalyticsEvents = true; + +export const getReportCrashErrorsValue = () => reportCrashErrors; +export const getReportAnalyticsEventsValue = () => reportAnalyticsEvents; + if (!isFDroidBuild) { bugsnag = require('@bugsnag/react-native').default; - bugsnag.start(); + bugsnag.start({ + onBreadcrumb() { + return reportAnalyticsEvents; + }, + onError(error) { + if (!reportAnalyticsEvents) { error.breadcrumbs = []; } + return reportCrashErrors; + } + }); crashlytics = require('@react-native-firebase/crashlytics').default; } @@ -42,6 +56,16 @@ export const setCurrentScreen = (currentScreen) => { } }; +export const toggleCrashErrorsReport = (value) => { + crashlytics().setCrashlyticsCollectionEnabled(value); + return reportCrashErrors = value; +}; + +export const toggleAnalyticsEventsReport = (value) => { + analytics().setAnalyticsCollectionEnabled(value); + return reportAnalyticsEvents = value; +}; + export default (e) => { if (e instanceof Error && bugsnag && e.message !== 'Aborted' && !__DEV__) { bugsnag.notify(e, (event) => { diff --git a/app/views/SecurityPrivacyView.js b/app/views/SecurityPrivacyView.js index 937a0250..a21ae00f 100644 --- a/app/views/SecurityPrivacyView.js +++ b/app/views/SecurityPrivacyView.js @@ -1,158 +1,119 @@ -import React from 'react'; +import React, { useEffect, useState } from 'react'; import { Switch } from 'react-native'; import PropTypes from 'prop-types'; -import { connect } from 'react-redux'; import AsyncStorage from '@react-native-community/async-storage'; +import { useSelector } from 'react-redux'; -import { toggleCrashReport as toggleCrashReportAction, toggleAnalyticsEvents as toggleAnalyticsEventsAction } from '../actions/crashReport'; import { SWITCH_TRACK_COLOR } from '../constants/colors'; import StatusBar from '../containers/StatusBar'; import * as List from '../containers/List'; import I18n from '../i18n'; import { CRASH_REPORT_KEY, ANALYTICS_EVENTS_KEY } from '../lib/rocketchat'; import { - loggerConfig, analytics, logEvent, events + logEvent, events, toggleCrashErrorsReport, toggleAnalyticsEventsReport, getReportCrashErrorsValue, getReportAnalyticsEventsValue } from '../utils/log'; import SafeAreaView from '../containers/SafeAreaView'; import { isFDroidBuild } from '../constants/environment'; -import { getUserSelector } from '../selectors/login'; -class SecurityPrivacyView extends React.Component { - static navigationOptions = () => ({ - title: I18n.t('Security_and_privacy') - }); +const SecurityPrivacyView = ({ navigation }) => { + const [crashReportState, setCrashReportState] = useState(getReportCrashErrorsValue()); + const [analyticsEventsState, setAnalyticsEventsState] = useState(getReportAnalyticsEventsValue()); - static propTypes = { - navigation: PropTypes.object, - allowCrashReport: PropTypes.bool, - allowAnalyticsEvents: PropTypes.bool, - e2eEnabled: PropTypes.bool, - toggleCrashReport: PropTypes.func, - toggleAnalyticsEvents: PropTypes.func, - user: PropTypes.shape({ - roles: PropTypes.array, - id: PropTypes.string - }) - } + const { e2eEnabled } = useSelector(state => state.settings); - toggleCrashReport = (value) => { + useEffect(() => { + navigation.setOptions({ + title: I18n.t('Security_and_privacy') + }); + }, []); + + const toggleCrashReport = (value) => { logEvent(events.SE_TOGGLE_CRASH_REPORT); AsyncStorage.setItem(CRASH_REPORT_KEY, JSON.stringify(value)); - const { toggleCrashReport } = this.props; - toggleCrashReport(value); - if (!isFDroidBuild) { - loggerConfig.autoNotify = value; - if (value) { - loggerConfig.clearBeforeSendCallbacks(); - } else { - loggerConfig.registerBeforeSendCallback(() => false); - } - } - } + setCrashReportState(value); + toggleCrashErrorsReport(value); + }; - toggleAnalyticsEvents = (value) => { + const toggleAnalyticsEvents = (value) => { logEvent(events.SE_TOGGLE_ANALYTICS_EVENTS); - const { toggleAnalyticsEvents } = this.props; AsyncStorage.setItem(ANALYTICS_EVENTS_KEY, JSON.stringify(value)); - toggleAnalyticsEvents(value); - analytics().setAnalyticsCollectionEnabled(value); - } + setAnalyticsEventsState(value); + toggleAnalyticsEventsReport(value); + }; - navigateToScreen = (screen) => { + const navigateToScreen = (screen) => { logEvent(events[`SP_GO_${ screen.replace('View', '').toUpperCase() }`]); - const { navigation } = this.props; navigation.navigate(screen); - } + }; - renderCrashReportSwitch = () => { - const { allowCrashReport } = this.props; - return ( - - ); - } + return ( + + + + + + {e2eEnabled + ? ( + <> + navigateToScreen('E2EEncryptionSecurityView')} + testID='security-privacy-view-e2e-encryption' + /> + + + ) + : null + } + navigateToScreen('ScreenLockConfigView')} + testID='security-privacy-view-screen-lock' + /> + + - renderAnalyticsEventsSwitch = () => { - const { allowAnalyticsEvents } = this.props; - return ( - - ); - } - - render() { - const { e2eEnabled } = this.props; - return ( - - - - - - {e2eEnabled - ? ( - <> - this.navigateToScreen('E2EEncryptionSecurityView')} - testID='security-privacy-view-e2e-encryption' + {!isFDroidBuild ? ( + <> + + + ( + - - - ) - : null - } - this.navigateToScreen('ScreenLockConfigView')} - testID='security-privacy-view-screen-lock' - /> - - + )} + /> + + ( + + )} + /> + + + + + ) : null} + + + ); +}; - {!isFDroidBuild ? ( - <> - - - this.renderAnalyticsEventsSwitch()} - /> - - this.renderCrashReportSwitch()} - /> - - - - - ) : null} - - - ); - } -} +SecurityPrivacyView.propTypes = { + navigation: PropTypes.object +}; -const mapStateToProps = state => ({ - user: getUserSelector(state), - allowCrashReport: state.crashReport.allowCrashReport, - allowAnalyticsEvents: state.crashReport.allowAnalyticsEvents, - e2eEnabled: state.settings.E2E_Enable -}); - -const mapDispatchToProps = dispatch => ({ - toggleCrashReport: params => dispatch(toggleCrashReportAction(params)), - toggleAnalyticsEvents: params => dispatch(toggleAnalyticsEventsAction(params)) -}); - -export default connect(mapStateToProps, mapDispatchToProps)(SecurityPrivacyView); +export default SecurityPrivacyView;