From 72f50a8c61e279829c89ec9264894afd0de8d44d Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 19 Jun 2018 11:51:06 +0100 Subject: [PATCH 1/7] rewrite group permalinks in also Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/HtmlUtils.js | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/HtmlUtils.js b/src/HtmlUtils.js index 7ca404be31..4f66468373 100644 --- a/src/HtmlUtils.js +++ b/src/HtmlUtils.js @@ -216,10 +216,16 @@ const sanitizeHtmlParams = { m = attribs.href.match(linkifyMatrix.MATRIXTO_URL_PATTERN); if (m) { const entity = m[1]; - if (entity[0] === '@') { - attribs.href = '#/user/' + entity; - } else if (entity[0] === '#' || entity[0] === '!') { - attribs.href = '#/room/' + entity; + switch (entity[0]) { + case '@': + attribs.href = '#/user/' + entity; + break; + case '+': + attribs.href = '#/group/' + entity; + break; + case '#': case '!': + attribs.href = '#/room/' + entity; + break; } delete attribs.target; } From b79cd205a06fed509544e4d927aa0e01fe0a26fb Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 19 Jun 2018 11:52:48 +0100 Subject: [PATCH 2/7] Support autocompleting Communities Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/autocomplete/Autocompleter.js | 4 +- src/autocomplete/CommunityProvider.js | 122 ++++++++++++++++++++++++++ 2 files changed, 125 insertions(+), 1 deletion(-) create mode 100644 src/autocomplete/CommunityProvider.js diff --git a/src/autocomplete/Autocompleter.js b/src/autocomplete/Autocompleter.js index 3d30363d9f..6ad90eaebe 100644 --- a/src/autocomplete/Autocompleter.js +++ b/src/autocomplete/Autocompleter.js @@ -1,6 +1,6 @@ /* Copyright 2016 Aviral Dasgupta -Copyright 2017 New Vector Ltd +Copyright 2017, 2018 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. @@ -19,6 +19,7 @@ limitations under the License. import type {Component} from 'react'; import CommandProvider from './CommandProvider'; +import CommunityProvider from './CommunityProvider'; import DuckDuckGoProvider from './DuckDuckGoProvider'; import RoomProvider from './RoomProvider'; import UserProvider from './UserProvider'; @@ -47,6 +48,7 @@ const PROVIDERS = [ EmojiProvider, NotifProvider, CommandProvider, + CommunityProvider, DuckDuckGoProvider, ]; diff --git a/src/autocomplete/CommunityProvider.js b/src/autocomplete/CommunityProvider.js new file mode 100644 index 0000000000..db4d52fae2 --- /dev/null +++ b/src/autocomplete/CommunityProvider.js @@ -0,0 +1,122 @@ +/* +Copyright 2018 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 React from 'react'; +import { _t } from '../languageHandler'; +import AutocompleteProvider from './AutocompleteProvider'; +import MatrixClientPeg from '../MatrixClientPeg'; +import FuzzyMatcher from './FuzzyMatcher'; +import {PillCompletion} from './Components'; +import sdk from '../index'; +import _sortBy from 'lodash/sortBy'; +import {makeGroupPermalink} from "../matrix-to"; +import type {Completion, SelectionRange} from "./Autocompleter"; +import FlairStore from "../stores/FlairStore"; + +const COMMUNITY_REGEX = /(?=\+)(\S*)/g; + +function score(query, space) { + const index = space.indexOf(query); + if (index === -1) { + return Infinity; + } else { + return index; + } +} + +export default class CommunityProvider extends AutocompleteProvider { + constructor() { + super(COMMUNITY_REGEX); + this.matcher = new FuzzyMatcher([], { + keys: ['groupId', 'name', 'shortDescription'], + }); + } + + async getCompletions(query: string, selection: SelectionRange, force?: boolean = false): Array { + const BaseAvatar = sdk.getComponent('views.avatars.BaseAvatar'); + + // Disable autocompletions when composing commands because of various issues + // (see https://github.com/vector-im/riot-web/issues/4762) + if (/^(\/join|\/leave)/.test(query)) { + return []; + } + + const cli = MatrixClientPeg.get(); + let completions = []; + const {command, range} = this.getCurrentCommand(query, selection, force); + if (command) { + const joinedGroups = cli.getGroups().filter(({myMembership}) => myMembership !== 'invite'); + + const groups = (await Promise.all(joinedGroups.map(async ({avatarUrl, groupId, name=''}) => { + try { + return FlairStore.getGroupProfileCached(cli, groupId); + } catch (e) { // if FlairStore failed, rely on js-sdk's store which lacks info + return Promise.resolve({ + name, + groupId, + avatarUrl, + shortDescription: '', // js-sdk doesn't store this + }); + } + }))); + + this.matcher.setObjects(groups); + // this.matcher.setObjects(joinedGroups); + // this.matcher.setObjects(joinedGroups.map(({groupId}) => { + // const groupProfile = GroupStore.getSummary(groupId).profile; + // if (groupProfile) { + // return { + // groupId, + // name: groupProfile.name || '', + // avatarUrl: groupProfile.avatar_url, + // }; + // } + // })).filter(Boolean); + + const matchedString = command[0]; + completions = this.matcher.match(matchedString); + completions = _sortBy(completions, [ + (c) => score(matchedString, c.groupId), + (c) => c.groupId.length, + ]).map(({avatarUrl, groupId, name}) => ({ + completion: groupId, + suffix: ' ', + href: makeGroupPermalink(groupId), + component: ( + + } title={name} description={groupId} /> + ), + range, + })) + .filter((completion) => !!completion.completion && completion.completion.length > 0) + .slice(0, 4); + } + return completions; + } + + getName() { + return '💬 ' + _t('Communities'); + } + + renderCompletions(completions: [React.Component]): ?React.Component { + return
+ { completions } +
; + } +} From c1e608f1a83f359f21859a84aae7247ea32b89d1 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 19 Jun 2018 11:53:17 +0100 Subject: [PATCH 3/7] show permalinks to communities as Pills Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- res/css/views/elements/_RichText.scss | 5 +++- src/components/views/elements/Pill.js | 37 ++++++++++++++++++++++++--- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/res/css/views/elements/_RichText.scss b/res/css/views/elements/_RichText.scss index 474a123455..eda9f6a4de 100644 --- a/res/css/views/elements/_RichText.scss +++ b/res/css/views/elements/_RichText.scss @@ -4,6 +4,7 @@ .mx_UserPill, .mx_RoomPill, +.mx_GroupPill, .mx_AtRoomPill { border-radius: 16px; display: inline-block; @@ -13,7 +14,8 @@ } .mx_EventTile_body .mx_UserPill, -.mx_EventTile_body .mx_RoomPill { +.mx_EventTile_body .mx_RoomPill, +.mx_EventTile_body .mx_GroupPill { cursor: pointer; } @@ -43,6 +45,7 @@ .mx_UserPill .mx_BaseAvatar, .mx_RoomPill .mx_BaseAvatar, +.mx_GroupPill .mx_BaseAvatar, .mx_AtRoomPill .mx_BaseAvatar { position: relative; left: -3px; diff --git a/src/components/views/elements/Pill.js b/src/components/views/elements/Pill.js index 7e5ad379de..70e1d0659a 100644 --- a/src/components/views/elements/Pill.js +++ b/src/components/views/elements/Pill.js @@ -1,5 +1,6 @@ /* Copyright 2017 Vector Creations Ltd +Copyright 2018 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. @@ -22,12 +23,13 @@ import PropTypes from 'prop-types'; import MatrixClientPeg from '../../../MatrixClientPeg'; import { MATRIXTO_URL_PATTERN } from '../../../linkify-matrix'; import { getDisplayAliasForRoom } from '../../../Rooms'; +import FlairStore from "../../../stores/FlairStore"; const REGEX_MATRIXTO = new RegExp(MATRIXTO_URL_PATTERN); // For URLs of matrix.to links in the timeline which have been reformatted by // HttpUtils transformTags to relative links. This excludes event URLs (with `[^\/]*`) -const REGEX_LOCAL_MATRIXTO = /^#\/(?:user|room)\/(([\#\!\@\+])[^\/]*)$/; +const REGEX_LOCAL_MATRIXTO = /^#\/(?:user|room|group)\/(([#!@+])[^\/]*)$/; const Pill = React.createClass({ statics: { @@ -45,6 +47,7 @@ const Pill = React.createClass({ }, TYPE_USER_MENTION: 'TYPE_USER_MENTION', TYPE_ROOM_MENTION: 'TYPE_ROOM_MENTION', + TYPE_GROUP_MENTION: 'TYPE_GROUP_MENTION', TYPE_AT_ROOM_MENTION: 'TYPE_AT_ROOM_MENTION', // '@room' mention }, @@ -81,12 +84,14 @@ const Pill = React.createClass({ // The member related to the user pill member: null, + // The group related to the group pill + group: null, // The room related to the room pill room: null, }; }, - componentWillReceiveProps(nextProps) { + async componentWillReceiveProps(nextProps) { let regex = REGEX_MATRIXTO; if (nextProps.inMessage) { regex = REGEX_LOCAL_MATRIXTO; @@ -109,9 +114,11 @@ const Pill = React.createClass({ '@': Pill.TYPE_USER_MENTION, '#': Pill.TYPE_ROOM_MENTION, '!': Pill.TYPE_ROOM_MENTION, + '+': Pill.TYPE_GROUP_MENTION, }[prefix]; let member; + let group; let room; switch (pillType) { case Pill.TYPE_AT_ROOM_MENTION: { @@ -140,8 +147,17 @@ const Pill = React.createClass({ } } break; + case Pill.TYPE_GROUP_MENTION: { + const cli = MatrixClientPeg.get(); + + try { + group = await FlairStore.getGroupProfileCached(cli, resourceId); + } catch (e) { // if FlairStore failed, rely on js-sdk's store which lacks info + group = cli.getGroup(resourceId); + } + } } - this.setState({resourceId, pillType, member, room}); + this.setState({resourceId, pillType, member, group, room}); }, componentWillMount() { @@ -179,6 +195,7 @@ const Pill = React.createClass({ }); }, render: function() { + const BaseAvatar = sdk.getComponent('views.avatars.BaseAvatar'); const MemberAvatar = sdk.getComponent('avatars.MemberAvatar'); const RoomAvatar = sdk.getComponent('avatars.RoomAvatar'); @@ -229,6 +246,20 @@ const Pill = React.createClass({ } } break; + case Pill.TYPE_GROUP_MENTION: { + if (this.state.group) { + const {avatarUrl, groupId, name} = this.state.group; + const cli = MatrixClientPeg.get(); + + linkText = groupId; + if (this.props.shouldShowPillAvatar) { + avatar = ; + } + pillClass = 'mx_RoomPill' || 'mx_GroupPill'; + } + } + break; } const classes = classNames(pillClass, { From 287745f8c6315c7f5a8183f5e24142e249cb3379 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 19 Jun 2018 12:06:13 +0100 Subject: [PATCH 4/7] delint, remove unused imports and fix flow annotations Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/autocomplete/AutocompleteProvider.js | 14 +++++++------- src/autocomplete/Autocompleter.js | 3 ++- src/autocomplete/CommandProvider.js | 4 ++-- src/autocomplete/DuckDuckGoProvider.js | 5 +++-- src/autocomplete/EmojiProvider.js | 8 ++++---- src/autocomplete/NotifProvider.js | 3 ++- src/autocomplete/RoomProvider.js | 5 +++-- src/autocomplete/UserProvider.js | 8 ++++---- 8 files changed, 27 insertions(+), 23 deletions(-) diff --git a/src/autocomplete/AutocompleteProvider.js b/src/autocomplete/AutocompleteProvider.js index c93ae4fb2a..3fdb2998e7 100644 --- a/src/autocomplete/AutocompleteProvider.js +++ b/src/autocomplete/AutocompleteProvider.js @@ -1,7 +1,7 @@ /* Copyright 2016 Aviral Dasgupta Copyright 2017 Vector Creations Ltd -Copyright 2017 New Vector Ltd +Copyright 2017, 2018 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. @@ -36,7 +36,7 @@ export default class AutocompleteProvider { /** * Of the matched commands in the query, returns the first that contains or is contained by the selection, or null. */ - getCurrentCommand(query: string, selection: {start: number, end: number}, force: boolean = false): ?string { + getCurrentCommand(query: string, selection: SelectionRange, force: boolean = false): ?string { let commandRegex = this.commandRegex; if (force && this.shouldForceComplete()) { @@ -51,14 +51,14 @@ export default class AutocompleteProvider { let match; while ((match = commandRegex.exec(query)) != null) { - let matchStart = match.index, - matchEnd = matchStart + match[0].length; - if (selection.start <= matchEnd && selection.end >= matchStart) { + const start = match.index; + const end = start + match[0].length; + if (selection.start <= end && selection.end >= start) { return { command: match, range: { - start: matchStart, - end: matchEnd, + start, + end, }, }; } diff --git a/src/autocomplete/Autocompleter.js b/src/autocomplete/Autocompleter.js index 6ad90eaebe..f5fec4c502 100644 --- a/src/autocomplete/Autocompleter.js +++ b/src/autocomplete/Autocompleter.js @@ -18,6 +18,7 @@ limitations under the License. // @flow import type {Component} from 'react'; +import {Room} from 'matrix-js-sdk'; import CommandProvider from './CommandProvider'; import CommunityProvider from './CommunityProvider'; import DuckDuckGoProvider from './DuckDuckGoProvider'; @@ -56,7 +57,7 @@ const PROVIDERS = [ const PROVIDER_COMPLETION_TIMEOUT = 3000; export default class Autocompleter { - constructor(room) { + constructor(room: Room) { this.room = room; this.providers = PROVIDERS.map((p) => { return new p(room); diff --git a/src/autocomplete/CommandProvider.js b/src/autocomplete/CommandProvider.js index b162f2f92a..5e96e612c2 100644 --- a/src/autocomplete/CommandProvider.js +++ b/src/autocomplete/CommandProvider.js @@ -22,7 +22,7 @@ import { _t, _td } from '../languageHandler'; import AutocompleteProvider from './AutocompleteProvider'; import FuzzyMatcher from './FuzzyMatcher'; import {TextualCompletion} from './Components'; -import type {SelectionRange} from "./Autocompleter"; +import type {Completion, SelectionRange} from "./Autocompleter"; // TODO merge this with the factory mechanics of SlashCommands? // Warning: Since the description string will be translated in _t(result.description), all these strings below must be in i18n/strings/en_EN.json file @@ -124,7 +124,7 @@ export default class CommandProvider extends AutocompleteProvider { }); } - async getCompletions(query: string, selection: SelectionRange, force?: boolean) { + async getCompletions(query: string, selection: SelectionRange, force?: boolean): Array { const {command, range} = this.getCurrentCommand(query, selection); if (!command) return []; diff --git a/src/autocomplete/DuckDuckGoProvider.js b/src/autocomplete/DuckDuckGoProvider.js index 68d4915f56..e25ef16428 100644 --- a/src/autocomplete/DuckDuckGoProvider.js +++ b/src/autocomplete/DuckDuckGoProvider.js @@ -1,7 +1,7 @@ /* Copyright 2016 Aviral Dasgupta Copyright 2017 Vector Creations Ltd -Copyright 2017 New Vector Ltd +Copyright 2017, 2018 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. @@ -22,6 +22,7 @@ import AutocompleteProvider from './AutocompleteProvider'; import 'whatwg-fetch'; import {TextualCompletion} from './Components'; +import type {SelectionRange} from "./Autocompleter"; const DDG_REGEX = /\/ddg\s+(.+)$/g; const REFERRER = 'vector'; @@ -36,7 +37,7 @@ export default class DuckDuckGoProvider extends AutocompleteProvider { + `&format=json&no_redirect=1&no_html=1&t=${encodeURIComponent(REFERRER)}`; } - async getCompletions(query: string, selection: {start: number, end: number}) { + async getCompletions(query: string, selection: SelectionRange, force?: boolean = false) { const {command, range} = this.getCurrentCommand(query, selection); if (!query || !command) { return []; diff --git a/src/autocomplete/EmojiProvider.js b/src/autocomplete/EmojiProvider.js index f4e576ea0f..81f6144fd3 100644 --- a/src/autocomplete/EmojiProvider.js +++ b/src/autocomplete/EmojiProvider.js @@ -1,7 +1,7 @@ /* Copyright 2016 Aviral Dasgupta Copyright 2017 Vector Creations Ltd -Copyright 2017 New Vector Ltd +Copyright 2017, 2018 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. @@ -19,11 +19,11 @@ limitations under the License. import React from 'react'; import { _t } from '../languageHandler'; import AutocompleteProvider from './AutocompleteProvider'; -import {emojioneList, shortnameToImage, shortnameToUnicode, asciiRegexp, unicodeRegexp} from 'emojione'; +import {shortnameToUnicode, asciiRegexp, unicodeRegexp} from 'emojione'; import FuzzyMatcher from './FuzzyMatcher'; import sdk from '../index'; import {PillCompletion} from './Components'; -import type {SelectionRange, Completion} from './Autocompleter'; +import type {Completion, SelectionRange} from './Autocompleter'; import _uniq from 'lodash/uniq'; import _sortBy from 'lodash/sortBy'; import SettingsStore from "../settings/SettingsStore"; @@ -95,7 +95,7 @@ export default class EmojiProvider extends AutocompleteProvider { }); } - async getCompletions(query: string, selection: SelectionRange) { + async getCompletions(query: string, selection: SelectionRange, force?: boolean): Array { if (SettingsStore.getValue("MessageComposerInput.dontSuggestEmoji")) { return []; // don't give any suggestions if the user doesn't want them } diff --git a/src/autocomplete/NotifProvider.js b/src/autocomplete/NotifProvider.js index b7ac645525..842fb4fb18 100644 --- a/src/autocomplete/NotifProvider.js +++ b/src/autocomplete/NotifProvider.js @@ -20,6 +20,7 @@ import { _t } from '../languageHandler'; import MatrixClientPeg from '../MatrixClientPeg'; import {PillCompletion} from './Components'; import sdk from '../index'; +import type {Completion, SelectionRange} from "./Autocompleter"; const AT_ROOM_REGEX = /@\S*/g; @@ -29,7 +30,7 @@ export default class NotifProvider extends AutocompleteProvider { this.room = room; } - async getCompletions(query: string, selection: {start: number, end: number}, force = false) { + async getCompletions(query: string, selection: SelectionRange, force?:boolean = false): Array { const RoomAvatar = sdk.getComponent('views.avatars.RoomAvatar'); const client = MatrixClientPeg.get(); diff --git a/src/autocomplete/RoomProvider.js b/src/autocomplete/RoomProvider.js index 31599703c2..c222ae95d4 100644 --- a/src/autocomplete/RoomProvider.js +++ b/src/autocomplete/RoomProvider.js @@ -1,7 +1,7 @@ /* Copyright 2016 Aviral Dasgupta Copyright 2017 Vector Creations Ltd -Copyright 2017 New Vector Ltd +Copyright 2017, 2018 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. @@ -26,6 +26,7 @@ import {getDisplayAliasForRoom} from '../Rooms'; import sdk from '../index'; import _sortBy from 'lodash/sortBy'; import {makeRoomPermalink} from "../matrix-to"; +import type {Completion, SelectionRange} from "./Autocompleter"; const ROOM_REGEX = /(?=#)(\S*)/g; @@ -46,7 +47,7 @@ export default class RoomProvider extends AutocompleteProvider { }); } - async getCompletions(query: string, selection: {start: number, end: number}, force = false) { + async getCompletions(query: string, selection: SelectionRange, force?: boolean = false): Array { const RoomAvatar = sdk.getComponent('views.avatars.RoomAvatar'); // Disable autocompletions when composing commands because of various issues diff --git a/src/autocomplete/UserProvider.js b/src/autocomplete/UserProvider.js index ce8f1020a1..85837d5ebb 100644 --- a/src/autocomplete/UserProvider.js +++ b/src/autocomplete/UserProvider.js @@ -2,7 +2,7 @@ /* Copyright 2016 Aviral Dasgupta Copyright 2017 Vector Creations Ltd -Copyright 2017 New Vector Ltd +Copyright 2017, 2018 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. @@ -23,12 +23,12 @@ import AutocompleteProvider from './AutocompleteProvider'; import {PillCompletion} from './Components'; import sdk from '../index'; import FuzzyMatcher from './FuzzyMatcher'; -import _pull from 'lodash/pull'; import _sortBy from 'lodash/sortBy'; import MatrixClientPeg from '../MatrixClientPeg'; import type {Room, RoomMember} from 'matrix-js-sdk'; import {makeUserPermalink} from "../matrix-to"; +import type {SelectionRange} from "./Autocompleter"; const USER_REGEX = /@\S*/g; @@ -36,7 +36,7 @@ export default class UserProvider extends AutocompleteProvider { users: Array = null; room: Room = null; - constructor(room) { + constructor(room: Room) { super(USER_REGEX, { keys: ['name'], }); @@ -87,7 +87,7 @@ export default class UserProvider extends AutocompleteProvider { this.users = null; } - async getCompletions(query: string, selection: {start: number, end: number}, force = false) { + async getCompletions(query: string, selection: SelectionRange, force?: boolean = false) { const MemberAvatar = sdk.getComponent('views.avatars.MemberAvatar'); // Disable autocompletions when composing commands because of various issues From 9ee78de7e5ac0875a263e1a81fda61ede27cac15 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 22 Jun 2018 12:05:46 +0100 Subject: [PATCH 5/7] pr iteration, don't assume js-sdk stores group stuff other than groupId Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/HtmlUtils.js | 3 ++- src/autocomplete/CommunityProvider.js | 24 ++++++------------------ 2 files changed, 8 insertions(+), 19 deletions(-) diff --git a/src/HtmlUtils.js b/src/HtmlUtils.js index 4f66468373..57be007209 100644 --- a/src/HtmlUtils.js +++ b/src/HtmlUtils.js @@ -223,7 +223,8 @@ const sanitizeHtmlParams = { case '+': attribs.href = '#/group/' + entity; break; - case '#': case '!': + case '#': + case '!': attribs.href = '#/room/' + entity; break; } diff --git a/src/autocomplete/CommunityProvider.js b/src/autocomplete/CommunityProvider.js index db4d52fae2..6b5438e8c8 100644 --- a/src/autocomplete/CommunityProvider.js +++ b/src/autocomplete/CommunityProvider.js @@ -58,33 +58,22 @@ export default class CommunityProvider extends AutocompleteProvider { let completions = []; const {command, range} = this.getCurrentCommand(query, selection, force); if (command) { - const joinedGroups = cli.getGroups().filter(({myMembership}) => myMembership !== 'invite'); + const joinedGroups = cli.getGroups().filter(({myMembership}) => myMembership === 'join'); - const groups = (await Promise.all(joinedGroups.map(async ({avatarUrl, groupId, name=''}) => { + const groups = (await Promise.all(joinedGroups.map(async ({groupId}) => { try { return FlairStore.getGroupProfileCached(cli, groupId); - } catch (e) { // if FlairStore failed, rely on js-sdk's store which lacks info + } catch (e) { // if FlairStore failed, fall back to just groupId return Promise.resolve({ - name, + name: '', groupId, - avatarUrl, - shortDescription: '', // js-sdk doesn't store this + avatarUrl: '', + shortDescription: '', }); } }))); this.matcher.setObjects(groups); - // this.matcher.setObjects(joinedGroups); - // this.matcher.setObjects(joinedGroups.map(({groupId}) => { - // const groupProfile = GroupStore.getSummary(groupId).profile; - // if (groupProfile) { - // return { - // groupId, - // name: groupProfile.name || '', - // avatarUrl: groupProfile.avatar_url, - // }; - // } - // })).filter(Boolean); const matchedString = command[0]; completions = this.matcher.match(matchedString); @@ -104,7 +93,6 @@ export default class CommunityProvider extends AutocompleteProvider { ), range, })) - .filter((completion) => !!completion.completion && completion.completion.length > 0) .slice(0, 4); } return completions; From d92d95c37d7d032520e7377c5e9f99e5481f6562 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 22 Jun 2018 12:11:16 +0100 Subject: [PATCH 6/7] don't fall back to getGroups as it gets it no additional data Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/elements/Pill.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/components/views/elements/Pill.js b/src/components/views/elements/Pill.js index 70e1d0659a..b860f7bf72 100644 --- a/src/components/views/elements/Pill.js +++ b/src/components/views/elements/Pill.js @@ -152,8 +152,12 @@ const Pill = React.createClass({ try { group = await FlairStore.getGroupProfileCached(cli, resourceId); - } catch (e) { // if FlairStore failed, rely on js-sdk's store which lacks info - group = cli.getGroup(resourceId); + } catch (e) { // if FlairStore failed, fall back to just groupId + group = { + groupId: resourceId, + avatarUrl: null, + name: null, + }; } } } From 32ab9972300983b691401374be47e24b1ca3ba36 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 22 Jun 2018 14:36:29 +0100 Subject: [PATCH 7/7] properly style Group Pill Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- res/css/views/elements/_RichText.scss | 12 +++++++++++- res/themes/light/css/_base.scss | 1 + src/components/views/elements/Pill.js | 2 +- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/res/css/views/elements/_RichText.scss b/res/css/views/elements/_RichText.scss index eda9f6a4de..e21fc184ba 100644 --- a/res/css/views/elements/_RichText.scss +++ b/res/css/views/elements/_RichText.scss @@ -37,12 +37,22 @@ /* More specific to override `.markdown-body a` color */ .mx_EventTile_content .markdown-body a.mx_RoomPill, -.mx_RoomPill { +.mx_EventTile_content .markdown-body a.mx_GroupPill, +.mx_RoomPill, +.mx_GroupPill { color: $accent-fg-color; background-color: $rte-room-pill-color; padding-right: 5px; } +/* More specific to override `.markdown-body a` color */ +.mx_EventTile_content .markdown-body a.mx_GroupPill, +.mx_GroupPill { + color: $accent-fg-color; + background-color: $rte-group-pill-color; + padding-right: 5px; +} + .mx_UserPill .mx_BaseAvatar, .mx_RoomPill .mx_BaseAvatar, .mx_GroupPill .mx_BaseAvatar, diff --git a/res/themes/light/css/_base.scss b/res/themes/light/css/_base.scss index 5d5f5d7c90..55c761e8d9 100644 --- a/res/themes/light/css/_base.scss +++ b/res/themes/light/css/_base.scss @@ -97,6 +97,7 @@ $voip-accept-color: #80f480; $rte-bg-color: #e9e9e9; $rte-code-bg-color: rgba(0, 0, 0, 0.04); $rte-room-pill-color: #aaa; +$rte-group-pill-color: #aaa; // ******************** diff --git a/src/components/views/elements/Pill.js b/src/components/views/elements/Pill.js index b860f7bf72..e14d6c37c9 100644 --- a/src/components/views/elements/Pill.js +++ b/src/components/views/elements/Pill.js @@ -260,7 +260,7 @@ const Pill = React.createClass({ avatar = ; } - pillClass = 'mx_RoomPill' || 'mx_GroupPill'; + pillClass = 'mx_GroupPill'; } } break;