Implement Store for ordering tags in the tag panel

This commit is contained in:
Luke Barnard 2017-12-05 14:38:17 +00:00
parent 4f58b92a14
commit 8178496457
3 changed files with 100 additions and 1 deletions

View file

@ -20,6 +20,7 @@ import { MatrixClient } from 'matrix-js-sdk';
import classNames from 'classnames';
import FilterStore from '../../stores/FilterStore';
import FlairStore from '../../stores/FlairStore';
import TagOrderStore from '../../stores/TagOrderStore';
import sdk from '../../index';
import dis from '../../dispatcher';
import { isOnlyCtrlOrCmdKeyEvent } from '../../Keyboard';
@ -115,6 +116,14 @@ export default React.createClass({
selectedTags: FilterStore.getSelectedTags(),
});
});
this._tagOrderStoreToken = TagOrderStore.addListener(() => {
if (this.unmounted) {
return;
}
this.setState({
orderedTags: TagOrderStore.getOrderedTags(),
});
});
this._fetchJoinedRooms();
},
@ -157,7 +166,13 @@ export default React.createClass({
render() {
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
const TintableSvg = sdk.getComponent('elements.TintableSvg');
const tags = this.state.joinedGroupProfiles.map((groupProfile, index) => {
const orderedGroupProfiles = this.state.orderedTags ?
this.state.joinedGroupProfiles.sort((a, b) =>
this.state.orderedTags.indexOf(a.groupId) -
this.state.orderedTags.indexOf(b.groupId),
) : this.state.joinedGroupProfiles;
const tags = orderedGroupProfiles.map((groupProfile, index) => {
return <TagTile
key={groupProfile.groupId + '_' + index}
groupProfile={groupProfile}

View file

@ -255,4 +255,8 @@ export const SETTINGS = {
default: true,
controller: new AudioNotificationsEnabledController(),
},
"TagOrderStore.orderedTags": {
supportedLevels: LEVELS_ACCOUNT_SETTINGS,
default: null,
},
};

View file

@ -0,0 +1,80 @@
/*
Copyright 2017 Vector Creations Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import {Store} from 'flux/utils';
import dis from '../dispatcher';
// import Analytics from '../Analytics';
import SettingsStore from "../settings/SettingsStore";
const INITIAL_STATE = {
orderedTags: null,
};
/**
* A class for storing application state for ordering tags in the TagPanel.
*/
class TagOrderStore extends Store {
constructor() {
super(dis);
// Initialise state
this._state = INITIAL_STATE;
}
_setState(newState) {
this._state = Object.assign(this._state, newState);
this.__emitChange();
}
__onDispatch(payload) {
switch (payload.action) {
case 'sync_state':
// Get ordering from account data, once the client has synced
if (payload.prevState === "PREPARED" && payload.state === "SYNCING") {
this._setState({
orderedTags: SettingsStore.getValue("TagOrderStore.orderedTags"),
});
}
break;
case 'all_tags':
// Initialise the state with all known tags displayed in the TagPanel
this._setState({allTags: payload.tags});
break;
case 'order_tag': {
// Puts payload.tag below payload.prevTag in the orderedTags state
const tags = SettingsStore.getValue("TagOrderStore.orderedTags") || this._state.allTags;
let orderedTags = tags.filter((t) => t !== payload.tag);
const tagPrevIx = orderedTags.indexOf(payload.prevTag);
orderedTags = [
...orderedTags.slice(0, tagPrevIx + 1),
payload.tag,
...orderedTags.slice(tagPrevIx + 1),
];
this._setState({orderedTags});
SettingsStore.setValue("TagOrderStore.orderedTags", null, "account", orderedTags);
}
break;
}
}
getOrderedTags() {
return this._state.orderedTags || SettingsStore.getValue("TagOrderStore.orderedTags");
}
}
if (global.singletonTagOrderStore === undefined) {
global.singletonTagOrderStore = new TagOrderStore();
}
export default global.singletonTagOrderStore;