-
-
Notifications
You must be signed in to change notification settings - Fork 827
DnD Ordered TagPanel #1653
DnD Ordered TagPanel #1653
Changes from 37 commits
8178496
82a95f0
a8a650c
7aa5dce
4af7def
35a108e
a9cc8eb
8f88995
7e1f1cd
65d8833
ee6df10
1251544
7255096
31a52c1
53e7232
8f07744
df88b71
991ea4e
aa91409
0b38bf5
8d2d3e6
a120335
3e532e3
60d8ebb
13925db
d5534a9
cc30b8f
5de0559
42c1f3c
a8b245d
f38690f
e1ea8f0
a653ece
ddf5dba
31ea092
fe6b7c0
950f591
6b02f59
629cd13
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
/* | ||
Copyright 2017 New Vector 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 { asyncAction } from './actionCreators'; | ||
|
||
const GroupActions = {}; | ||
|
||
/** | ||
* Create a GroupActions.fetchJoinedGroups action that represents an | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is still incorrect |
||
* asyncronous request to fetch the groups to which a user is joined. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. asynchronous |
||
* | ||
* @param {MatrixClient} matrixClient the matrix client to query. | ||
* @returns {function} an asyncronous action of type | ||
* GroupActions.fetchJoinedGroups. | ||
*/ | ||
GroupActions.fetchJoinedGroups = function(matrixClient) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. needs more docs |
||
return asyncAction('GroupActions.fetchJoinedGroups', () => matrixClient.getJoinedGroups()); | ||
}; | ||
|
||
export default GroupActions; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
/* | ||
Copyright 2017 New Vector 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 dis from '../dispatcher'; | ||
|
||
// TODO: migrate from sync_state to MatrixActions.sync so that more js-sdk events | ||
// become dispatches in the same place. | ||
/** | ||
* Create a MatrixActions.sync action that represents a MatrixClient `sync` event, | ||
* each parameter mapping to a key-value in the action. | ||
* | ||
* @param {MatrixClient} matrixClient the matrix client | ||
* @param {string} state the current sync state. | ||
* @param {string} prevState the previous sync state. | ||
* @returns {Object} an action of type MatrixActions.sync. | ||
*/ | ||
function createSyncAction(matrixClient, state, prevState) { | ||
return { | ||
action: 'MatrixActions.sync', | ||
state, | ||
prevState, | ||
matrixClient, | ||
}; | ||
} | ||
|
||
/** | ||
* @typedef AccountDataAction | ||
* @type {Object} | ||
* @property {string} action 'MatrixActions.accountData'. | ||
* @property {MatrixEvent} event the MatrixEvent that triggered the dispatch. | ||
* @property {string} event_type the type of the MatrixEvent, e.g. "m.direct". | ||
* @property {Object} event_content the content of the MatrixEvent. | ||
*/ | ||
|
||
/** | ||
* Create a MatrixActions.accountData action that represents a MatrixClient `accountData` | ||
* matrix event. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ditto There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (it would help my brain if you could give some examples of what |
||
* | ||
* @param {MatrixClient} matrixClient the matrix client. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why do we pass this in, given it's ignored? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Basically so that we can handle both action creators the same in |
||
* @param {MatrixEvent} accountDataEvent the account data event. | ||
* @returns {AccountDataAction} an action of type MatrixActions.accountData. | ||
*/ | ||
function createAccountDataAction(matrixClient, accountDataEvent) { | ||
return { | ||
action: 'MatrixActions.accountData', | ||
event: accountDataEvent, | ||
event_type: accountDataEvent.getType(), | ||
event_content: accountDataEvent.getContent(), | ||
}; | ||
} | ||
|
||
/** | ||
* This object is responsible for dispatching actions when certain events are emitted by | ||
* the given MatrixClient. | ||
*/ | ||
export default { | ||
// A list of callbacks to call to unregister all listeners added | ||
_matrixClientListenersStop: [], | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. could probably do with a comment here too |
||
|
||
/** | ||
* Start listening to certain events from the MatrixClient and dispatch actions when | ||
* they are emitted. | ||
* @param {MatrixClient} matrixClient the MatrixClient to listen to events from | ||
*/ | ||
start(matrixClient) { | ||
this._addMatrixClientListener(matrixClient, 'sync', createSyncAction); | ||
this._addMatrixClientListener(matrixClient, 'accountData', createAccountDataAction); | ||
}, | ||
|
||
/** | ||
* Start listening to events of type eventName on matrixClient and when they are emitted, | ||
* dispatch an action created by the actionCreator function. | ||
* @param {MatrixClient} matrixClient a MatrixClient to register a listener with. | ||
* @param {string} eventName the event to listen to on MatrixClient. | ||
* @param {function} actionCreator a function that should return an action to dispatch | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. could you also specify that the function will be passed the MatrixClient event? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm assuming you meant MatrixClient itself There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. both, but yes. |
||
* when given the MatrixClient as an argument as well as | ||
* arguments emitted in the MatrixClient event. | ||
*/ | ||
_addMatrixClientListener(matrixClient, eventName, actionCreator) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I know this is internal, but it's opaque enough that it could do with some comments |
||
const listener = (...args) => { | ||
dis.dispatch(actionCreator(matrixClient, ...args)); | ||
}; | ||
matrixClient.on(eventName, listener); | ||
this._matrixClientListenersStop.push(() => { | ||
matrixClient.removeListener(eventName, listener); | ||
}); | ||
}, | ||
|
||
/** | ||
* Stop listening to events. | ||
*/ | ||
stop() { | ||
this._matrixClientListenersStop.forEach((stopListener) => stopListener()); | ||
}, | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
/* | ||
Copyright 2017 New Vector 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 Analytics from '../Analytics'; | ||
import { asyncAction } from './actionCreators'; | ||
import TagOrderStore from '../stores/TagOrderStore'; | ||
|
||
const TagOrderActions = {}; | ||
|
||
/** | ||
* Create a TagOrderActions.commitTagOrdering action that represents an | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. as with GroupActions.fetchJoinedGroups, I don't think this is correct. |
||
* asyncronous request to commit TagOrderStore.getOrderedTags() to account | ||
* data. | ||
* | ||
* @param {MatrixClient} matrixClient the matrix client to set the account | ||
* data on. | ||
* @returns {function} an asyncronous action of type | ||
* TagOrderActions.commitTagOrdering. | ||
*/ | ||
TagOrderActions.commitTagOrdering = function(matrixClient) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. needs docs |
||
return asyncAction('TagOrderActions.commitTagOrdering', () => { | ||
// Only commit tags if the state is ready, i.e. not null | ||
const tags = TagOrderStore.getOrderedTags(); | ||
if (!tags) { | ||
return; | ||
} | ||
|
||
Analytics.trackEvent('TagOrderActions', 'commitTagOrdering'); | ||
return matrixClient.setAccountData('im.vector.web.tag_ordering', {tags}); | ||
}); | ||
}; | ||
|
||
export default TagOrderActions; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
/* | ||
Copyright 2017 New Vector 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. | ||
*/ | ||
|
||
/** | ||
* Create an asynchronous action creator that will dispatch actions indicating | ||
* the current status of the promise returned by fn. | ||
* @param {string} id the id to give the dispatched actions. This is given a | ||
* suffix determining whether it is pending, successful or | ||
* a failure. | ||
* @param {function} fn a function that returns a Promise. | ||
* @returns {function} an asyncronous action creator - a function that uses its | ||
* single argument as a dispatch function. | ||
*/ | ||
export function asyncAction(id, fn) { | ||
return (dispatch) => { | ||
dispatch({action: id + '.pending'}); | ||
fn().then((result) => { | ||
dispatch({action: id + '.success', result}); | ||
}).catch((err) => { | ||
dispatch({action: id + '.failure', err}); | ||
}); | ||
}; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,6 +18,8 @@ limitations under the License. | |
|
||
import * as Matrix from 'matrix-js-sdk'; | ||
import React from 'react'; | ||
import { DragDropContext } from 'react-dnd'; | ||
import HTML5Backend from 'react-dnd-html5-backend'; | ||
|
||
import { KeyCode, isOnlyCtrlOrCmdKeyEvent } from '../../Keyboard'; | ||
import Notifier from '../../Notifier'; | ||
|
@@ -38,7 +40,7 @@ import SettingsStore from "../../settings/SettingsStore"; | |
* | ||
* Components mounted below us can access the matrix client via the react context. | ||
*/ | ||
export default React.createClass({ | ||
const LoggedInView = React.createClass({ | ||
displayName: 'LoggedInView', | ||
|
||
propTypes: { | ||
|
@@ -344,3 +346,5 @@ export default React.createClass({ | |
); | ||
}, | ||
}); | ||
|
||
export default DragDropContext(HTML5Backend)(LoggedInView); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I know little about react-dnd but I assume this still allows us to have other drag-n-drop contexts within it (ie. is it going to break the RoomTile DND?) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The point of moving it to the root LoggedInView is such that we can actually do DnD wherever we please. The instructions said to wrap the entire app, using two contexts (on e.g. TagPanel and LeftPanel) causes bugs. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ok 👍 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not aiui.
It returns an action creator: ie, a function which, when called, will start such a request and create such a (set of) actions.