[NEW] Log events from Room, Settings and Edit status (#2206)

* Create method to track user event to isolate the logic to improve future refactoring

* Track Onboarding view

* Track NewServer view

* Refactor track method due to firebase already send the current screen

* Track default login and all the oAuth options

* Track default sign up in RegisterView

* Change trackUserEvent signature and update all the files

* Track the remaining login services

* track add server, change server and search

* Track SidebarView and refactor to use react-navigation

* Track profile events and handle exceptions

* Track create channel flux

* Track send message to user via NewMessageView

* Track create direct message flux

* Handle failure of create channel and group in the saga

* Track create discussion flux

* Track navigate to directory and its actions

* Track read, favorite and hide a channel, handling its errors

* Track all channels sorting and grouping

* Resolve requests to improve the importing logs and events

* Remove unused events file

* Remove unused events file

* log proposed Room events

* Log proposed Message actions events

* Log EditStatus proposed events

* Log Settings proposed events

* Leave a bugsnag breadcrumb when logging an event

* Move all logEvent to the top of code block and log remaining fail events

* Move all the non-logic-dependent logEvent to the top of code block

* Move all non-logic and non-data dependent logEvent to the top of code block

* Improve the logging of sidebar events

* Improve events from onboarding and newserver

* Improve events from login and register view, and log enter with apple

* Improve NewMessageView events

* Improve CreateChannel events

* Improve CreateDiscussion and SelectedUsers create group events

* Improve RoomsList events and log trivial events

* Improve ProfileView events

* Remove single line function body for the sidebarNavigate

* Improve SettingsView events

* Log more events from ScreenLockConfigView

* Navigate to Status and AdminPanel View using the defined sidebarNavigate method

* Improve StatusView events

* Improve RoomView events

Co-authored-by: Diego Mello <diegolmello@gmail.com>
This commit is contained in:
Youssef Muhamad 2020-07-30 16:51:13 -03:00 committed by GitHub
parent 0e23ab880f
commit 363cd13207
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 188 additions and 30 deletions

View File

@ -7,7 +7,7 @@ import moment from 'moment';
import RocketChat from '../../lib/rocketchat'; import RocketChat from '../../lib/rocketchat';
import database from '../../lib/database'; import database from '../../lib/database';
import I18n from '../../i18n'; import I18n from '../../i18n';
import log from '../../utils/log'; import log, { logEvent } from '../../utils/log';
import Navigation from '../../lib/Navigation'; import Navigation from '../../lib/Navigation';
import { getMessageTranslation } from '../message/utils'; import { getMessageTranslation } from '../message/utils';
import { LISTENER } from '../Toast'; import { LISTENER } from '../Toast';
@ -15,6 +15,7 @@ import EventEmitter from '../../utils/events';
import { showConfirmationAlert } from '../../utils/info'; import { showConfirmationAlert } from '../../utils/info';
import { useActionSheet } from '../ActionSheet'; import { useActionSheet } from '../ActionSheet';
import Header, { HEADER_HEIGHT } from './Header'; import Header, { HEADER_HEIGHT } from './Header';
import events from '../../utils/log/events';
const MessageActions = React.memo(forwardRef(({ const MessageActions = React.memo(forwardRef(({
room, room,
@ -112,11 +113,18 @@ const MessageActions = React.memo(forwardRef(({
const getPermalink = message => RocketChat.getPermalinkMessage(message); const getPermalink = message => RocketChat.getPermalinkMessage(message);
const handleReply = message => replyInit(message, true); const handleReply = (message) => {
logEvent(events.ROOM_MSG_ACTION_REPLY);
replyInit(message, true);
};
const handleEdit = message => editInit(message); const handleEdit = (message) => {
logEvent(events.ROOM_MSG_ACTION_EDIT);
editInit(message);
};
const handleCreateDiscussion = (message) => { const handleCreateDiscussion = (message) => {
logEvent(events.ROOM_MSG_ACTION_DISCUSSION);
const params = { message, channel: room, showCloseModal: true }; const params = { message, channel: room, showCloseModal: true };
if (isMasterDetail) { if (isMasterDetail) {
Navigation.navigate('ModalStackNavigator', { screen: 'CreateDiscussionView', params }); Navigation.navigate('ModalStackNavigator', { screen: 'CreateDiscussionView', params });
@ -126,6 +134,7 @@ const MessageActions = React.memo(forwardRef(({
}; };
const handleUnread = async(message) => { const handleUnread = async(message) => {
logEvent(events.ROOM_MSG_ACTION_UNREAD);
const { id: messageId, ts } = message; const { id: messageId, ts } = message;
const { rid } = room; const { rid } = room;
try { try {
@ -144,54 +153,66 @@ const MessageActions = React.memo(forwardRef(({
Navigation.navigate('RoomsListView'); Navigation.navigate('RoomsListView');
} }
} catch (e) { } catch (e) {
logEvent(events.ROOM_MSG_ACTION_UNREAD_F);
log(e); log(e);
} }
}; };
const handlePermalink = async(message) => { const handlePermalink = async(message) => {
logEvent(events.ROOM_MSG_ACTION_PERMALINK);
try { try {
const permalink = await getPermalink(message); const permalink = await getPermalink(message);
Clipboard.setString(permalink); Clipboard.setString(permalink);
EventEmitter.emit(LISTENER, { message: I18n.t('Permalink_copied_to_clipboard') }); EventEmitter.emit(LISTENER, { message: I18n.t('Permalink_copied_to_clipboard') });
} catch { } catch {
// Do nothing logEvent(events.ROOM_MSG_ACTION_PERMALINK_F);
} }
}; };
const handleCopy = async(message) => { const handleCopy = async(message) => {
logEvent(events.ROOM_MSG_ACTION_COPY);
await Clipboard.setString(message.msg); await Clipboard.setString(message.msg);
EventEmitter.emit(LISTENER, { message: I18n.t('Copied_to_clipboard') }); EventEmitter.emit(LISTENER, { message: I18n.t('Copied_to_clipboard') });
}; };
const handleShare = async(message) => { const handleShare = async(message) => {
logEvent(events.ROOM_MSG_ACTION_SHARE);
try { try {
const permalink = await getPermalink(message); const permalink = await getPermalink(message);
Share.share({ message: permalink }); Share.share({ message: permalink });
} catch { } catch {
// Do nothing logEvent(events.ROOM_MSG_ACTION_SHARE_F);
} }
}; };
const handleQuote = message => replyInit(message, false); const handleQuote = (message) => {
logEvent(events.ROOM_MSG_ACTION_QUOTE);
replyInit(message, false);
};
const handleStar = async(message) => { const handleStar = async(message) => {
logEvent(message.starred ? events.ROOM_MSG_ACTION_UNSTAR : events.ROOM_MSG_ACTION_STAR);
try { try {
await RocketChat.toggleStarMessage(message.id, message.starred); await RocketChat.toggleStarMessage(message.id, message.starred);
EventEmitter.emit(LISTENER, { message: message.starred ? I18n.t('Message_unstarred') : I18n.t('Message_starred') }); EventEmitter.emit(LISTENER, { message: message.starred ? I18n.t('Message_unstarred') : I18n.t('Message_starred') });
} catch (e) { } catch (e) {
logEvent(events.ROOM_MSG_ACTION_STAR_F);
log(e); log(e);
} }
}; };
const handlePin = async(message) => { const handlePin = async(message) => {
logEvent(events.ROOM_MSG_ACTION_PIN);
try { try {
await RocketChat.togglePinMessage(message.id, message.pinned); await RocketChat.togglePinMessage(message.id, message.pinned);
} catch (e) { } catch (e) {
logEvent(events.ROOM_MSG_ACTION_PIN_F);
log(e); log(e);
} }
}; };
const handleReaction = (shortname, message) => { const handleReaction = (shortname, message) => {
logEvent(events.ROOM_MSG_ACTION_REACTION);
if (shortname) { if (shortname) {
onReactionPress(shortname, message.id); onReactionPress(shortname, message.id);
} else { } else {
@ -234,10 +255,12 @@ const MessageActions = React.memo(forwardRef(({
}; };
const handleReport = async(message) => { const handleReport = async(message) => {
logEvent(events.ROOM_MSG_ACTION_REPORT);
try { try {
await RocketChat.reportMessage(message.id); await RocketChat.reportMessage(message.id);
Alert.alert(I18n.t('Message_Reported')); Alert.alert(I18n.t('Message_Reported'));
} catch (e) { } catch (e) {
logEvent(events.ROOM_MSG_ACTION_REPORT_F);
log(e); log(e);
} }
}; };
@ -248,8 +271,10 @@ const MessageActions = React.memo(forwardRef(({
callToAction: I18n.t('Delete'), callToAction: I18n.t('Delete'),
onPress: async() => { onPress: async() => {
try { try {
logEvent(events.ROOM_MSG_ACTION_DELETE);
await RocketChat.deleteMessage(message.id, message.subscription.id); await RocketChat.deleteMessage(message.id, message.subscription.id);
} catch (e) { } catch (e) {
logEvent(events.ROOM_MSG_ACTION_DELETE_F);
log(e); log(e);
} }
} }
@ -381,6 +406,7 @@ const MessageActions = React.memo(forwardRef(({
}; };
const showMessageActions = async(message) => { const showMessageActions = async(message) => {
logEvent(events.ROOM_SHOW_MSG_ACTIONS);
await getPermissions(); await getPermissions();
showActionSheet({ showActionSheet({
options: getOptions(message), options: getOptions(message),

View File

@ -10,6 +10,7 @@ import styles from './styles';
import I18n from '../../i18n'; import I18n from '../../i18n';
import { themes } from '../../constants/colors'; import { themes } from '../../constants/colors';
import { CustomIcon } from '../../lib/Icons'; import { CustomIcon } from '../../lib/Icons';
import { logEvent, events } from '../../utils/log';
const RECORDING_EXTENSION = '.aac'; const RECORDING_EXTENSION = '.aac';
const RECORDING_SETTINGS = { const RECORDING_SETTINGS = {
@ -103,6 +104,7 @@ export default class RecordAudio extends React.PureComponent {
} }
startRecordingAudio = async() => { startRecordingAudio = async() => {
logEvent(events.ROOM_AUDIO_RECORD);
if (!this.isRecorderBusy) { if (!this.isRecorderBusy) {
this.isRecorderBusy = true; this.isRecorderBusy = true;
try { try {
@ -120,13 +122,14 @@ export default class RecordAudio extends React.PureComponent {
await Audio.requestPermissionsAsync(); await Audio.requestPermissionsAsync();
} }
} catch (error) { } catch (error) {
// Do nothing logEvent(events.ROOM_AUDIO_RECORD_F);
} }
this.isRecorderBusy = false; this.isRecorderBusy = false;
} }
}; };
finishRecordingAudio = async() => { finishRecordingAudio = async() => {
logEvent(events.ROOM_AUDIO_FINISH);
if (!this.isRecorderBusy) { if (!this.isRecorderBusy) {
const { onFinish } = this.props; const { onFinish } = this.props;
@ -147,7 +150,7 @@ export default class RecordAudio extends React.PureComponent {
onFinish(fileInfo); onFinish(fileInfo);
} catch (error) { } catch (error) {
// Do nothing logEvent(events.ROOM_AUDIO_FINISH_F);
} }
this.setState({ isRecording: false, recordingDurationMillis: 0 }); this.setState({ isRecording: false, recordingDurationMillis: 0 });
deactivateKeepAwake(); deactivateKeepAwake();
@ -156,12 +159,13 @@ export default class RecordAudio extends React.PureComponent {
}; };
cancelRecordingAudio = async() => { cancelRecordingAudio = async() => {
logEvent(events.ROOM_AUDIO_CANCEL);
if (!this.isRecorderBusy) { if (!this.isRecorderBusy) {
this.isRecorderBusy = true; this.isRecorderBusy = true;
try { try {
await this.recording.stopAndUnloadAsync(); await this.recording.stopAndUnloadAsync();
} catch (error) { } catch (error) {
// Do nothing logEvent(events.ROOM_AUDIO_CANCEL_F);
} }
this.setState({ isRecording: false, recordingDurationMillis: 0 }); this.setState({ isRecording: false, recordingDurationMillis: 0 });
deactivateKeepAwake(); deactivateKeepAwake();

View File

@ -17,8 +17,8 @@ import RocketChat from '../../lib/rocketchat';
import styles from './styles'; import styles from './styles';
import database from '../../lib/database'; import database from '../../lib/database';
import { emojis } from '../../emojis'; import { emojis } from '../../emojis';
import log, { logEvent, events } from '../../utils/log';
import RecordAudio from './RecordAudio'; import RecordAudio from './RecordAudio';
import log from '../../utils/log';
import I18n from '../../i18n'; import I18n from '../../i18n';
import ReplyPreview from './ReplyPreview'; import ReplyPreview from './ReplyPreview';
import debounce from '../../utils/debounce'; import debounce from '../../utils/debounce';
@ -585,37 +585,41 @@ class MessageBox extends Component {
} }
takePhoto = async() => { takePhoto = async() => {
logEvent(events.ROOM_BOX_ACTION_PHOTO);
try { try {
const image = await ImagePicker.openCamera(this.imagePickerConfig); const image = await ImagePicker.openCamera(this.imagePickerConfig);
if (this.canUploadFile(image)) { if (this.canUploadFile(image)) {
this.openShareView([image]); this.openShareView([image]);
} }
} catch (e) { } catch (e) {
// Do nothing logEvent(events.ROOM_BOX_ACTION_PHOTO_F);
} }
} }
takeVideo = async() => { takeVideo = async() => {
logEvent(events.ROOM_BOX_ACTION_VIDEO);
try { try {
const video = await ImagePicker.openCamera(this.videoPickerConfig); const video = await ImagePicker.openCamera(this.videoPickerConfig);
if (this.canUploadFile(video)) { if (this.canUploadFile(video)) {
this.openShareView([video]); this.openShareView([video]);
} }
} catch (e) { } catch (e) {
// Do nothing logEvent(events.ROOM_BOX_ACTION_VIDEO_F);
} }
} }
chooseFromLibrary = async() => { chooseFromLibrary = async() => {
logEvent(events.ROOM_BOX_ACTION_LIBRARY);
try { try {
const attachments = await ImagePicker.openPicker(this.libraryPickerConfig); const attachments = await ImagePicker.openPicker(this.libraryPickerConfig);
this.openShareView(attachments); this.openShareView(attachments);
} catch (e) { } catch (e) {
// Do nothing logEvent(events.ROOM_BOX_ACTION_LIBRARY_F);
} }
} }
chooseFile = async() => { chooseFile = async() => {
logEvent(events.ROOM_BOX_ACTION_FILE);
try { try {
const res = await DocumentPicker.pick({ const res = await DocumentPicker.pick({
type: [DocumentPicker.types.allFiles] type: [DocumentPicker.types.allFiles]
@ -631,6 +635,7 @@ class MessageBox extends Component {
} }
} catch (e) { } catch (e) {
if (!DocumentPicker.isCancel(e)) { if (!DocumentPicker.isCancel(e)) {
logEvent(events.ROOM_BOX_ACTION_FILE_F);
log(e); log(e);
} }
} }
@ -648,6 +653,7 @@ class MessageBox extends Component {
} }
createDiscussion = () => { createDiscussion = () => {
logEvent(events.ROOM_BOX_ACTION_DISCUSSION);
const { isMasterDetail } = this.props; const { isMasterDetail } = this.props;
const params = { channel: this.room, showCloseModal: true }; const params = { channel: this.room, showCloseModal: true };
if (isMasterDetail) { if (isMasterDetail) {
@ -658,6 +664,7 @@ class MessageBox extends Component {
} }
showMessageBoxActions = () => { showMessageBoxActions = () => {
logEvent(events.ROOM_SHOW_BOX_ACTIONS);
const { showActionSheet } = this.props; const { showActionSheet } = this.props;
showActionSheet({ options: this.options }); showActionSheet({ options: this.options });
} }
@ -668,10 +675,9 @@ class MessageBox extends Component {
this.clearInput(); this.clearInput();
} }
openEmoji = async() => { openEmoji = () => {
await this.setState({ logEvent(events.ROOM_OPEN_EMOJI);
showEmojiKeyboard: true this.setState({ showEmojiKeyboard: true });
});
} }
recordingCallback = (recording) => { recordingCallback = (recording) => {

View File

@ -43,6 +43,16 @@ export default {
SIDEBAR_NAVIGATE_TO_SETTINGS: 'sidebar_navigate_to_settings', SIDEBAR_NAVIGATE_TO_SETTINGS: 'sidebar_navigate_to_settings',
SIDEBAR_NAVIGATE_TO_ADMINPANEL: 'sidebar_navigate_to_admin_panel', SIDEBAR_NAVIGATE_TO_ADMINPANEL: 'sidebar_navigate_to_admin_panel',
// STATUS VIEW
STATUS_DONE: 'status_done',
STATUS_ONLINE: 'status_online',
STATUS_BUSY: 'status_busy',
STATUS_AWAY: 'status_away',
STATUS_OFFLINE: 'status_offline',
STATUS_F: 'status_f',
STATUS_CUSTOM: 'status_custom',
STATUS_CUSTOM_F: 'status_custom_f',
// ROOMS LIST VIEW // ROOMS LIST VIEW
RL_TOGGLE_SERVER_DROPDOWN: 'rl_toggle_server_dropdown', RL_TOGGLE_SERVER_DROPDOWN: 'rl_toggle_server_dropdown',
RL_ADD_SERVER: 'rl_add_server', RL_ADD_SERVER: 'rl_add_server',
@ -62,7 +72,7 @@ export default {
RL_TOGGLE_SORT_DROPDOWN: 'rl_toggle_sort_dropdown', RL_TOGGLE_SORT_DROPDOWN: 'rl_toggle_sort_dropdown',
RL_SORT_CHANNELS_BY_NAME: 'rl_sort_channels_by_name', RL_SORT_CHANNELS_BY_NAME: 'rl_sort_channels_by_name',
RL_SORT_CHANNELS_BY_ACTIVITY: 'rl_sort_channels_by_activity', RL_SORT_CHANNELS_BY_ACTIVITY: 'rl_sort_channels_by_activity',
RL_SORT_CHANNELS_FAIL: 'rl_sort_channels_fail', RL_SORT_CHANNELS_F: 'rl_sort_channels_f',
RL_GROUP_CHANNELS_BY_TYPE: 'rl_group_channels_by_type', RL_GROUP_CHANNELS_BY_TYPE: 'rl_group_channels_by_type',
RL_GROUP_CHANNELS_BY_FAVORITE: 'rl_group_channels_by_favorite', RL_GROUP_CHANNELS_BY_FAVORITE: 'rl_group_channels_by_favorite',
RL_GROUP_CHANNELS_BY_UNREAD: 'rl_group_channels_by_unread', RL_GROUP_CHANNELS_BY_UNREAD: 'rl_group_channels_by_unread',
@ -104,5 +114,84 @@ export default {
PROFILE_SAVE_AVATAR: 'profile_save_avatar', PROFILE_SAVE_AVATAR: 'profile_save_avatar',
PROFILE_SAVE_AVATAR_F: 'profile_save_avatar_f', PROFILE_SAVE_AVATAR_F: 'profile_save_avatar_f',
PROFILE_SAVE_CHANGES: 'profile_save_changes', PROFILE_SAVE_CHANGES: 'profile_save_changes',
PROFILE_SAVE_CHANGES_F: 'profile_save_changes_f' PROFILE_SAVE_CHANGES_F: 'profile_save_changes_f',
// SETTINGS VIEW
SE_CONTACT_US: 'se_contact_us',
SE_CONTACT_US_F: 'se_contact_us_f',
SE_NAVIGATE_TO_LANGUAGE: 'se_navigate_to_language',
SE_REVIEW_THIS_APP: 'se_review_this_app',
SE_REVIEW_THIS_APP_F: 'se_review_this_app_f',
SE_SHARE_THIS_APP: 'se_share_this_app',
SE_NAVIGATE_TO_DEFAULTBROWSER: 'se_navigate_to_default_browser',
SE_NAVIGATE_TO_THEME: 'se_navigate_to_theme',
SE_NAVIGATE_TO_SCREENLOCKCONFIG: 'se_navigate_to_screen_lock_cfg',
SE_NAVIGATE_TO_PROFILE: 'se_navigate_to_profile',
SE_READ_LICENSE: 'se_read_license',
SE_COPY_APP_VERSION: 'se_copy_app_version',
SE_COPY_SERVER_VERSION: 'se_copy_server_version',
SE_TOGGLE_CRASH_REPORT: 'se_toggle_crash_report',
SE_CLEAR_LOCAL_SERVER_CACHE: 'se_clear_local_server_cache',
SE_LOG_OUT: 'se_log_out',
// LANGUAGE VIEW
LANG_SET_LANGUAGE: 'lang_set_language',
LANG_SET_LANGUAGE_F: 'lang_set_language_f',
// DEFAULT BROWSER VIEW
DB_CHANGE_DEFAULT_BROWSER: 'db_change_default_browser',
DB_CHANGE_DEFAULT_BROWSER_F: 'db_change_default_browser_f',
// THEME VIEW
THEME_SET_THEME_GROUP: 'theme_set_theme_group',
THEME_SET_DARK_LEVEL: 'theme_set_dark_level',
// SCREEN LOCK CONFIG VIEW
SLC_SAVE_SCREEN_LOCK: 'slc_save_screen_lock',
SLC_TOGGLE_AUTOLOCK: 'slc_toggle_autolock',
SLC_TOGGLE_BIOMETRY: 'slc_toggle_biometry',
SLC_CHANGE_PASSCODE: 'slc_change_passcode',
SLC_CHANGE_AUTOLOCK_TIME: 'slc_change_autolock_time',
// ROOM VIEW
ROOM_SEND_MESSAGE: 'room_send_message',
ROOM_OPEN_EMOJI: 'room_open_emoji',
ROOM_AUDIO_RECORD: 'room_audio_record',
ROOM_AUDIO_RECORD_F: 'room_audio_record_f',
ROOM_AUDIO_FINISH: 'room_audio_finish',
ROOM_AUDIO_FINISH_F: 'room_audio_finish_f',
ROOM_AUDIO_CANCEL: 'room_audio_cancel',
ROOM_AUDIO_CANCEL_F: 'room_audio_cancel_f',
ROOM_SHOW_BOX_ACTIONS: 'room_show_box_actions',
ROOM_BOX_ACTION_PHOTO: 'room_box_action_photo',
ROOM_BOX_ACTION_PHOTO_F: 'room_box_action_photo_f',
ROOM_BOX_ACTION_VIDEO: 'room_box_action_video',
ROOM_BOX_ACTION_VIDEO_F: 'room_box_action_video_f',
ROOM_BOX_ACTION_LIBRARY: 'room_box_action_library',
ROOM_BOX_ACTION_LIBRARY_F: 'room_box_action_library_f',
ROOM_BOX_ACTION_FILE: 'room_box_action_file',
ROOM_BOX_ACTION_FILE_F: 'room_box_action_file_f',
ROOM_BOX_ACTION_DISCUSSION: 'room_box_action_discussion',
ROOM_SHOW_MSG_ACTIONS: 'room_show_msg_actions',
ROOM_MSG_ACTION_REPLY: 'room_msg_action_reply',
ROOM_MSG_ACTION_QUOTE: 'room_msg_action_quote',
ROOM_MSG_ACTION_EDIT: 'room_msg_action_edit',
ROOM_MSG_ACTION_DELETE: 'room_msg_action_delete',
ROOM_MSG_ACTION_DELETE_F: 'room_msg_action_delete_f',
ROOM_MSG_ACTION_PERMALINK: 'room_msg_action_permalink',
ROOM_MSG_ACTION_PERMALINK_F: 'room_msg_action_permalink_f',
ROOM_MSG_ACTION_DISCUSSION: 'room_msg_action_discussion',
ROOM_MSG_ACTION_UNREAD: 'room_msg_action_unread',
ROOM_MSG_ACTION_UNREAD_F: 'room_msg_action_unread_f',
ROOM_MSG_ACTION_COPY: 'room_msg_action_copy',
ROOM_MSG_ACTION_SHARE: 'room_msg_action_share',
ROOM_MSG_ACTION_SHARE_F: 'room_msg_action_share_f',
ROOM_MSG_ACTION_STAR: 'room_msg_action_star',
ROOM_MSG_ACTION_UNSTAR: 'room_msg_action_unstar',
ROOM_MSG_ACTION_STAR_F: 'room_msg_action_star_f',
ROOM_MSG_ACTION_PIN: 'room_msg_action_pin',
ROOM_MSG_ACTION_PIN_F: 'room_msg_action_pin_f',
ROOM_MSG_ACTION_REACTION: 'room_msg_action_reaction',
ROOM_MSG_ACTION_REPORT: 'room_msg_action_report',
ROOM_MSG_ACTION_REPORT_F: 'room_msg_action_report_f'
}; };

View File

@ -5,6 +5,7 @@ import { isIOS } from './deviceInfo';
import I18n from '../i18n'; import I18n from '../i18n';
import { showErrorAlert } from './info'; import { showErrorAlert } from './info';
import { STORE_REVIEW_LINK } from '../constants/links'; import { STORE_REVIEW_LINK } from '../constants/links';
import { logEvent, events } from './log';
const store = isIOS ? 'App Store' : 'Play Store'; const store = isIOS ? 'App Store' : 'Play Store';
@ -31,6 +32,7 @@ const onCancelPress = () => {
}; };
export const onReviewPress = async() => { export const onReviewPress = async() => {
logEvent(events.SE_REVIEW_THIS_APP);
await onCancelPress(); await onCancelPress();
try { try {
const supported = await Linking.canOpenURL(STORE_REVIEW_LINK); const supported = await Linking.canOpenURL(STORE_REVIEW_LINK);
@ -38,6 +40,7 @@ export const onReviewPress = async() => {
Linking.openURL(STORE_REVIEW_LINK); Linking.openURL(STORE_REVIEW_LINK);
} }
} catch (e) { } catch (e) {
logEvent(events.SE_REVIEW_THIS_APP_F);
showErrorAlert(I18n.t('Review_app_unable_store', { store })); showErrorAlert(I18n.t('Review_app_unable_store', { store }));
} }
}; };

View File

@ -16,6 +16,7 @@ import { CustomIcon } from '../lib/Icons';
import { DEFAULT_BROWSER_KEY } from '../utils/openLink'; import { DEFAULT_BROWSER_KEY } from '../utils/openLink';
import { isIOS } from '../utils/deviceInfo'; import { isIOS } from '../utils/deviceInfo';
import SafeAreaView from '../containers/SafeAreaView'; import SafeAreaView from '../containers/SafeAreaView';
import { logEvent, events } from '../utils/log';
const DEFAULT_BROWSERS = [ const DEFAULT_BROWSERS = [
{ {
@ -113,12 +114,13 @@ class DefaultBrowserView extends React.Component {
} }
changeDefaultBrowser = async(newBrowser) => { changeDefaultBrowser = async(newBrowser) => {
logEvent(events.DB_CHANGE_DEFAULT_BROWSER, { browser: newBrowser });
try { try {
const browser = newBrowser !== 'inApp' ? newBrowser : null; const browser = newBrowser !== 'inApp' ? newBrowser : null;
await RNUserDefaults.set(DEFAULT_BROWSER_KEY, browser); await RNUserDefaults.set(DEFAULT_BROWSER_KEY, browser);
this.setState({ browser }); this.setState({ browser });
} catch { } catch {
// do nothing logEvent(events.DB_CHANGE_DEFAULT_BROWSER_F);
} }
} }

View File

@ -6,7 +6,7 @@ import { connect } from 'react-redux';
import RocketChat from '../../lib/rocketchat'; import RocketChat from '../../lib/rocketchat';
import I18n from '../../i18n'; import I18n from '../../i18n';
import { showErrorAlert } from '../../utils/info'; import { showErrorAlert } from '../../utils/info';
import log from '../../utils/log'; import log, { logEvent, events } from '../../utils/log';
import { setUser as setUserAction } from '../../actions/login'; import { setUser as setUserAction } from '../../actions/login';
import StatusBar from '../../containers/StatusBar'; import StatusBar from '../../containers/StatusBar';
import { CustomIcon } from '../../lib/Icons'; import { CustomIcon } from '../../lib/Icons';
@ -112,6 +112,7 @@ class LanguageView extends React.Component {
} }
changeLanguage = async(language) => { changeLanguage = async(language) => {
logEvent(events.LANG_SET_LANGUAGE);
const { user, setUser } = this.props; const { user, setUser } = this.props;
const params = {}; const params = {};
@ -134,10 +135,11 @@ class LanguageView extends React.Component {
record.language = params.language; record.language = params.language;
}); });
} catch (e) { } catch (e) {
// do nothing logEvent(events.LANG_SET_LANGUAGE_F);
} }
}); });
} catch (e) { } catch (e) {
logEvent(events.LANG_SET_LANGUAGE_F);
showErrorAlert(I18n.t('There_was_an_error_while_action', { action: I18n.t('saving_preferences') })); showErrorAlert(I18n.t('There_was_an_error_while_action', { action: I18n.t('saving_preferences') }));
log(e); log(e);
} }

View File

@ -24,7 +24,7 @@ import MessageBox from '../../containers/MessageBox';
import ReactionPicker from './ReactionPicker'; import ReactionPicker from './ReactionPicker';
import UploadProgress from './UploadProgress'; import UploadProgress from './UploadProgress';
import styles from './styles'; import styles from './styles';
import log from '../../utils/log'; import log, { logEvent, events } from '../../utils/log';
import EventEmitter from '../../utils/events'; import EventEmitter from '../../utils/events';
import I18n from '../../i18n'; import I18n from '../../i18n';
import RoomHeaderView, { RightButtons, LeftButtons } from './Header'; import RoomHeaderView, { RightButtons, LeftButtons } from './Header';
@ -644,6 +644,7 @@ class RoomView extends React.Component {
} }
sendMessage = (message, tmid) => { sendMessage = (message, tmid) => {
logEvent(events.ROOM_SEND_MESSAGE);
const { user } = this.props; const { user } = this.props;
RocketChat.sendMessage(this.rid, message, this.tmid || tmid, user).then(() => { RocketChat.sendMessage(this.rid, message, this.tmid || tmid, user).then(() => {
if (this.list && this.list.current) { if (this.list && this.list.current) {

View File

@ -65,7 +65,7 @@ class Sort extends PureComponent {
setSortPreference(param); setSortPreference(param);
RocketChat.saveSortPreference(param); RocketChat.saveSortPreference(param);
} catch (e) { } catch (e) {
logEvent(events.RL_SORT_CHANNELS_FAIL); logEvent(events.RL_SORT_CHANNELS_F);
log(e); log(e);
} }
} }

View File

@ -16,6 +16,7 @@ import { supportedBiometryLabel, changePasscode, checkHasPasscode } from '../uti
import { DisclosureImage } from '../containers/DisclosureIndicator'; import { DisclosureImage } from '../containers/DisclosureIndicator';
import { DEFAULT_AUTO_LOCK } from '../constants/localAuthentication'; import { DEFAULT_AUTO_LOCK } from '../constants/localAuthentication';
import SafeAreaView from '../containers/SafeAreaView'; import SafeAreaView from '../containers/SafeAreaView';
import { events, logEvent } from '../utils/log';
const styles = StyleSheet.create({ const styles = StyleSheet.create({
listPadding: { listPadding: {
@ -113,6 +114,7 @@ class ScreenLockConfigView extends React.Component {
} }
save = async() => { save = async() => {
logEvent(events.SLC_SAVE_SCREEN_LOCK);
const { autoLock, autoLockTime, biometry } = this.state; const { autoLock, autoLockTime, biometry } = this.state;
const serversDB = database.servers; const serversDB = database.servers;
await serversDB.action(async() => { await serversDB.action(async() => {
@ -125,10 +127,12 @@ class ScreenLockConfigView extends React.Component {
} }
changePasscode = async({ force }) => { changePasscode = async({ force }) => {
logEvent(events.SLC_CHANGE_PASSCODE);
await changePasscode({ force }); await changePasscode({ force });
} }
toggleAutoLock = () => { toggleAutoLock = () => {
logEvent(events.SLC_TOGGLE_AUTOLOCK);
this.setState(({ autoLock }) => ({ autoLock: !autoLock, autoLockTime: DEFAULT_AUTO_LOCK }), async() => { this.setState(({ autoLock }) => ({ autoLock: !autoLock, autoLockTime: DEFAULT_AUTO_LOCK }), async() => {
const { autoLock } = this.state; const { autoLock } = this.state;
if (autoLock) { if (autoLock) {
@ -143,6 +147,7 @@ class ScreenLockConfigView extends React.Component {
} }
toggleBiometry = () => { toggleBiometry = () => {
logEvent(events.SLC_TOGGLE_BIOMETRY);
this.setState(({ biometry }) => ({ biometry: !biometry }), () => this.save()); this.setState(({ biometry }) => ({ biometry: !biometry }), () => this.save());
} }
@ -152,6 +157,7 @@ class ScreenLockConfigView extends React.Component {
} }
changeAutoLockTime = (autoLockTime) => { changeAutoLockTime = (autoLockTime) => {
logEvent(events.SLC_CHANGE_AUTOLOCK_TIME);
this.setState({ autoLockTime }, () => this.save()); this.setState({ autoLockTime }, () => this.save());
} }

View File

@ -183,7 +183,6 @@ class SelectedUsersView extends React.Component {
if (this.isGroupChat() && users.length === maxUsers) { if (this.isGroupChat() && users.length === maxUsers) {
return showErrorAlert(I18n.t('Max_number_of_users_allowed_is_number', { maxUsers }), I18n.t('Oops')); return showErrorAlert(I18n.t('Max_number_of_users_allowed_is_number', { maxUsers }), I18n.t('Oops'));
} }
logEvent(events.SELECTED_USERS_ADD_USER); logEvent(events.SELECTED_USERS_ADD_USER);
addUser(user); addUser(user);
} else { } else {

View File

@ -26,7 +26,9 @@ import openLink from '../../utils/openLink';
import scrollPersistTaps from '../../utils/scrollPersistTaps'; import scrollPersistTaps from '../../utils/scrollPersistTaps';
import { showErrorAlert, showConfirmationAlert } from '../../utils/info'; import { showErrorAlert, showConfirmationAlert } from '../../utils/info';
import styles from './styles'; import styles from './styles';
import { loggerConfig, analytics } from '../../utils/log'; import {
loggerConfig, analytics, logEvent, events
} from '../../utils/log';
import { PLAY_MARKET_LINK, APP_STORE_LINK, LICENSE_LINK } from '../../constants/links'; import { PLAY_MARKET_LINK, APP_STORE_LINK, LICENSE_LINK } from '../../constants/links';
import { withTheme } from '../../theme'; import { withTheme } from '../../theme';
import SidebarView from '../SidebarView'; import SidebarView from '../SidebarView';
@ -86,6 +88,7 @@ class SettingsView extends React.Component {
} }
handleLogout = () => { handleLogout = () => {
logEvent(events.SE_LOG_OUT);
showConfirmationAlert({ showConfirmationAlert({
message: I18n.t('You_will_be_logged_out_of_this_application'), message: I18n.t('You_will_be_logged_out_of_this_application'),
callToAction: I18n.t('Logout'), callToAction: I18n.t('Logout'),
@ -97,6 +100,7 @@ class SettingsView extends React.Component {
} }
handleClearCache = () => { handleClearCache = () => {
logEvent(events.SE_CLEAR_LOCAL_SERVER_CACHE);
showConfirmationAlert({ showConfirmationAlert({
message: I18n.t('This_will_clear_all_your_offline_data'), message: I18n.t('This_will_clear_all_your_offline_data'),
callToAction: I18n.t('Clear'), callToAction: I18n.t('Clear'),
@ -114,12 +118,12 @@ class SettingsView extends React.Component {
} }
toggleCrashReport = (value) => { toggleCrashReport = (value) => {
logEvent(events.SE_TOGGLE_CRASH_REPORT);
AsyncStorage.setItem(CRASH_REPORT_KEY, JSON.stringify(value)); AsyncStorage.setItem(CRASH_REPORT_KEY, JSON.stringify(value));
const { toggleCrashReport } = this.props; const { toggleCrashReport } = this.props;
toggleCrashReport(value); toggleCrashReport(value);
loggerConfig.autoNotify = value; loggerConfig.autoNotify = value;
analytics().setAnalyticsCollectionEnabled(value); analytics().setAnalyticsCollectionEnabled(value);
if (value) { if (value) {
loggerConfig.clearBeforeSendCallbacks(); loggerConfig.clearBeforeSendCallbacks();
} else { } else {
@ -136,11 +140,13 @@ class SettingsView extends React.Component {
} }
navigateToScreen = (screen) => { navigateToScreen = (screen) => {
logEvent(events[`SE_NAVIGATE_TO_${ screen.replace('View', '').toUpperCase() }`]);
const { navigation } = this.props; const { navigation } = this.props;
navigation.navigate(screen); navigation.navigate(screen);
} }
sendEmail = async() => { sendEmail = async() => {
logEvent(events.SE_CONTACT_US);
const subject = encodeURI('React Native App Support'); const subject = encodeURI('React Native App Support');
const email = encodeURI('support@rocket.chat'); const email = encodeURI('support@rocket.chat');
const description = encodeURI(` const description = encodeURI(`
@ -150,20 +156,24 @@ class SettingsView extends React.Component {
try { try {
await Linking.openURL(`mailto:${ email }?subject=${ subject }&body=${ description }`); await Linking.openURL(`mailto:${ email }?subject=${ subject }&body=${ description }`);
} catch (e) { } catch (e) {
logEvent(events.SE_CONTACT_US_F);
showErrorAlert(I18n.t('error-email-send-failed', { message: 'support@rocket.chat' })); showErrorAlert(I18n.t('error-email-send-failed', { message: 'support@rocket.chat' }));
} }
} }
shareApp = () => { shareApp = () => {
logEvent(events.SE_SHARE_THIS_APP);
Share.share({ message: isAndroid ? PLAY_MARKET_LINK : APP_STORE_LINK }); Share.share({ message: isAndroid ? PLAY_MARKET_LINK : APP_STORE_LINK });
} }
copyServerVersion = () => { copyServerVersion = () => {
const { server } = this.props; const { server: { version } } = this.props;
this.saveToClipboard(server.version); logEvent(events.SE_COPY_SERVER_VERSION, { serverVersion: version });
this.saveToClipboard(version);
} }
copyAppVersion = () => { copyAppVersion = () => {
logEvent(events.SE_COPY_APP_VERSION, { appVersion: getReadableVersion });
this.saveToClipboard(getReadableVersion); this.saveToClipboard(getReadableVersion);
} }
@ -173,6 +183,7 @@ class SettingsView extends React.Component {
} }
onPressLicense = () => { onPressLicense = () => {
logEvent(events.SE_READ_LICENSE);
const { theme } = this.props; const { theme } = this.props;
openLink(LICENSE_LINK, theme); openLink(LICENSE_LINK, theme);
} }

View File

@ -11,7 +11,7 @@ import TextInput from '../containers/TextInput';
import EventEmitter from '../utils/events'; import EventEmitter from '../utils/events';
import Loading from '../containers/Loading'; import Loading from '../containers/Loading';
import RocketChat from '../lib/rocketchat'; import RocketChat from '../lib/rocketchat';
import log from '../utils/log'; import log, { logEvent, events } from '../utils/log';
import { LISTENER } from '../containers/Toast'; import { LISTENER } from '../containers/Toast';
import { themes } from '../constants/colors'; import { themes } from '../constants/colors';
@ -92,6 +92,7 @@ class StatusView extends React.Component {
} }
submit = async() => { submit = async() => {
logEvent(events.STATUS_DONE);
const { statusText } = this.state; const { statusText } = this.state;
const { user } = this.props; const { user } = this.props;
if (statusText !== user.statusText) { if (statusText !== user.statusText) {
@ -114,11 +115,14 @@ class StatusView extends React.Component {
try { try {
const result = await RocketChat.setUserStatus(user.status, statusText); const result = await RocketChat.setUserStatus(user.status, statusText);
if (result.success) { if (result.success) {
logEvent(events.STATUS_CUSTOM);
EventEmitter.emit(LISTENER, { message: I18n.t('Status_saved_successfully') }); EventEmitter.emit(LISTENER, { message: I18n.t('Status_saved_successfully') });
} else { } else {
logEvent(events.STATUS_CUSTOM_F);
EventEmitter.emit(LISTENER, { message: I18n.t('error-could-not-change-status') }); EventEmitter.emit(LISTENER, { message: I18n.t('error-could-not-change-status') });
} }
} catch { } catch {
logEvent(events.STATUS_CUSTOM_F);
EventEmitter.emit(LISTENER, { message: I18n.t('error-could-not-change-status') }); EventEmitter.emit(LISTENER, { message: I18n.t('error-could-not-change-status') });
} }
@ -166,6 +170,7 @@ class StatusView extends React.Component {
<ListItem <ListItem
title={I18n.t(name)} title={I18n.t(name)}
onPress={async() => { onPress={async() => {
logEvent(events[`STATUS_${ item.id.toUpperCase() }`]);
if (user.status !== item.id) { if (user.status !== item.id) {
try { try {
const result = await RocketChat.setUserStatus(item.id, statusText); const result = await RocketChat.setUserStatus(item.id, statusText);
@ -173,6 +178,7 @@ class StatusView extends React.Component {
store.dispatch(setUser({ status: item.id })); store.dispatch(setUser({ status: item.id }));
} }
} catch (e) { } catch (e) {
logEvent(events.SET_STATUS_FAIL);
log(e); log(e);
} }
} }

View File

@ -16,6 +16,7 @@ import { CustomIcon } from '../lib/Icons';
import { THEME_PREFERENCES_KEY } from '../lib/rocketchat'; import { THEME_PREFERENCES_KEY } from '../lib/rocketchat';
import { supportSystemTheme } from '../utils/deviceInfo'; import { supportSystemTheme } from '../utils/deviceInfo';
import SafeAreaView from '../containers/SafeAreaView'; import SafeAreaView from '../containers/SafeAreaView';
import { events, logEvent } from '../utils/log';
const THEME_GROUP = 'THEME_GROUP'; const THEME_GROUP = 'THEME_GROUP';
const DARK_GROUP = 'DARK_GROUP'; const DARK_GROUP = 'DARK_GROUP';
@ -96,9 +97,11 @@ class ThemeView extends React.Component {
const { value, group } = item; const { value, group } = item;
let changes = {}; let changes = {};
if (group === THEME_GROUP && currentTheme !== value) { if (group === THEME_GROUP && currentTheme !== value) {
logEvent(events.THEME_SET_THEME_GROUP, { theme_group: value });
changes = { currentTheme: value }; changes = { currentTheme: value };
} }
if (group === DARK_GROUP && darkLevel !== value) { if (group === DARK_GROUP && darkLevel !== value) {
logEvent(events.THEME_SET_DARK_LEVEL, { dark_level: value });
changes = { darkLevel: value }; changes = { darkLevel: value };
} }
this.setTheme(changes); this.setTheme(changes);