mirror of
https://github.com/SchildiChat/element-web.git
synced 2024-10-01 01:26:12 -04:00
Merge branch 'develop' into kegan/controller-merging4
This commit is contained in:
commit
83b3702769
@ -288,6 +288,7 @@ module.exports = {
|
|||||||
|
|
||||||
fillSpace: function() {
|
fillSpace: function() {
|
||||||
if (!this.refs.messagePanel) return;
|
if (!this.refs.messagePanel) return;
|
||||||
|
if (this.state.searchResults) return; // TODO: paginate search results
|
||||||
var messageWrapperScroll = this._getScrollNode();
|
var messageWrapperScroll = this._getScrollNode();
|
||||||
if (messageWrapperScroll.scrollTop < messageWrapperScroll.clientHeight && this.state.room.oldState.paginationToken) {
|
if (messageWrapperScroll.scrollTop < messageWrapperScroll.clientHeight && this.state.room.oldState.paginationToken) {
|
||||||
this.setState({paginating: true});
|
this.setState({paginating: true});
|
||||||
@ -426,7 +427,7 @@ module.exports = {
|
|||||||
|
|
||||||
onSearch: function(term, scope) {
|
onSearch: function(term, scope) {
|
||||||
var filter;
|
var filter;
|
||||||
if (scope === "Room") { // FIXME: should be enum
|
if (scope === "Room") {
|
||||||
filter = {
|
filter = {
|
||||||
// XXX: it's unintuitive that the filter for searching doesn't have the same shape as the v2 filter API :(
|
// XXX: it's unintuitive that the filter for searching doesn't have the same shape as the v2 filter API :(
|
||||||
rooms: [
|
rooms: [
|
||||||
@ -443,6 +444,14 @@ module.exports = {
|
|||||||
search_term: term,
|
search_term: term,
|
||||||
filter: filter,
|
filter: filter,
|
||||||
order_by: "recent",
|
order_by: "recent",
|
||||||
|
include_state: true,
|
||||||
|
groupings: {
|
||||||
|
group_by: [
|
||||||
|
{
|
||||||
|
key: "room_id"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
event_context: {
|
event_context: {
|
||||||
before_limit: 1,
|
before_limit: 1,
|
||||||
after_limit: 1,
|
after_limit: 1,
|
||||||
@ -451,9 +460,28 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}).then(function(data) {
|
}).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({
|
self.setState({
|
||||||
searchTerm: term,
|
highlights: highlights,
|
||||||
searchResults: data,
|
searchResults: data,
|
||||||
|
searchScope: scope,
|
||||||
});
|
});
|
||||||
}, function(error) {
|
}, function(error) {
|
||||||
var ErrorDialog = sdk.getComponent("organisms.ErrorDialog");
|
var ErrorDialog = sdk.getComponent("organisms.ErrorDialog");
|
||||||
@ -466,20 +494,34 @@ module.exports = {
|
|||||||
|
|
||||||
getEventTiles: function() {
|
getEventTiles: function() {
|
||||||
var DateSeparator = sdk.getComponent('molecules.DateSeparator');
|
var DateSeparator = sdk.getComponent('molecules.DateSeparator');
|
||||||
|
var cli = MatrixClientPeg.get();
|
||||||
|
|
||||||
var ret = [];
|
var ret = [];
|
||||||
var count = 0;
|
var count = 0;
|
||||||
|
|
||||||
var EventTile = sdk.getComponent('messages.Event');
|
var EventTile = sdk.getComponent('messages.Event');
|
||||||
|
var self = this;
|
||||||
|
|
||||||
if (this.state.searchResults) {
|
if (this.state.searchResults &&
|
||||||
// XXX: this dance is foul, due to the results API not returning sorted results
|
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 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: todo: merge overlapping results somehow?
|
||||||
// XXX: why doesn't searching on name work?
|
// 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 });
|
if (self.state.searchScope === 'All') {
|
||||||
for (var i = 0; i < resultList.length; i++) {
|
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;
|
var ts1 = resultList[i].result.origin_server_ts;
|
||||||
ret.push(<li key={ts1 + "-search"}><DateSeparator ts={ts1}/></li>); // Rank: {resultList[i].rank}
|
ret.push(<li key={ts1 + "-search"}><DateSeparator ts={ts1}/></li>); // Rank: {resultList[i].rank}
|
||||||
var mxEv = new Matrix.MatrixEvent(resultList[i].result);
|
var mxEv = new Matrix.MatrixEvent(resultList[i].result);
|
||||||
@ -490,7 +532,7 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (EventTile.haveTileForEvent(mxEv)) {
|
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]) {
|
if (resultList[i].context.events_after[0]) {
|
||||||
var mxEv2 = new Matrix.MatrixEvent(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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -530,7 +573,7 @@ module.exports = {
|
|||||||
var ts0 = this.state.room.timeline[i - 1].getTs();
|
var ts0 = this.state.room.timeline[i - 1].getTs();
|
||||||
var ts1 = this.state.room.timeline[i].getTs();
|
var ts1 = this.state.room.timeline[i].getTs();
|
||||||
if (new Date(ts0).toDateString() !== new Date(ts1).toDateString()) {
|
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;
|
continuation = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,8 +15,7 @@ limitations under the License.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
.mx_MemberAvatar {
|
.mx_MemberAvatar {
|
||||||
/* commenting this out as it breaks on FF seemingly */
|
position: relative;
|
||||||
/* position: relative; */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_MemberAvatar_initial {
|
.mx_MemberAvatar_initial {
|
||||||
|
@ -22,7 +22,12 @@ html {
|
|||||||
}
|
}
|
||||||
|
|
||||||
body {
|
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;
|
font-size: 16px;
|
||||||
color: #454545;
|
color: #454545;
|
||||||
border: 0px;
|
border: 0px;
|
||||||
|
@ -16,4 +16,5 @@ limitations under the License.
|
|||||||
|
|
||||||
.mx_EventAsTextTile {
|
.mx_EventAsTextTile {
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
|
overflow-y: hidden;
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,7 @@ limitations under the License.
|
|||||||
margin-left: -73px;
|
margin-left: -73px;
|
||||||
margin-top: -4px;
|
margin-top: -4px;
|
||||||
float: left;
|
float: left;
|
||||||
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_EventTile_avatar img {
|
.mx_EventTile_avatar img {
|
||||||
@ -44,6 +45,7 @@ limitations under the License.
|
|||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
margin-bottom: 4px;
|
margin-bottom: 4px;
|
||||||
display: block;
|
display: block;
|
||||||
|
overflow-y: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_EventTile .mx_MessageTimestamp {
|
.mx_EventTile .mx_MessageTimestamp {
|
||||||
@ -63,6 +65,7 @@ limitations under the License.
|
|||||||
.mx_MessageTile_content {
|
.mx_MessageTile_content {
|
||||||
display: block;
|
display: block;
|
||||||
margin-right: 100px;
|
margin-right: 100px;
|
||||||
|
overflow-y: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Various markdown overrides */
|
/* Various markdown overrides */
|
||||||
@ -87,6 +90,12 @@ limitations under the License.
|
|||||||
color: #76cfa6;
|
color: #76cfa6;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mx_MessageTile_content .markdown-body .hljs {
|
||||||
|
display: inherit ! important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* end of overrides */
|
||||||
|
|
||||||
.mx_MessageTile_searchHighlight {
|
.mx_MessageTile_searchHighlight {
|
||||||
background-color: #76cfa6;
|
background-color: #76cfa6;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
|
@ -37,8 +37,10 @@ limitations under the License.
|
|||||||
}
|
}
|
||||||
|
|
||||||
.mx_MemberInfo_profileField {
|
.mx_MemberInfo_profileField {
|
||||||
opacity: 0.6;
|
font-color: #999999;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
|
position: relative;
|
||||||
|
background-color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_MemberInfo_buttons {
|
.mx_MemberInfo_buttons {
|
||||||
|
@ -98,10 +98,6 @@ limitations under the License.
|
|||||||
opacity: 0.25;
|
opacity: 0.25;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_MemberTile_zalgo {
|
|
||||||
font-family: Helvetica, Arial, Sans-Serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_MemberTile:hover .mx_MessageTimestamp {
|
.mx_MemberTile:hover .mx_MessageTimestamp {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,7 @@ limitations under the License.
|
|||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
|
|
||||||
/* needed for FF */
|
/* 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 */
|
/* hack for FF as vertical alignment of custom placeholder text is broken */
|
||||||
|
@ -111,6 +111,7 @@ limitations under the License.
|
|||||||
|
|
||||||
.mx_RoomHeader_nametext {
|
.mx_RoomHeader_nametext {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
overflow-y: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_RoomHeader_settingsButton {
|
.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
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
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 {
|
.mx_MemberList_invite {
|
||||||
font-family: 'Myriad Pro', Helvetica, Arial, Sans-Serif;
|
font-family: 'Myriad Pro', Arial, Helvetica, Sans-Serif;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
border: 1px solid #f0f0f0;
|
border: 1px solid #f0f0f0;
|
||||||
padding: 9px;
|
padding: 9px;
|
||||||
|
@ -125,7 +125,7 @@ limitations under the License.
|
|||||||
clear: both;
|
clear: both;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_RoomView_MessageList > h2 {
|
.mx_RoomView_MessageList h2 {
|
||||||
clear: both;
|
clear: both;
|
||||||
margin-top: 32px;
|
margin-top: 32px;
|
||||||
margin-bottom: 8px;
|
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.MRoomMemberEvent'] = require('matrix-react-sdk/lib/components/views/messages/MRoomMemberEvent');
|
||||||
skin['messages.Event'] = require('matrix-react-sdk/lib/components/views/messages/Event');
|
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.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.MFileMessage'] = require('matrix-react-sdk/lib/components/views/messages/MFileMessage');
|
||||||
skin['messages.MImageMessage'] = require('matrix-react-sdk/lib/components/views/messages/MImageMessage');
|
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.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['messages.UnknownMessage'] = require('matrix-react-sdk/lib/components/views/messages/UnknownMessage');
|
||||||
|
|
||||||
skin['rooms.MemberInfo'] = require('matrix-react-sdk/lib/components/views/rooms/MemberInfo');
|
skin['rooms.MemberInfo'] = require('matrix-react-sdk/lib/components/views/rooms/MemberInfo');
|
||||||
|
@ -17,11 +17,6 @@ limitations under the License.
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var React = require('react');
|
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({
|
module.exports = React.createClass({
|
||||||
displayName: 'SenderProfile',
|
displayName: 'SenderProfile',
|
||||||
@ -30,18 +25,12 @@ module.exports = React.createClass({
|
|||||||
var mxEvent = this.props.mxEvent;
|
var mxEvent = this.props.mxEvent;
|
||||||
var name = mxEvent.sender ? mxEvent.sender.name : mxEvent.getSender();
|
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;
|
var msgtype = mxEvent.getContent().msgtype;
|
||||||
if (msgtype && msgtype == 'm.emote') {
|
if (msgtype && msgtype == 'm.emote') {
|
||||||
name = ''; // emote message must include the name so don't duplicate it
|
name = ''; // emote message must include the name so don't duplicate it
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<span className={classes}>
|
<span className="mx_SenderProfile">
|
||||||
{name} { this.props.aux }
|
{name} { this.props.aux }
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
|
@ -206,7 +206,7 @@ module.exports = React.createClass({
|
|||||||
if (this.state.syncState === "ERROR") {
|
if (this.state.syncState === "ERROR") {
|
||||||
statusBar = (
|
statusBar = (
|
||||||
<div className="mx_RoomView_connectionLostBar">
|
<div className="mx_RoomView_connectionLostBar">
|
||||||
<img src="img/warning2.png" width="30" height="30" alt="/!\"/>
|
<img src="img/warning2.png" width="30" height="30" alt="/!\ "/>
|
||||||
<div className="mx_RoomView_connectionLostBar_textArea">
|
<div className="mx_RoomView_connectionLostBar_textArea">
|
||||||
<div className="mx_RoomView_connectionLostBar_title">
|
<div className="mx_RoomView_connectionLostBar_title">
|
||||||
Connectivity to the server has been lost.
|
Connectivity to the server has been lost.
|
||||||
@ -221,7 +221,7 @@ module.exports = React.createClass({
|
|||||||
else if (this.state.hasUnsentMessages) {
|
else if (this.state.hasUnsentMessages) {
|
||||||
statusBar = (
|
statusBar = (
|
||||||
<div className="mx_RoomView_connectionLostBar">
|
<div className="mx_RoomView_connectionLostBar">
|
||||||
<img src="img/warning2.png" width="30" height="30" alt="/!\"/>
|
<img src="img/warning2.png" width="30" height="30" alt="/!\ "/>
|
||||||
<div className="mx_RoomView_connectionLostBar_textArea">
|
<div className="mx_RoomView_connectionLostBar_textArea">
|
||||||
<div className="mx_RoomView_connectionLostBar_title">
|
<div className="mx_RoomView_connectionLostBar_title">
|
||||||
Some of your messages have not been sent.
|
Some of your messages have not been sent.
|
||||||
@ -291,6 +291,12 @@ module.exports = React.createClass({
|
|||||||
</div>;
|
</div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var messageComposer;
|
||||||
|
if (!this.state.searchResults) {
|
||||||
|
messageComposer =
|
||||||
|
<MessageComposer room={this.state.room} roomView={this} uploadFile={this.uploadFile} />
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mx_RoomView">
|
<div className="mx_RoomView">
|
||||||
<RoomHeader ref="header" room={this.state.room} editing={this.state.editingRoomSettings} onSearchClick={this.onSearchClick}
|
<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_statusArea">
|
||||||
<div className="mx_RoomView_statusAreaBox">
|
<div className="mx_RoomView_statusAreaBox">
|
||||||
<div className="mx_RoomView_statusAreaBox_line"></div>
|
<div className="mx_RoomView_statusAreaBox_line"></div>
|
||||||
{statusBar}
|
{ this.state.searchResults ? null : statusBar }
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<MessageComposer room={this.state.room} roomView={this} uploadFile={this.uploadFile} />
|
{ messageComposer }
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user