forked from matrix/element-web
Merge branch 'develop' into kegan/controller-merging4
This commit is contained in:
commit
83b3702769
|
@ -288,6 +288,7 @@ module.exports = {
|
|||
|
||||
fillSpace: function() {
|
||||
if (!this.refs.messagePanel) return;
|
||||
if (this.state.searchResults) return; // TODO: paginate search results
|
||||
var messageWrapperScroll = this._getScrollNode();
|
||||
if (messageWrapperScroll.scrollTop < messageWrapperScroll.clientHeight && this.state.room.oldState.paginationToken) {
|
||||
this.setState({paginating: true});
|
||||
|
@ -426,7 +427,7 @@ module.exports = {
|
|||
|
||||
onSearch: function(term, scope) {
|
||||
var filter;
|
||||
if (scope === "Room") { // FIXME: should be enum
|
||||
if (scope === "Room") {
|
||||
filter = {
|
||||
// XXX: it's unintuitive that the filter for searching doesn't have the same shape as the v2 filter API :(
|
||||
rooms: [
|
||||
|
@ -443,6 +444,14 @@ module.exports = {
|
|||
search_term: term,
|
||||
filter: filter,
|
||||
order_by: "recent",
|
||||
include_state: true,
|
||||
groupings: {
|
||||
group_by: [
|
||||
{
|
||||
key: "room_id"
|
||||
}
|
||||
]
|
||||
},
|
||||
event_context: {
|
||||
before_limit: 1,
|
||||
after_limit: 1,
|
||||
|
@ -451,9 +460,28 @@ module.exports = {
|
|||
}
|
||||
}
|
||||
}).then(function(data) {
|
||||
// for debugging:
|
||||
// data.search_categories.room_events.highlights = ["hello", "everybody"];
|
||||
|
||||
var highlights;
|
||||
if (data.search_categories.room_events.highlights &&
|
||||
data.search_categories.room_events.highlights.length > 0)
|
||||
{
|
||||
// postgres on synapse returns us precise details of the
|
||||
// strings which actually got matched for highlighting.
|
||||
// for overlapping highlights, favour longer (more specific) terms first
|
||||
highlights = data.search_categories.room_events.highlights
|
||||
.sort(function(a, b) { b.length - a.length });
|
||||
}
|
||||
else {
|
||||
// sqlite doesn't, so just try to highlight the literal search term
|
||||
highlights = [ term ];
|
||||
}
|
||||
|
||||
self.setState({
|
||||
searchTerm: term,
|
||||
highlights: highlights,
|
||||
searchResults: data,
|
||||
searchScope: scope,
|
||||
});
|
||||
}, function(error) {
|
||||
var ErrorDialog = sdk.getComponent("organisms.ErrorDialog");
|
||||
|
@ -466,20 +494,34 @@ module.exports = {
|
|||
|
||||
getEventTiles: function() {
|
||||
var DateSeparator = sdk.getComponent('molecules.DateSeparator');
|
||||
var cli = MatrixClientPeg.get();
|
||||
|
||||
var ret = [];
|
||||
var count = 0;
|
||||
|
||||
var EventTile = sdk.getComponent('messages.Event');
|
||||
var self = this;
|
||||
|
||||
if (this.state.searchResults) {
|
||||
// XXX: this dance is foul, due to the results API not returning sorted results
|
||||
if (this.state.searchResults &&
|
||||
this.state.searchResults.search_categories.room_events.results &&
|
||||
this.state.searchResults.search_categories.room_events.groups)
|
||||
{
|
||||
// XXX: this dance is foul, due to the results API not directly returning sorted results
|
||||
var results = this.state.searchResults.search_categories.room_events.results;
|
||||
var eventIds = Object.keys(results);
|
||||
var roomIdGroups = this.state.searchResults.search_categories.room_events.groups.room_id;
|
||||
|
||||
Object.keys(roomIdGroups)
|
||||
.sort(function(a, b) { roomIdGroups[a].order - roomIdGroups[b].order }) // WHY NOT RETURN AN ORDERED ARRAY?!?!?!
|
||||
.forEach(function(roomId)
|
||||
{
|
||||
// XXX: todo: merge overlapping results somehow?
|
||||
// XXX: why doesn't searching on name work?
|
||||
var resultList = eventIds.map(function(key) { return results[key]; }); // .sort(function(a, b) { b.rank - a.rank });
|
||||
for (var i = 0; i < resultList.length; i++) {
|
||||
if (self.state.searchScope === 'All') {
|
||||
ret.push(<li key={ roomId }><h1>Room: { cli.getRoom(roomId).name }</h1></li>);
|
||||
}
|
||||
|
||||
var resultList = roomIdGroups[roomId].results.map(function(eventId) { return results[eventId]; });
|
||||
for (var i = resultList.length - 1; i >= 0; i--) {
|
||||
var ts1 = resultList[i].result.origin_server_ts;
|
||||
ret.push(<li key={ts1 + "-search"}><DateSeparator ts={ts1}/></li>); // Rank: {resultList[i].rank}
|
||||
var mxEv = new Matrix.MatrixEvent(resultList[i].result);
|
||||
|
@ -490,7 +532,7 @@ module.exports = {
|
|||
}
|
||||
}
|
||||
if (EventTile.haveTileForEvent(mxEv)) {
|
||||
ret.push(<li key={mxEv.getId() + "+0"}><EventTile mxEvent={mxEv} searchTerm={this.state.searchTerm}/></li>);
|
||||
ret.push(<li key={mxEv.getId() + "+0"}><EventTile mxEvent={mxEv} highlights={self.state.highlights}/></li>);
|
||||
}
|
||||
if (resultList[i].context.events_after[0]) {
|
||||
var mxEv2 = new Matrix.MatrixEvent(resultList[i].context.events_after[0]);
|
||||
|
@ -499,6 +541,7 @@ module.exports = {
|
|||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -530,7 +573,7 @@ module.exports = {
|
|||
var ts0 = this.state.room.timeline[i - 1].getTs();
|
||||
var ts1 = this.state.room.timeline[i].getTs();
|
||||
if (new Date(ts0).toDateString() !== new Date(ts1).toDateString()) {
|
||||
dateSeparator = <DateSeparator key={ts1} ts={ts1}/>;
|
||||
dateSeparator = <li key={ts1}><DateSeparator key={ts1} ts={ts1}/></li>;
|
||||
continuation = false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,8 +15,7 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
.mx_MemberAvatar {
|
||||
/* commenting this out as it breaks on FF seemingly */
|
||||
/* position: relative; */
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.mx_MemberAvatar_initial {
|
||||
|
|
|
@ -22,7 +22,12 @@ html {
|
|||
}
|
||||
|
||||
body {
|
||||
font-family: 'Myriad Pro', Helvetica, Arial, Sans-Serif;
|
||||
/* Myriad Pro lacks combining diacritics, so these will fall through
|
||||
to the next font. Helevetica's diacritics however do not combine
|
||||
nicely with Myriad Pro (on OSX, at least) and result in a huge
|
||||
horizontal mess. Arial empirically gets it right, hence prioritising
|
||||
Arial here. */
|
||||
font-family: 'Myriad Pro', Arial, Helvetica, Sans-Serif;
|
||||
font-size: 16px;
|
||||
color: #454545;
|
||||
border: 0px;
|
||||
|
|
|
@ -16,4 +16,5 @@ limitations under the License.
|
|||
|
||||
.mx_EventAsTextTile {
|
||||
opacity: 0.5;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ limitations under the License.
|
|||
margin-left: -73px;
|
||||
margin-top: -4px;
|
||||
float: left;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.mx_EventTile_avatar img {
|
||||
|
@ -44,6 +45,7 @@ limitations under the License.
|
|||
font-size: 14px;
|
||||
margin-bottom: 4px;
|
||||
display: block;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
.mx_EventTile .mx_MessageTimestamp {
|
||||
|
@ -63,6 +65,7 @@ limitations under the License.
|
|||
.mx_MessageTile_content {
|
||||
display: block;
|
||||
margin-right: 100px;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
/* Various markdown overrides */
|
||||
|
@ -87,6 +90,12 @@ limitations under the License.
|
|||
color: #76cfa6;
|
||||
}
|
||||
|
||||
.mx_MessageTile_content .markdown-body .hljs {
|
||||
display: inherit ! important;
|
||||
}
|
||||
|
||||
/* end of overrides */
|
||||
|
||||
.mx_MessageTile_searchHighlight {
|
||||
background-color: #76cfa6;
|
||||
color: #fff;
|
||||
|
|
|
@ -37,8 +37,10 @@ limitations under the License.
|
|||
}
|
||||
|
||||
.mx_MemberInfo_profileField {
|
||||
opacity: 0.6;
|
||||
font-color: #999999;
|
||||
font-size: 14px;
|
||||
position: relative;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.mx_MemberInfo_buttons {
|
||||
|
|
|
@ -98,10 +98,6 @@ limitations under the License.
|
|||
opacity: 0.25;
|
||||
}
|
||||
|
||||
.mx_MemberTile_zalgo {
|
||||
font-family: Helvetica, Arial, Sans-Serif;
|
||||
}
|
||||
|
||||
.mx_MemberTile:hover .mx_MessageTimestamp {
|
||||
display: block;
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ limitations under the License.
|
|||
box-shadow: none;
|
||||
|
||||
/* needed for FF */
|
||||
font-family: 'Myriad Pro', Helvetica, Arial, Sans-Serif;
|
||||
font-family: 'Myriad Pro', Arial, Helvetica, Sans-Serif;
|
||||
}
|
||||
|
||||
/* hack for FF as vertical alignment of custom placeholder text is broken */
|
||||
|
|
|
@ -111,6 +111,7 @@ limitations under the License.
|
|||
|
||||
.mx_RoomHeader_nametext {
|
||||
display: inline-block;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
.mx_RoomHeader_settingsButton {
|
||||
|
|
|
@ -13,8 +13,3 @@ 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.
|
||||
*/
|
||||
|
||||
.mx_SenderProfile_zalgo {
|
||||
font-family: Helvetica, Arial, Sans-Serif;
|
||||
display: table-row ! important;
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ limitations under the License.
|
|||
}
|
||||
|
||||
.mx_MemberList_invite {
|
||||
font-family: 'Myriad Pro', Helvetica, Arial, Sans-Serif;
|
||||
font-family: 'Myriad Pro', Arial, Helvetica, Sans-Serif;
|
||||
border-radius: 3px;
|
||||
border: 1px solid #f0f0f0;
|
||||
padding: 9px;
|
||||
|
|
|
@ -125,7 +125,7 @@ limitations under the License.
|
|||
clear: both;
|
||||
}
|
||||
|
||||
.mx_RoomView_MessageList > h2 {
|
||||
.mx_RoomView_MessageList h2 {
|
||||
clear: both;
|
||||
margin-top: 32px;
|
||||
margin-bottom: 8px;
|
||||
|
|
|
@ -50,12 +50,10 @@ skin['messages.TextualEvent'] = require('matrix-react-sdk/lib/components/views/m
|
|||
skin['messages.MRoomMemberEvent'] = require('matrix-react-sdk/lib/components/views/messages/MRoomMemberEvent');
|
||||
skin['messages.Event'] = require('matrix-react-sdk/lib/components/views/messages/Event');
|
||||
skin['messages.Message'] = require('matrix-react-sdk/lib/components/views/messages/Message');
|
||||
skin['messages.MEmoteMessage'] = require('matrix-react-sdk/lib/components/views/messages/MEmoteMessage');
|
||||
skin['messages.MFileMessage'] = require('matrix-react-sdk/lib/components/views/messages/MFileMessage');
|
||||
skin['messages.MImageMessage'] = require('matrix-react-sdk/lib/components/views/messages/MImageMessage');
|
||||
skin['messages.MNoticeMessage'] = require('matrix-react-sdk/lib/components/views/messages/MNoticeMessage');
|
||||
skin['messages.MTextMessage'] = require('matrix-react-sdk/lib/components/views/messages/MTextMessage');
|
||||
skin['messages.MVideoMessage'] = require('matrix-react-sdk/lib/components/views/messages/MVideoMessage');
|
||||
skin['messages.TextualMessage'] = require('matrix-react-sdk/lib/components/views/messages/TextualMessage');
|
||||
skin['messages.UnknownMessage'] = require('matrix-react-sdk/lib/components/views/messages/UnknownMessage');
|
||||
|
||||
skin['rooms.MemberInfo'] = require('matrix-react-sdk/lib/components/views/rooms/MemberInfo');
|
||||
|
|
|
@ -17,11 +17,6 @@ limitations under the License.
|
|||
'use strict';
|
||||
|
||||
var React = require('react');
|
||||
var classNames = require("classnames");
|
||||
|
||||
// The Lato WOFF doesn't include sensible combining diacritics, so Chrome chokes on rendering them.
|
||||
// Revert to Arial when this happens, which on OSX works at least.
|
||||
var zalgo = /[\u0300-\u036f\u1ab0-\u1aff\u1dc0-\u1dff\u20d0-\u20ff\ufe20-\ufe2f]/;
|
||||
|
||||
module.exports = React.createClass({
|
||||
displayName: 'SenderProfile',
|
||||
|
@ -30,18 +25,12 @@ module.exports = React.createClass({
|
|||
var mxEvent = this.props.mxEvent;
|
||||
var name = mxEvent.sender ? mxEvent.sender.name : mxEvent.getSender();
|
||||
|
||||
var classes = classNames({
|
||||
mx_SenderProfile: true,
|
||||
// taken from https://en.wikipedia.org/wiki/Combining_character
|
||||
mx_SenderProfile_zalgo: zalgo.test(name),
|
||||
});
|
||||
|
||||
var msgtype = mxEvent.getContent().msgtype;
|
||||
if (msgtype && msgtype == 'm.emote') {
|
||||
name = ''; // emote message must include the name so don't duplicate it
|
||||
}
|
||||
return (
|
||||
<span className={classes}>
|
||||
<span className="mx_SenderProfile">
|
||||
{name} { this.props.aux }
|
||||
</span>
|
||||
);
|
||||
|
|
|
@ -291,6 +291,12 @@ module.exports = React.createClass({
|
|||
</div>;
|
||||
}
|
||||
|
||||
var messageComposer;
|
||||
if (!this.state.searchResults) {
|
||||
messageComposer =
|
||||
<MessageComposer room={this.state.room} roomView={this} uploadFile={this.uploadFile} />
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="mx_RoomView">
|
||||
<RoomHeader ref="header" room={this.state.room} editing={this.state.editingRoomSettings} onSearchClick={this.onSearchClick}
|
||||
|
@ -313,10 +319,10 @@ module.exports = React.createClass({
|
|||
<div className="mx_RoomView_statusArea">
|
||||
<div className="mx_RoomView_statusAreaBox">
|
||||
<div className="mx_RoomView_statusAreaBox_line"></div>
|
||||
{statusBar}
|
||||
{ this.state.searchResults ? null : statusBar }
|
||||
</div>
|
||||
</div>
|
||||
<MessageComposer room={this.state.room} roomView={this} uploadFile={this.uploadFile} />
|
||||
{ messageComposer }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue