From 1f46cca65ca0669c1fc1a6fec5113f835a1a3023 Mon Sep 17 00:00:00 2001 From: Harrison Healey Date: Wed, 23 Mar 2016 13:03:12 -0400 Subject: Changed PreferenceStore to store data in memory --- webapp/components/sidebar.jsx | 15 ++- .../components/tutorial/tutorial_intro_screens.jsx | 19 ++-- webapp/components/tutorial/tutorial_tip.jsx | 11 +- .../user_settings/user_settings_advanced.jsx | 46 +++++---- .../user_settings/user_settings_display.jsx | 40 +++++--- webapp/root.jsx | 7 +- webapp/stores/preference_store.jsx | 113 +++++---------------- webapp/utils/async_client.jsx | 17 +++- 8 files changed, 118 insertions(+), 150 deletions(-) (limited to 'webapp') diff --git a/webapp/components/sidebar.jsx b/webapp/components/sidebar.jsx index 49ae1bec6..d8d825fd4 100644 --- a/webapp/components/sidebar.jsx +++ b/webapp/components/sidebar.jsx @@ -93,12 +93,12 @@ export default class Sidebar extends React.Component { const preferences = PreferenceStore.getCategory(Constants.Preferences.CATEGORY_DIRECT_CHANNEL_SHOW); const directChannels = []; - for (const preference of preferences) { - if (preference.value !== 'true') { + for (const [name, value] of preferences) { + if (value !== 'true') { continue; } - const teammateId = preference.name; + const teammateId = name; let directChannel = channels.find(Utils.isDirectChannelForUser.bind(null, teammateId)); @@ -239,11 +239,10 @@ export default class Sidebar extends React.Component { if (!this.isLeaving.get(channel.id)) { this.isLeaving.set(channel.id, true); - const preference = PreferenceStore.setPreference(Constants.Preferences.CATEGORY_DIRECT_CHANNEL_SHOW, channel.teammate_id, 'false'); - - // bypass AsyncClient since we've already saved the updated preferences - Client.savePreferences( - [preference], + AsyncClient.savePreference( + Constants.Preferences.CATEGORY_DIRECT_CHANNEL_SHOW, + channel.teammate_id, + 'false', () => { this.isLeaving.set(channel.id, false); }, diff --git a/webapp/components/tutorial/tutorial_intro_screens.jsx b/webapp/components/tutorial/tutorial_intro_screens.jsx index 5db45523e..734842cad 100644 --- a/webapp/components/tutorial/tutorial_intro_screens.jsx +++ b/webapp/components/tutorial/tutorial_intro_screens.jsx @@ -36,17 +36,22 @@ export default class TutorialIntroScreens extends React.Component { Utils.switchChannel(ChannelStore.getByName(Constants.DEFAULT_CHANNEL)); - let preference = PreferenceStore.getPreference(Preferences.TUTORIAL_STEP, UserStore.getCurrentId(), {value: '0'}); + let step = PreferenceStore.getInt(Preferences.TUTORIAL_STEP, UserStore.getCurrentId(), 0); - const newValue = (parseInt(preference.value, 10) + 1).toString(); - - preference = PreferenceStore.setPreference(Preferences.TUTORIAL_STEP, UserStore.getCurrentId(), newValue); - AsyncClient.savePreferences([preference]); + AsyncClient.savePreference( + Preferences.TUTORIAL_STEP, + UserStore.getCurrentId(), + step + 1 + ); } skipTutorial(e) { e.preventDefault(); - const preference = PreferenceStore.setPreference(Preferences.TUTORIAL_STEP, UserStore.getCurrentId(), '999'); - AsyncClient.savePreferences([preference]); + + AsyncClient.savePreference( + Preferences.TUTORIAL_STEP, + UserStore.getCurrentId(), + 999 + ); } createScreen() { switch (this.state.currentScreen) { diff --git a/webapp/components/tutorial/tutorial_tip.jsx b/webapp/components/tutorial/tutorial_tip.jsx index ab49d4b04..d93fff1b1 100644 --- a/webapp/components/tutorial/tutorial_tip.jsx +++ b/webapp/components/tutorial/tutorial_tip.jsx @@ -29,12 +29,13 @@ export default class TutorialTip extends React.Component { this.setState({show}); if (!show && this.state.currentScreen >= this.props.screens.length - 1) { - let preference = PreferenceStore.getPreference(Preferences.TUTORIAL_STEP, UserStore.getCurrentId(), {value: '0'}); + let step = PreferenceStore.getInt(Preferences.TUTORIAL_STEP, UserStore.getCurrentId(), 0); - const newValue = (parseInt(preference.value, 10) + 1).toString(); - - preference = PreferenceStore.setPreference(Preferences.TUTORIAL_STEP, UserStore.getCurrentId(), newValue); - AsyncClient.savePreferences([preference]); + AsyncClient.savePreference( + Preferences.TUTORIAL_STEP, + UserStore.getCurrentId(), + step + 1 + ); } } handleNext() { diff --git a/webapp/components/user_settings/user_settings_advanced.jsx b/webapp/components/user_settings/user_settings_advanced.jsx index 7c496f57b..4fcdc9a41 100644 --- a/webapp/components/user_settings/user_settings_advanced.jsx +++ b/webapp/components/user_settings/user_settings_advanced.jsx @@ -1,11 +1,12 @@ // Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. // See License.txt for license information. -import * as Client from 'utils/client.jsx'; +import * as AsyncClient from 'utils/async_client.jsx'; import SettingItemMin from '../setting_item_min.jsx'; import SettingItemMax from '../setting_item_max.jsx'; import Constants from 'utils/constants.jsx'; import PreferenceStore from 'stores/preference_store.jsx'; +import UserStore from 'stores/user_store.jsx'; import {intlShape, injectIntl, defineMessages, FormattedMessage} from 'react-intl'; @@ -68,25 +69,27 @@ class AdvancedSettingsDisplay extends React.Component { const preReleaseFeaturesKeys = Object.keys(PreReleaseFeatures); const advancedSettings = PreferenceStore.getCategory(Constants.Preferences.CATEGORY_ADVANCED_SETTINGS); const settings = { - send_on_ctrl_enter: PreferenceStore.getPreference( + send_on_ctrl_enter: PreferenceStore.get( Constants.Preferences.CATEGORY_ADVANCED_SETTINGS, 'send_on_ctrl_enter', - {value: 'false'} - ).value + 'false' + ) }; let enabledFeatures = 0; - advancedSettings.forEach((setting) => { - preReleaseFeaturesKeys.forEach((key) => { + for (const [name, value] of advancedSettings) { + for (const key of preReleaseFeaturesKeys) { const feature = PreReleaseFeatures[key]; - if (setting.name === Constants.FeatureTogglePrefix + feature.label) { - settings[setting.name] = setting.value; - if (setting.value === 'true') { - enabledFeatures++; + + if (name === Constants.FeatureTogglePrefix + feature.label) { + settings[name] = value; + + if (value === 'true') { + enabledFeatures += 1; } } - }); - }); + } + } this.state = {preReleaseFeatures: PreReleaseFeatures, settings, preReleaseFeaturesKeys, enabledFeatures}; } @@ -124,20 +127,21 @@ class AdvancedSettingsDisplay extends React.Component { handleSubmit(settings) { const preferences = []; + const userId = UserStore.getCurrentId(); + // this should be refactored so we can actually be certain about what type everything is (Array.isArray(settings) ? settings : [settings]).forEach((setting) => { - preferences.push( - PreferenceStore.setPreference( - Constants.Preferences.CATEGORY_ADVANCED_SETTINGS, - setting, - String(this.state.settings[setting]) - ) - ); + preferences.push({ + user_id: userId, + category: Constants.Preferences.CATEGORY_ADVANCED_SETTINGS, + name: setting, + value: this.state.settings[setting] + }); }); - Client.savePreferences(preferences, + AsyncClient.savePreferences( + preferences, () => { - PreferenceStore.emitChange(); this.updateSection(''); }, (err) => { diff --git a/webapp/components/user_settings/user_settings_display.jsx b/webapp/components/user_settings/user_settings_display.jsx index 3299588f7..e56156049 100644 --- a/webapp/components/user_settings/user_settings_display.jsx +++ b/webapp/components/user_settings/user_settings_display.jsx @@ -6,24 +6,22 @@ import SettingItemMax from '../setting_item_max.jsx'; import ManageLanguages from './manage_languages.jsx'; import ThemeSetting from './user_settings_theme.jsx'; +import * as AsyncClient from 'utils/async_client.jsx'; import PreferenceStore from 'stores/preference_store.jsx'; +import UserStore from 'stores/user_store.jsx'; import * as Utils from 'utils/utils.jsx'; import * as I18n from 'i18n/i18n.jsx'; import Constants from 'utils/constants.jsx'; +const Preferences = Constants.Preferences; -import {savePreferences} from 'utils/client.jsx'; import {FormattedMessage} from 'react-intl'; function getDisplayStateFromStores() { - const militaryTime = PreferenceStore.getPreference(Constants.Preferences.CATEGORY_DISPLAY_SETTINGS, 'use_military_time', {value: 'false'}); - const nameFormat = PreferenceStore.getPreference(Constants.Preferences.CATEGORY_DISPLAY_SETTINGS, 'name_format', {value: 'username'}); - const selectedFont = PreferenceStore.getPreference(Constants.Preferences.CATEGORY_DISPLAY_SETTINGS, 'selected_font', {value: Constants.DEFAULT_FONT}); - return { - militaryTime: militaryTime.value, - nameFormat: nameFormat.value, - selectedFont: selectedFont.value + militaryTime: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, 'use_military_time', 'false'), + nameFormat: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, 'name_format', 'username'), + selectedFont: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, 'selected_font', Constants.DEFAULT_FONT) }; } @@ -44,13 +42,29 @@ export default class UserSettingsDisplay extends React.Component { this.state = getDisplayStateFromStores(); } handleSubmit() { - const timePreference = PreferenceStore.setPreference(Constants.Preferences.CATEGORY_DISPLAY_SETTINGS, 'use_military_time', this.state.militaryTime); - const namePreference = PreferenceStore.setPreference(Constants.Preferences.CATEGORY_DISPLAY_SETTINGS, 'name_format', this.state.nameFormat); - const fontPreference = PreferenceStore.setPreference(Constants.Preferences.CATEGORY_DISPLAY_SETTINGS, 'selected_font', this.state.selectedFont); + const userId = UserStore.getCurrentId(); + + const timePreference = { + user_id: userId, + category: Preferences.CATEGORY_DISPLAY_SETTINGS, + name: 'use_military_time', + value: this.state.militaryTime + }; + const namePreference = { + user_id: userId, + category: Preferences.CATEGORY_DISPLAY_SETTINGS, + name: 'name_format', + value: this.state.nameFormat + }; + const fontPreference = { + user_id: userId, + category: Preferences.CATEGORY_DISPLAY_SETTINGS, + name: 'selected_font', + value: this.state.selectedFont + }; - savePreferences([timePreference, namePreference, fontPreference], + AsyncClient.savePreferences([timePreference, namePreference, fontPreference], () => { - PreferenceStore.emitChange(); this.updateSection(''); }, (err) => { diff --git a/webapp/root.jsx b/webapp/root.jsx index b0a6ae1ac..7462813b7 100644 --- a/webapp/root.jsx +++ b/webapp/root.jsx @@ -138,11 +138,7 @@ function preRenderSetup(callwhendone) { function preLoggedIn(nextState, replace, callback) { const d1 = Client.getAllPreferences( (data) => { - if (!data) { - return; - } - - PreferenceStore.setPreferences(data); + PreferenceStore.setPreferencesFromServer(data); }, (err) => { AsyncClient.dispatchError(err, 'getAllPreferences'); @@ -198,6 +194,7 @@ function onLoggedOut(nextState) { BrowserStore.signalLogout(); BrowserStore.clear(); ErrorStore.clearLastError(); + PreferenceStore.clear(); }, () => { browserHistory.push('/' + teamName + '/login'); diff --git a/webapp/stores/preference_store.jsx b/webapp/stores/preference_store.jsx index df77f0d51..fcfd1c426 100644 --- a/webapp/stores/preference_store.jsx +++ b/webapp/stores/preference_store.jsx @@ -4,143 +4,80 @@ import Constants from 'utils/constants.jsx'; const ActionTypes = Constants.ActionTypes; import AppDispatcher from '../dispatcher/app_dispatcher.jsx'; -import BrowserStore from './browser_store.jsx'; import EventEmitter from 'events'; -import UserStore from 'stores/user_store.jsx'; const CHANGE_EVENT = 'change'; -function getPreferenceKey(category, name) { - return `${category}-${name}`; -} - -function getPreferenceKeyForModel(preference) { - return `${preference.category}-${preference.name}`; -} - class PreferenceStoreClass extends EventEmitter { constructor() { super(); - this.getAllPreferences = this.getAllPreferences.bind(this); - this.get = this.get.bind(this); - this.getBool = this.getBool.bind(this); - this.getInt = this.getInt.bind(this); - this.getPreference = this.getPreference.bind(this); - this.getCategory = this.getCategory.bind(this); - this.getPreferencesWhere = this.getPreferencesWhere.bind(this); - this.setAllPreferences = this.setAllPreferences.bind(this); - this.setPreference = this.setPreference.bind(this); - - this.emitChange = this.emitChange.bind(this); - this.addChangeListener = this.addChangeListener.bind(this); - this.removeChangeListener = this.removeChangeListener.bind(this); - this.handleEventPayload = this.handleEventPayload.bind(this); this.dispatchToken = AppDispatcher.register(this.handleEventPayload); + + this.preferences = new Map(); } - getAllPreferences() { - return new Map(BrowserStore.getItem('preferences', [])); + getKey(category, name) { + return `${category}--${name}`; } get(category, name, defaultValue = '') { - const preference = this.getAllPreferences().get(getPreferenceKey(category, name)); + const key = this.getKey(category, name); - if (!preference) { + if (!this.preferences.has(key)) { return defaultValue; } - return preference.value || defaultValue; + return this.preferences.get(key); } getBool(category, name, defaultValue = false) { - const preference = this.getAllPreferences().get(getPreferenceKey(category, name)); + const key = this.getKey(category, name); - if (!preference) { + if (!this.preferences.has(key)) { return defaultValue; } - // prevent a non-false default value from being returned instead of an actual false value - if (preference.value === 'false') { - return false; - } - - return (preference.value !== 'false') || defaultValue; + return this.preferences.get(key) !== 'false'; } getInt(category, name, defaultValue = 0) { - const preference = this.getAllPreferences().get(getPreferenceKey(category, name)); + const key = this.getKey(category, name); - if (!preference) { + if (!this.preferences.has(key)) { return defaultValue; } - // prevent a non-zero default value from being returned instead of an actual 0 value - if (preference.value === '0') { - return 0; - } - - return parseInt(preference.value, 10) || defaultValue; - } - - getPreference(category, name, defaultValue = {}) { - return this.getAllPreferences().get(getPreferenceKey(category, name)) || defaultValue; + return parseInt(this.preferences.get(key), 10); } getCategory(category) { - return this.getPreferencesWhere((preference) => (preference.category === category)); - } + const prefix = category + '--'; - getPreferencesWhere(pred) { - const all = this.getAllPreferences(); - const preferences = []; + const preferences = new Map(); - for (const [, preference] of all) { - if (pred(preference)) { - preferences.push(preference); + for (const [key, value] of this.preferences) { + if (key.startsWith(prefix)) { + preferences.set(key.substring(prefix.length), value); } } return preferences; } - setAllPreferences(preferences) { - // note that we store the preferences as an array of key-value pairs so that we can deserialize - // it as a proper Map instead of an object - BrowserStore.setItem('preferences', [...preferences]); - } - setPreference(category, name, value) { - const preferences = this.getAllPreferences(); - - const key = getPreferenceKey(category, name); - let preference = preferences.get(key); - - if (!preference) { - preference = { - user_id: UserStore.getCurrentId(), - category, - name - }; - } - preference.value = value; - - preferences.set(key, preference); - - this.setAllPreferences(preferences); - - return preference; + this.preferences.set(this.getKey(category, name), value); } - setPreferences(newPreferences) { - const preferences = this.getAllPreferences(); - + setPreferencesFromServer(newPreferences) { for (const preference of newPreferences) { - preferences.set(getPreferenceKeyForModel(preference), preference); + this.setPreference(preference.category, preference.name, preference.value); } + } - this.setAllPreferences(preferences); + clear() { + this.preferences.clear(); } emitChange() { @@ -166,7 +103,7 @@ class PreferenceStoreClass extends EventEmitter { break; } case ActionTypes.RECEIVED_PREFERENCES: - this.setPreferences(action.preferences); + this.setPreferencesFromServer(action.preferences); this.emitChange(); break; } diff --git a/webapp/utils/async_client.jsx b/webapp/utils/async_client.jsx index d3f91bb0e..6140fd9e0 100644 --- a/webapp/utils/async_client.jsx +++ b/webapp/utils/async_client.jsx @@ -673,9 +673,9 @@ export function getStatuses() { const preferences = PreferenceStore.getCategory(Constants.Preferences.CATEGORY_DIRECT_CHANNEL_SHOW); const teammateIds = []; - for (const preference of preferences) { - if (preference.value === 'true') { - teammateIds.push(preference.name); + for (const [name, value] of preferences) { + if (value === 'true') { + teammateIds.push(name); } } @@ -756,6 +756,17 @@ export function getAllPreferences() { ); } +export function savePreference(category, name, value, success, error) { + const preference = { + user_id: UserStore.getCurrentId(), + category, + name, + value + }; + + savePreferences([preference], success, error); +} + export function savePreferences(preferences, success, error) { client.savePreferences( preferences, -- cgit v1.2.3-1-g7c22