Merge pull request #2515 from hmhealey/prefs

Changed PreferenceStore to store data in memory
Этот коммит содержится в:
Joram Wilander
2016-03-23 14:22:30 -04:00
родитель aed690c589 1f46cca65c
Коммит 6275ad2ae4
8 изменённых файлов: 118 добавлений и 150 удалений

Просмотреть файл

@@ -93,12 +93,12 @@ export default class Sidebar extends React.Component {
const preferences = PreferenceStore.getCategory(Constants.Preferences.CATEGORY_DIRECT_CHANNEL_SHOW); const preferences = PreferenceStore.getCategory(Constants.Preferences.CATEGORY_DIRECT_CHANNEL_SHOW);
const directChannels = []; const directChannels = [];
for (const preference of preferences) { for (const [name, value] of preferences) {
if (preference.value !== 'true') { if (value !== 'true') {
continue; continue;
} }
const teammateId = preference.name; const teammateId = name;
let directChannel = channels.find(Utils.isDirectChannelForUser.bind(null, teammateId)); 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)) { if (!this.isLeaving.get(channel.id)) {
this.isLeaving.set(channel.id, true); this.isLeaving.set(channel.id, true);
const preference = PreferenceStore.setPreference(Constants.Preferences.CATEGORY_DIRECT_CHANNEL_SHOW, channel.teammate_id, 'false'); AsyncClient.savePreference(
Constants.Preferences.CATEGORY_DIRECT_CHANNEL_SHOW,
// bypass AsyncClient since we've already saved the updated preferences channel.teammate_id,
Client.savePreferences( 'false',
[preference],
() => { () => {
this.isLeaving.set(channel.id, false); this.isLeaving.set(channel.id, false);
}, },

Просмотреть файл

@@ -36,17 +36,22 @@ export default class TutorialIntroScreens extends React.Component {
Utils.switchChannel(ChannelStore.getByName(Constants.DEFAULT_CHANNEL)); 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(); AsyncClient.savePreference(
Preferences.TUTORIAL_STEP,
preference = PreferenceStore.setPreference(Preferences.TUTORIAL_STEP, UserStore.getCurrentId(), newValue); UserStore.getCurrentId(),
AsyncClient.savePreferences([preference]); step + 1
);
} }
skipTutorial(e) { skipTutorial(e) {
e.preventDefault(); e.preventDefault();
const preference = PreferenceStore.setPreference(Preferences.TUTORIAL_STEP, UserStore.getCurrentId(), '999');
AsyncClient.savePreferences([preference]); AsyncClient.savePreference(
Preferences.TUTORIAL_STEP,
UserStore.getCurrentId(),
999
);
} }
createScreen() { createScreen() {
switch (this.state.currentScreen) { switch (this.state.currentScreen) {

Просмотреть файл

@@ -29,12 +29,13 @@ export default class TutorialTip extends React.Component {
this.setState({show}); this.setState({show});
if (!show && this.state.currentScreen >= this.props.screens.length - 1) { 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(); AsyncClient.savePreference(
Preferences.TUTORIAL_STEP,
preference = PreferenceStore.setPreference(Preferences.TUTORIAL_STEP, UserStore.getCurrentId(), newValue); UserStore.getCurrentId(),
AsyncClient.savePreferences([preference]); step + 1
);
} }
} }
handleNext() { handleNext() {

Просмотреть файл

@@ -1,11 +1,12 @@
// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. // Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information. // 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 SettingItemMin from '../setting_item_min.jsx';
import SettingItemMax from '../setting_item_max.jsx'; import SettingItemMax from '../setting_item_max.jsx';
import Constants from 'utils/constants.jsx'; import Constants from 'utils/constants.jsx';
import PreferenceStore from 'stores/preference_store.jsx'; import PreferenceStore from 'stores/preference_store.jsx';
import UserStore from 'stores/user_store.jsx';
import {intlShape, injectIntl, defineMessages, FormattedMessage} from 'react-intl'; import {intlShape, injectIntl, defineMessages, FormattedMessage} from 'react-intl';
@@ -68,25 +69,27 @@ class AdvancedSettingsDisplay extends React.Component {
const preReleaseFeaturesKeys = Object.keys(PreReleaseFeatures); const preReleaseFeaturesKeys = Object.keys(PreReleaseFeatures);
const advancedSettings = PreferenceStore.getCategory(Constants.Preferences.CATEGORY_ADVANCED_SETTINGS); const advancedSettings = PreferenceStore.getCategory(Constants.Preferences.CATEGORY_ADVANCED_SETTINGS);
const settings = { const settings = {
send_on_ctrl_enter: PreferenceStore.getPreference( send_on_ctrl_enter: PreferenceStore.get(
Constants.Preferences.CATEGORY_ADVANCED_SETTINGS, Constants.Preferences.CATEGORY_ADVANCED_SETTINGS,
'send_on_ctrl_enter', 'send_on_ctrl_enter',
{value: 'false'} 'false'
).value )
}; };
let enabledFeatures = 0; let enabledFeatures = 0;
advancedSettings.forEach((setting) => { for (const [name, value] of advancedSettings) {
preReleaseFeaturesKeys.forEach((key) => { for (const key of preReleaseFeaturesKeys) {
const feature = PreReleaseFeatures[key]; const feature = PreReleaseFeatures[key];
if (setting.name === Constants.FeatureTogglePrefix + feature.label) {
settings[setting.name] = setting.value; if (name === Constants.FeatureTogglePrefix + feature.label) {
if (setting.value === 'true') { settings[name] = value;
enabledFeatures++;
if (value === 'true') {
enabledFeatures += 1;
}
}
} }
} }
});
});
this.state = {preReleaseFeatures: PreReleaseFeatures, settings, preReleaseFeaturesKeys, enabledFeatures}; this.state = {preReleaseFeatures: PreReleaseFeatures, settings, preReleaseFeaturesKeys, enabledFeatures};
} }
@@ -124,20 +127,21 @@ class AdvancedSettingsDisplay extends React.Component {
handleSubmit(settings) { handleSubmit(settings) {
const preferences = []; 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) => { (Array.isArray(settings) ? settings : [settings]).forEach((setting) => {
preferences.push( preferences.push({
PreferenceStore.setPreference( user_id: userId,
Constants.Preferences.CATEGORY_ADVANCED_SETTINGS, category: Constants.Preferences.CATEGORY_ADVANCED_SETTINGS,
setting, name: setting,
String(this.state.settings[setting]) value: this.state.settings[setting]
) });
);
}); });
Client.savePreferences(preferences, AsyncClient.savePreferences(
preferences,
() => { () => {
PreferenceStore.emitChange();
this.updateSection(''); this.updateSection('');
}, },
(err) => { (err) => {

Просмотреть файл

@@ -6,24 +6,22 @@ import SettingItemMax from '../setting_item_max.jsx';
import ManageLanguages from './manage_languages.jsx'; import ManageLanguages from './manage_languages.jsx';
import ThemeSetting from './user_settings_theme.jsx'; import ThemeSetting from './user_settings_theme.jsx';
import * as AsyncClient from 'utils/async_client.jsx';
import PreferenceStore from 'stores/preference_store.jsx'; import PreferenceStore from 'stores/preference_store.jsx';
import UserStore from 'stores/user_store.jsx';
import * as Utils from 'utils/utils.jsx'; import * as Utils from 'utils/utils.jsx';
import * as I18n from 'i18n/i18n.jsx'; import * as I18n from 'i18n/i18n.jsx';
import Constants from 'utils/constants.jsx'; import Constants from 'utils/constants.jsx';
const Preferences = Constants.Preferences;
import {savePreferences} from 'utils/client.jsx';
import {FormattedMessage} from 'react-intl'; import {FormattedMessage} from 'react-intl';
function getDisplayStateFromStores() { 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 { return {
militaryTime: militaryTime.value, militaryTime: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, 'use_military_time', 'false'),
nameFormat: nameFormat.value, nameFormat: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, 'name_format', 'username'),
selectedFont: selectedFont.value 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(); this.state = getDisplayStateFromStores();
} }
handleSubmit() { handleSubmit() {
const timePreference = PreferenceStore.setPreference(Constants.Preferences.CATEGORY_DISPLAY_SETTINGS, 'use_military_time', this.state.militaryTime); const userId = UserStore.getCurrentId();
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);
savePreferences([timePreference, namePreference, fontPreference], 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
};
AsyncClient.savePreferences([timePreference, namePreference, fontPreference],
() => { () => {
PreferenceStore.emitChange();
this.updateSection(''); this.updateSection('');
}, },
(err) => { (err) => {

Просмотреть файл

@@ -137,11 +137,7 @@ function preRenderSetup(callwhendone) {
function preLoggedIn(nextState, replace, callback) { function preLoggedIn(nextState, replace, callback) {
const d1 = Client.getAllPreferences( const d1 = Client.getAllPreferences(
(data) => { (data) => {
if (!data) { PreferenceStore.setPreferencesFromServer(data);
return;
}
PreferenceStore.setPreferences(data);
}, },
(err) => { (err) => {
AsyncClient.dispatchError(err, 'getAllPreferences'); AsyncClient.dispatchError(err, 'getAllPreferences');
@@ -197,6 +193,7 @@ function onLoggedOut(nextState) {
BrowserStore.signalLogout(); BrowserStore.signalLogout();
BrowserStore.clear(); BrowserStore.clear();
ErrorStore.clearLastError(); ErrorStore.clearLastError();
PreferenceStore.clear();
}, },
() => { () => {
browserHistory.push('/' + teamName + '/login'); browserHistory.push('/' + teamName + '/login');

Просмотреть файл

@@ -4,143 +4,80 @@
import Constants from 'utils/constants.jsx'; import Constants from 'utils/constants.jsx';
const ActionTypes = Constants.ActionTypes; const ActionTypes = Constants.ActionTypes;
import AppDispatcher from '../dispatcher/app_dispatcher.jsx'; import AppDispatcher from '../dispatcher/app_dispatcher.jsx';
import BrowserStore from './browser_store.jsx';
import EventEmitter from 'events'; import EventEmitter from 'events';
import UserStore from 'stores/user_store.jsx';
const CHANGE_EVENT = 'change'; const CHANGE_EVENT = 'change';
function getPreferenceKey(category, name) {
return `${category}-${name}`;
}
function getPreferenceKeyForModel(preference) {
return `${preference.category}-${preference.name}`;
}
class PreferenceStoreClass extends EventEmitter { class PreferenceStoreClass extends EventEmitter {
constructor() { constructor() {
super(); 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.handleEventPayload = this.handleEventPayload.bind(this);
this.dispatchToken = AppDispatcher.register(this.handleEventPayload); this.dispatchToken = AppDispatcher.register(this.handleEventPayload);
this.preferences = new Map();
} }
getAllPreferences() { getKey(category, name) {
return new Map(BrowserStore.getItem('preferences', [])); return `${category}--${name}`;
} }
get(category, name, defaultValue = '') { 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 defaultValue;
} }
return preference.value || defaultValue; return this.preferences.get(key);
} }
getBool(category, name, defaultValue = false) { 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; return defaultValue;
} }
// prevent a non-false default value from being returned instead of an actual false value return this.preferences.get(key) !== 'false';
if (preference.value === 'false') {
return false;
}
return (preference.value !== 'false') || defaultValue;
} }
getInt(category, name, defaultValue = 0) { 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; return defaultValue;
} }
// prevent a non-zero default value from being returned instead of an actual 0 value return parseInt(this.preferences.get(key), 10);
if (preference.value === '0') {
return 0;
}
return parseInt(preference.value, 10) || defaultValue;
}
getPreference(category, name, defaultValue = {}) {
return this.getAllPreferences().get(getPreferenceKey(category, name)) || defaultValue;
} }
getCategory(category) { getCategory(category) {
return this.getPreferencesWhere((preference) => (preference.category === category)); const prefix = category + '--';
}
getPreferencesWhere(pred) { const preferences = new Map();
const all = this.getAllPreferences();
const preferences = [];
for (const [, preference] of all) { for (const [key, value] of this.preferences) {
if (pred(preference)) { if (key.startsWith(prefix)) {
preferences.push(preference); preferences.set(key.substring(prefix.length), value);
} }
} }
return preferences; 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) { setPreference(category, name, value) {
const preferences = this.getAllPreferences(); this.preferences.set(this.getKey(category, name), value);
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;
} }
setPreferences(newPreferences) { setPreferencesFromServer(newPreferences) {
const preferences = this.getAllPreferences();
for (const preference of 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() { emitChange() {
@@ -166,7 +103,7 @@ class PreferenceStoreClass extends EventEmitter {
break; break;
} }
case ActionTypes.RECEIVED_PREFERENCES: case ActionTypes.RECEIVED_PREFERENCES:
this.setPreferences(action.preferences); this.setPreferencesFromServer(action.preferences);
this.emitChange(); this.emitChange();
break; break;
} }

Просмотреть файл

@@ -673,9 +673,9 @@ export function getStatuses() {
const preferences = PreferenceStore.getCategory(Constants.Preferences.CATEGORY_DIRECT_CHANNEL_SHOW); const preferences = PreferenceStore.getCategory(Constants.Preferences.CATEGORY_DIRECT_CHANNEL_SHOW);
const teammateIds = []; const teammateIds = [];
for (const preference of preferences) { for (const [name, value] of preferences) {
if (preference.value === 'true') { if (value === 'true') {
teammateIds.push(preference.name); 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) { export function savePreferences(preferences, success, error) {
client.savePreferences( client.savePreferences(
preferences, preferences,