-
-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Message/event pinning #5142
Message/event pinning #5142
Conversation
Signed-off-by: Travis Ralston <travpc@gmail.com>
Signed-off-by: Travis Ralston <travpc@gmail.com>
Signed-off-by: Travis Ralston <travpc@gmail.com>
Signed-off-by: Travis Ralston <travpc@gmail.com>
Signed-off-by: Travis Ralston <travpc@gmail.com>
Signed-off-by: Travis Ralston <travpc@gmail.com>
Signed-off-by: Travis Ralston <travpc@gmail.com>
Signed-off-by: Travis Ralston <travpc@gmail.com>
Signed-off-by: Travis Ralston <travpc@gmail.com>
Signed-off-by: Travis Ralston <travpc@gmail.com>
Signed-off-by: Travis Ralston <travpc@gmail.com>
Signed-off-by: Travis Ralston <travpc@gmail.com>
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.
Most of these comments are little things. The main concern is whether pinned events will fail to load for new people joining the room.
Also the format they're being stored in could lead to multiple writes clobbering each other as it's one state event with a list, but the alternative would gradually build up state since we can't delete state events, so maybe this is preferable.
@ara4n wdyt?
@@ -122,6 +133,28 @@ module.exports = React.createClass({ | |||
this.closeMenu(); | |||
}, | |||
|
|||
onPinClick: function() { | |||
MatrixClientPeg.get().getStateEvent(this.props.mxEvent.getRoomId(), 'm.room.pinned_events', '') | |||
.then(null, e => { |
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.
catch
?
|
||
'use strict'; | ||
|
||
var React = require('react'); |
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.
These should really be imports in new code
limitations under the License. | ||
*/ | ||
|
||
'use strict'; |
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.
We shouldn't really be writing this in new files
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.
copy/paste fails (as with most of the comments). will fix.
const PinnedEventTile = React.createClass({ | ||
displayName: 'PinnedEventTile', | ||
propTypes: { | ||
mxRoom: React.PropTypes.object.isRequired, |
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.
Ideally these would use the prop-types
module in new code
|
||
let unpinButton = null; | ||
if (this._canUnpin()) { | ||
unpinButton = <img src="img/cancel-red.svg" className="mx_PinnedEventTile_unpinButton" width="8" height="8" |
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.
This should probably be an AccessibleButton?
import { _t } from "matrix-react-sdk/lib/languageHandler"; | ||
import { EventTimeline } from "matrix-js-sdk"; | ||
|
||
const PinnedEventTile = React.createClass({ |
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 a huge deal but this is probably chunky enough to warrant its own file
const cli = MatrixClientPeg.get(); | ||
|
||
pinnedEvents.getContent().pinned.map(eventId => { | ||
promises.push(cli.getEventTimeline(this.props.room.getUnfilteredTimelineSet(), eventId, 0).then(timeline => { |
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.
Hmm, I don't think this will necessarily find the event as you'll only get whatever has been loaded into the unfiltered timeline set, ie. someone newly entering a room won't be able to load a pinned event posted longer ago than the brief bit of scrollback their client loads, I think.
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.
Watching the network pane, it does a request to the context API. It does try to hit the cache first though.
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.
Oh I see - I didn't realise that hit the context API! That sounds like exactly what it should be doing then.
|
||
_getPinnedTiles: function() { | ||
if (this.state.pinned.length == 0) { | ||
return <div>{ _t("No pinned messages.") }</div>; |
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.
Would we ever show this? Surely if there are no pinned messages, you'd just show nothing at the top?
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.
The pinned messages pane is a drawer that is dismissed by default. This is more to communicate to people that there's nothing to see when they pop it open.
"Unpin Message": "Unpin Message", | ||
"Jump to message": "Jump to message", | ||
"No pinned messages.": "No pinned messages.", | ||
"Loading...": "Loading...", |
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.
Ftr these will just fall back to UK English if they're not there so adding them here doesn't actually do anything
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.
The only reason I include these is to make weblate not complain about en-us being <100%.
@@ -0,0 +1,171 @@ | |||
/* |
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.
We do do it elsewhere at the moment, but generally putting components in riot-web that are referenced from react-sdk is a big no-no since it worsens react-sdk's dependency on riot-web.
For whatever it's worth, the following semantics are applied based on the event spec:
|
Signed-off-by: Travis Ralston <travpc@gmail.com>
Signed-off-by: Travis Ralston <travpc@gmail.com>
@dbkr Both sides updated. Thanks for the feedback! |
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.
OK by me - letting @ara4n take a look as it's a reasonably chunky feature
okay, i'm a terrible terrible person and had completely missed/forgotten this PR whilst submerged in funding crap over the last few weeks; sorry @turt2live! @dbkr/@turt2live please stab me in the eye (via Matrix or IRL) if this happens again... In other news, WOO!!!! This is awesome! We desperately need the feature, and this looks like a great implementation of it (modulo perhaps a little bit of CSS on my side). My only thoughts are:
This is fantastic! :D :D :D |
I have a feeling that using reactions for pinning might be a bit harder, although it might work out in the end (assuming there's some way to say "give me all the events that have an m.pinned reaction" with minimal performance loss). As for the labs setting: I meant to do that, and seemingly forgot. I'll figure out how the new system works and get this PR up to speed. |
the new system should be simpler (although I haven't touched it myself yet). And yup, using reactions would be contingent on being able to rapidly filter events in a room based on a tag, effectively. But saying "hey, give me all the events i've starred" or "give me all the pinned events" or "give me all the events tagged spam" all feel fairly reasonable things to optimise for in the long term. |
Signed-off-by: Travis Ralston <travpc@gmail.com>
@ara4n it's now behind a labs setting. It won't prevent the timeline text if someone in the room pins something, but it'll prevent the happy paths for people to pin messages (context menu and the list itself). The build error is due to matrix-org/matrix-react-sdk#1483 |
hm. how hard is it to hide the pinned messages themselves behind the labs flag? as i'm most worried that the pinned messages may surprise/break innocent users (especially until CSS is tweaked a bit)... |
The pinned messages are behind a drawer that requires a manual click, like in Discord. I've put the button behind the labs flag, so the drawer can't even open without some Hard Work. Personally I'm not a fan of pinned messages automatically showing, which is why the PR intentionally puts it behind a drawer. |
okay. i can see a real use for pinned messages being used as a topic analog, though, but let's have a play! thanks :D |
Many users have requested the ability to pin messages in a room, either for pinning the rules of the room or having more context than a topic can provide. This PR adds basic message pinning and prepares for the future of pinning threads.
This addresses #1858
Here's what it looks like (when opened):
m.room.message
events in RiotRequired partner PRs