[MM-23160][MM-24633][MM-24697] Highlight Group Names 2 (#4551)
* Initial Commit for Group Highlights * Fix some stuff * Get my groups * update channel.js * Address PR comments * Address PR comments * Update app/actions/views/channel.js Co-authored-by: Miguel Alatzar <migbot@users.noreply.github.com> * update selector stuff Co-authored-by: Miguel Alatzar <migbot@users.noreply.github.com>
This commit is contained in:
parent
69240c6c30
commit
2840a42a00
17 changed files with 350 additions and 45 deletions
|
|
@ -586,6 +586,7 @@ function loadGroupData() {
|
|||
const state = getState();
|
||||
const actions = [];
|
||||
const team = getCurrentTeam(state);
|
||||
const currentUserId = getCurrentUserId(state);
|
||||
const serverVersion = state.entities.general.serverVersion;
|
||||
const license = getLicense(state);
|
||||
const hasLicense = license?.IsLicensed === 'true' && license?.LDAPGroups === 'true';
|
||||
|
|
@ -632,10 +633,25 @@ function loadGroupData() {
|
|||
});
|
||||
}
|
||||
}
|
||||
break;
|
||||
} catch (err) {
|
||||
return {error: err};
|
||||
if (i === MAX_RETRIES) {
|
||||
return {error: err};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const myGroups = await Client4.getGroupsByUserId(currentUserId);
|
||||
if (myGroups.length) {
|
||||
actions.push({
|
||||
type: GroupTypes.RECEIVED_MY_GROUPS,
|
||||
data: myGroups,
|
||||
});
|
||||
}
|
||||
} catch {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
|
||||
if (actions.length) {
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ export default class AtMention extends React.PureComponent {
|
|||
teammateNameDisplay: PropTypes.string,
|
||||
theme: PropTypes.object.isRequired,
|
||||
usersByUsername: PropTypes.object.isRequired,
|
||||
groupsByName: PropTypes.object,
|
||||
};
|
||||
|
||||
static contextTypes = {
|
||||
|
|
@ -93,6 +94,12 @@ export default class AtMention extends React.PureComponent {
|
|||
};
|
||||
}
|
||||
|
||||
getGroupFromMentionName() {
|
||||
const {groupsByName, mentionName} = this.props;
|
||||
const mentionNameTrimmed = mentionName.toLowerCase().replace(/[._-]*$/, '');
|
||||
return groupsByName?.[mentionNameTrimmed] || {};
|
||||
}
|
||||
|
||||
handleLongPress = async () => {
|
||||
const {formatMessage} = this.context.intl;
|
||||
|
||||
|
|
@ -134,13 +141,28 @@ export default class AtMention extends React.PureComponent {
|
|||
render() {
|
||||
const {isSearchResult, mentionName, mentionStyle, onPostPress, teammateNameDisplay, textStyle, mentionKeys} = this.props;
|
||||
const {user} = this.state;
|
||||
let highlighted;
|
||||
|
||||
if (!user.username) {
|
||||
const group = this.getGroupFromMentionName();
|
||||
if (group.allow_reference) {
|
||||
highlighted = mentionKeys.some((item) => item.key === group.name);
|
||||
return (
|
||||
<Text
|
||||
style={textStyle}
|
||||
>
|
||||
<Text style={highlighted ? null : mentionStyle}>
|
||||
{`@${group.name}`}
|
||||
</Text>
|
||||
</Text>
|
||||
);
|
||||
}
|
||||
|
||||
return <Text style={textStyle}>{'@' + mentionName}</Text>;
|
||||
}
|
||||
|
||||
const suffix = this.props.mentionName.substring(user.username.length);
|
||||
const highlighted = mentionKeys.some((item) => item.key === user.username);
|
||||
highlighted = mentionKeys.some((item) => item.key === user.username);
|
||||
|
||||
return (
|
||||
<Text
|
||||
|
|
|
|||
|
|
@ -3,18 +3,23 @@
|
|||
|
||||
import {connect} from 'react-redux';
|
||||
|
||||
import {getUsersByUsername, getCurrentUserMentionKeys} from '@mm-redux/selectors/entities/users';
|
||||
import {getUsersByUsername} from '@mm-redux/selectors/entities/users';
|
||||
|
||||
import {getAllUserMentionKeys} from '@mm-redux/selectors/entities/search';
|
||||
|
||||
import {getTeammateNameDisplaySetting, getTheme} from '@mm-redux/selectors/entities/preferences';
|
||||
|
||||
import {getGroupsByName} from '@mm-redux/selectors/entities/groups';
|
||||
|
||||
import AtMention from './at_mention';
|
||||
|
||||
function mapStateToProps(state) {
|
||||
function mapStateToProps(state, ownProps) {
|
||||
return {
|
||||
theme: getTheme(state),
|
||||
usersByUsername: getUsersByUsername(state),
|
||||
mentionKeys: getCurrentUserMentionKeys(state),
|
||||
mentionKeys: ownProps.mentionKeys || getAllUserMentionKeys(state),
|
||||
teammateNameDisplay: getTeammateNameDisplaySetting(state),
|
||||
groupsByName: getGroupsByName(state),
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ exports[`Markdown should match with disableAtChannelMentionHighlight 1`] = `
|
|||
first={true}
|
||||
last={true}
|
||||
literal={null}
|
||||
nodeKey="6"
|
||||
nodeKey="8"
|
||||
>
|
||||
<Unknown
|
||||
context={
|
||||
|
|
@ -64,21 +64,23 @@ exports[`Markdown should match with disableAtChannelMentionHighlight 1`] = `
|
|||
context={
|
||||
Array [
|
||||
"paragraph",
|
||||
"mention_highlight",
|
||||
]
|
||||
}
|
||||
literal={null}
|
||||
mentionName="all"
|
||||
nodeKey="5"
|
||||
nodeKey="6"
|
||||
>
|
||||
<Unknown
|
||||
context={
|
||||
Array [
|
||||
"paragraph",
|
||||
"mention_highlight",
|
||||
"at_mention",
|
||||
]
|
||||
}
|
||||
literal="@all"
|
||||
nodeKey="4"
|
||||
nodeKey="5"
|
||||
/>
|
||||
</Unknown>
|
||||
</Unknown>
|
||||
|
|
|
|||
|
|
@ -5,16 +5,16 @@ import {connect} from 'react-redux';
|
|||
|
||||
import {getAutolinkedUrlSchemes, getConfig} from '@mm-redux/selectors/entities/general';
|
||||
import {getTheme} from '@mm-redux/selectors/entities/preferences';
|
||||
import {getCurrentUserMentionKeys} from '@mm-redux/selectors/entities/users';
|
||||
import {getAllUserMentionKeys} from '@mm-redux/selectors/entities/search';
|
||||
|
||||
import Markdown from './markdown';
|
||||
|
||||
function mapStateToProps(state) {
|
||||
function mapStateToProps(state, ownProps) {
|
||||
const {MinimumHashtagLength} = getConfig(state);
|
||||
|
||||
return {
|
||||
autolinkedUrlSchemes: getAutolinkedUrlSchemes(state),
|
||||
mentionKeys: getCurrentUserMentionKeys(state),
|
||||
mentionKeys: ownProps.mentionKeys || getAllUserMentionKeys(state),
|
||||
minimumHashtagLength: MinimumHashtagLength ? parseInt(MinimumHashtagLength, 10) : 3,
|
||||
theme: getTheme(state),
|
||||
};
|
||||
|
|
|
|||
|
|
@ -92,14 +92,6 @@ export default class Markdown extends PureComponent {
|
|||
return !scheme || this.props.autolinkedUrlSchemes.indexOf(scheme) !== -1;
|
||||
};
|
||||
|
||||
getMentionKeys = () => {
|
||||
const mentionKeys = this.props.mentionKeys;
|
||||
if (this.props.disableAtChannelMentionHighlight) {
|
||||
return mentionKeys.filter((mention) => !['@all', '@channel', '@here'].includes(mention.key));
|
||||
}
|
||||
return mentionKeys;
|
||||
}
|
||||
|
||||
createRenderer = () => {
|
||||
return new Renderer({
|
||||
renderers: {
|
||||
|
|
@ -223,6 +215,7 @@ export default class Markdown extends PureComponent {
|
|||
isSearchResult={this.props.isSearchResult}
|
||||
mentionName={mentionName}
|
||||
onPostPress={this.props.onPostPress}
|
||||
mentionKeys={this.props.mentionKeys}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
|
@ -439,7 +432,7 @@ export default class Markdown extends PureComponent {
|
|||
ast = combineTextNodes(ast);
|
||||
ast = addListItemIndices(ast);
|
||||
ast = pullOutImages(ast);
|
||||
ast = highlightMentions(ast, this.getMentionKeys());
|
||||
ast = highlightMentions(ast, this.props.mentionKeys);
|
||||
|
||||
if (this.props.isEdited) {
|
||||
const editIndicatorNode = new Node('edited_indicator');
|
||||
|
|
|
|||
|
|
@ -33,24 +33,4 @@ describe('Markdown', () => {
|
|||
|
||||
expect(wrapper.getElement()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
describe('getMentionKeys', () => {
|
||||
let wrapper;
|
||||
beforeAll(() => {
|
||||
wrapper = shallow(
|
||||
<Markdown
|
||||
{...baseProps}
|
||||
/>,
|
||||
);
|
||||
});
|
||||
|
||||
it('should return base mentionKey props when disableAtChannelMentionHighlight not present', () => {
|
||||
expect(wrapper.instance().getMentionKeys()).toEqual(baseProps.mentionKeys);
|
||||
});
|
||||
|
||||
it('should filter channel mentions from mentionKey props when disableAtChannelMentionHighlight is true', () => {
|
||||
wrapper.setProps({disableAtChannelMentionHighlight: true});
|
||||
expect(wrapper.instance().getMentionKeys()).toEqual([{key: 'user.name'}]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import {getCurrentTeamId} from '@mm-redux/selectors/entities/teams';
|
|||
import {getCustomEmojisByName} from '@mm-redux/selectors/entities/emojis';
|
||||
import {makeGetReactionsForPost} from '@mm-redux/selectors/entities/posts';
|
||||
import {memoizeResult} from '@mm-redux/utils/helpers';
|
||||
import {makeGetMentionKeysForPost} from '@mm-redux/selectors/entities/search';
|
||||
|
||||
import {
|
||||
isEdited,
|
||||
|
|
@ -103,6 +104,7 @@ export function makeMapStateToProps() {
|
|||
isEmojiOnly,
|
||||
shouldRenderJumboEmoji,
|
||||
theme: getTheme(state),
|
||||
mentionKeys: makeGetMentionKeysForPost(state, postProps?.disable_group_highlight, postProps?.mentionHighlightDisabled),
|
||||
canDelete,
|
||||
...getDimensions(state),
|
||||
};
|
||||
|
|
|
|||
|
|
@ -77,6 +77,13 @@ describe('makeMapStateToProps', () => {
|
|||
general: {
|
||||
serverVersion: '',
|
||||
},
|
||||
users: {
|
||||
profiles: {},
|
||||
},
|
||||
groups: {
|
||||
groups: {},
|
||||
myGroups: {},
|
||||
},
|
||||
},
|
||||
};
|
||||
const defaultOwnProps = {
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ export default class PostBody extends PureComponent {
|
|||
shouldRenderJumboEmoji: PropTypes.bool.isRequired,
|
||||
theme: PropTypes.object,
|
||||
location: PropTypes.string,
|
||||
mentionKeys: PropTypes.array.isRequired,
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
|
|
@ -345,6 +346,7 @@ export default class PostBody extends PureComponent {
|
|||
shouldRenderJumboEmoji,
|
||||
showLongPost,
|
||||
theme,
|
||||
mentionKeys,
|
||||
} = this.props;
|
||||
const {isLongPost, maxHeight} = this.state;
|
||||
const style = getStyleSheet(theme);
|
||||
|
|
@ -413,7 +415,7 @@ export default class PostBody extends PureComponent {
|
|||
onPostPress={onPress}
|
||||
textStyles={textStyles}
|
||||
value={message}
|
||||
disableAtChannelMentionHighlight={postProps.mentionHighlightDisabled}
|
||||
mentionKeys={mentionKeys}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -2861,6 +2861,13 @@ export default class Client4 {
|
|||
);
|
||||
};
|
||||
|
||||
getGroupsByUserId = async (userID: string) => {
|
||||
return this.doFetch(
|
||||
`${this.getUsersRoute()}/${userID}/groups`,
|
||||
{method: 'get'},
|
||||
);
|
||||
}
|
||||
|
||||
getGroupsNotAssociatedToTeam = async (teamID: string, q = '', page = 0, perPage = PER_PAGE_DEFAULT) => {
|
||||
this.trackEvent('api', 'api_groups_get_not_associated_to_team', {team_id: teamID});
|
||||
return this.doFetch(
|
||||
|
|
|
|||
|
|
@ -163,6 +163,20 @@ function syncables(state: Dictionary<GroupSyncables> = {}, action: GenericAction
|
|||
}
|
||||
}
|
||||
|
||||
function myGroups(state: any = {}, action: GenericAction) {
|
||||
switch (action.type) {
|
||||
case GroupTypes.RECEIVED_MY_GROUPS: {
|
||||
const nextState = {...state};
|
||||
for (const group of action.data) {
|
||||
nextState[group.id] = group;
|
||||
}
|
||||
return nextState;
|
||||
}
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
function members(state: any = {}, action: GenericAction) {
|
||||
switch (action.type) {
|
||||
case GroupTypes.RECEIVED_GROUP_MEMBERS: {
|
||||
|
|
@ -221,6 +235,7 @@ function groups(state: Dictionary<Group> = {}, action: GenericAction) {
|
|||
}
|
||||
|
||||
export default combineReducers({
|
||||
myGroups,
|
||||
syncables,
|
||||
members,
|
||||
groups,
|
||||
|
|
|
|||
|
|
@ -2,10 +2,12 @@
|
|||
// See LICENSE.txt for license information.
|
||||
import * as reselect from 'reselect';
|
||||
import {GlobalState} from '@mm-redux/types/store';
|
||||
import {Dictionary} from '@mm-redux/types/utilities';
|
||||
import {Group} from '@mm-redux/types/groups';
|
||||
import {filterGroupsMatchingTerm} from '@mm-redux/utils/group_utils';
|
||||
import {getCurrentUserLocale} from '@mm-redux/selectors/entities/i18n';
|
||||
import {getChannel} from '@mm-redux/selectors/entities/channels';
|
||||
import {UserMentionKey} from '@mm-redux/selectors/entities/users';
|
||||
import {haveIChannelPermission} from '@mm-redux/selectors/entities/roles';
|
||||
import {getTeam} from '@mm-redux/selectors/entities/teams';
|
||||
import {Permissions} from '@mm-redux/constants';
|
||||
|
|
@ -17,7 +19,11 @@ const emptySyncables = {
|
|||
};
|
||||
|
||||
export function getAllGroups(state: GlobalState) {
|
||||
return state.entities.groups?.groups || [];
|
||||
return state.entities.groups?.groups || {};
|
||||
}
|
||||
|
||||
export function getMyGroups(state: GlobalState) {
|
||||
return state.entities.groups?.myGroups || {};
|
||||
}
|
||||
|
||||
export function getGroup(state: GlobalState, id: string) {
|
||||
|
|
@ -166,3 +172,32 @@ export const getAllAssociatedGroupsForReference = reselect.createSelector(
|
|||
return Object.values(allGroups).filter((group) => group.allow_reference && group.delete_at === 0);
|
||||
},
|
||||
);
|
||||
|
||||
export const getMyAllowReferencedGroups = reselect.createSelector(
|
||||
getMyGroups,
|
||||
(myGroups) => {
|
||||
return Object.values(myGroups).filter((group) => group.allow_reference && group.delete_at === 0);
|
||||
},
|
||||
);
|
||||
|
||||
export const getCurrentUserGroupMentionKeys = reselect.createSelector(
|
||||
getMyAllowReferencedGroups,
|
||||
(groups: Array<Group>) => {
|
||||
const keys: UserMentionKey[] = [];
|
||||
groups.forEach((group) => keys.push({key: `@${group.name}`}));
|
||||
return keys;
|
||||
},
|
||||
);
|
||||
|
||||
export const getGroupsByName = reselect.createSelector(
|
||||
getAllGroups,
|
||||
(groups) => {
|
||||
const groupsByName: Dictionary<Group> = {};
|
||||
|
||||
Object.values(groups).forEach((group) => {
|
||||
groupsByName[group.name] = group;
|
||||
});
|
||||
|
||||
return groupsByName;
|
||||
},
|
||||
);
|
||||
|
|
|
|||
|
|
@ -26,4 +26,184 @@ describe('Selectors.Search', () => {
|
|||
it('should return current search for current team', () => {
|
||||
assert.deepEqual(Selectors.getCurrentSearchForCurrentTeam(testState), team1CurrentSearch);
|
||||
});
|
||||
|
||||
it('getAllUserMentionKeys', () => {
|
||||
const userId = '1234';
|
||||
const notifyProps = {
|
||||
first_name: 'true',
|
||||
};
|
||||
const state = {
|
||||
entities: {
|
||||
users: {
|
||||
currentUserId: userId,
|
||||
profiles: {
|
||||
[userId]: {id: userId, username: 'user', first_name: 'First', last_name: 'Last', notify_props: notifyProps},
|
||||
},
|
||||
},
|
||||
groups: {
|
||||
myGroups: {
|
||||
test1: {
|
||||
name: 'I-AM-THE-BEST!',
|
||||
delete_at: 0,
|
||||
allow_reference: true,
|
||||
},
|
||||
test2: {
|
||||
name: 'Do-you-love-me?',
|
||||
delete_at: 0,
|
||||
allow_reference: true,
|
||||
},
|
||||
test3: {
|
||||
name: 'Maybe?-A-little-bit-I-guess....',
|
||||
delete_at: 0,
|
||||
allow_reference: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
assert.deepEqual(Selectors.getAllUserMentionKeys(state), [{key: 'First', caseSensitive: true}, {key: '@user'}, {key: '@I-AM-THE-BEST!'}, {key: '@Do-you-love-me?'}]);
|
||||
});
|
||||
|
||||
describe('makeGetMentionKeysForPost', () => {
|
||||
it('should return all mentionKeys', () => {
|
||||
const postProps = {
|
||||
disable_group_highlight: false,
|
||||
mentionHighlightDisabled: false,
|
||||
};
|
||||
const state = {
|
||||
entities: {
|
||||
users: {
|
||||
currentUserId: 'a123',
|
||||
profiles: {
|
||||
a123: {
|
||||
username: 'a123',
|
||||
notify_props: {
|
||||
channel: 'true',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
groups: {
|
||||
myGroups: {
|
||||
developers: {
|
||||
id: 123,
|
||||
name: 'developers',
|
||||
allow_reference: true,
|
||||
delete_at: 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
const results = Selectors.makeGetMentionKeysForPost(state, postProps.disable_group_highlight, postProps.mentionHighlightDisabled);
|
||||
const expected = [{key: '@channel'}, {key: '@all'}, {key: '@here'}, {key: '@a123'}, {key: '@developers'}];
|
||||
assert.deepEqual(results, expected);
|
||||
});
|
||||
|
||||
it('should return mentionKeys without groups', () => {
|
||||
const postProps = {
|
||||
disable_group_highlight: true,
|
||||
mentionHighlightDisabled: false,
|
||||
};
|
||||
const state = {
|
||||
entities: {
|
||||
users: {
|
||||
currentUserId: 'a123',
|
||||
profiles: {
|
||||
a123: {
|
||||
username: 'a123',
|
||||
notify_props: {
|
||||
channel: 'true',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
groups: {
|
||||
myGroups: {
|
||||
developers: {
|
||||
id: 123,
|
||||
name: 'developers',
|
||||
allow_reference: true,
|
||||
delete_at: 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
const results = Selectors.makeGetMentionKeysForPost(state, postProps.disable_group_highlight, postProps.mentionHighlightDisabled);
|
||||
const expected = [{key: '@channel'}, {key: '@all'}, {key: '@here'}, {key: '@a123'}];
|
||||
assert.deepEqual(results, expected);
|
||||
});
|
||||
|
||||
it('should return group mentions and all mentions without channel mentions', () => {
|
||||
const postProps = {
|
||||
disable_group_highlight: false,
|
||||
mentionHighlightDisabled: true,
|
||||
};
|
||||
const state = {
|
||||
entities: {
|
||||
users: {
|
||||
currentUserId: 'a123',
|
||||
profiles: {
|
||||
a123: {
|
||||
username: 'a123',
|
||||
notify_props: {
|
||||
channel: 'true',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
groups: {
|
||||
myGroups: {
|
||||
developers: {
|
||||
id: 123,
|
||||
name: 'developers',
|
||||
allow_reference: true,
|
||||
delete_at: 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
const results = Selectors.makeGetMentionKeysForPost(state, postProps.disable_group_highlight, postProps.mentionHighlightDisabled);
|
||||
const expected = [{key: '@a123'}, {key: '@developers'}];
|
||||
assert.deepEqual(results, expected);
|
||||
});
|
||||
|
||||
it('should return all mentions without group mentions and channel mentions', () => {
|
||||
const postProps = {
|
||||
disable_group_highlight: true,
|
||||
mentionHighlightDisabled: true,
|
||||
};
|
||||
const state = {
|
||||
entities: {
|
||||
users: {
|
||||
currentUserId: 'a123',
|
||||
profiles: {
|
||||
a123: {
|
||||
username: 'a123',
|
||||
notify_props: {
|
||||
channel: 'true',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
groups: {
|
||||
myGroups: {
|
||||
developers: {
|
||||
id: 123,
|
||||
name: 'developers',
|
||||
allow_reference: true,
|
||||
delete_at: 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
const results = Selectors.makeGetMentionKeysForPost(state, postProps.disable_group_highlight, postProps.mentionHighlightDisabled);
|
||||
const expected = [{key: '@a123'}];
|
||||
assert.deepEqual(results, expected);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -2,15 +2,46 @@
|
|||
// See LICENSE.txt for license information.
|
||||
|
||||
import * as reselect from 'reselect';
|
||||
import {GlobalState} from '@mm-redux/types/store';
|
||||
import {UserMentionKey} from './users';
|
||||
import {getCurrentUserMentionKeys} from '@mm-redux/selectors/entities/users';
|
||||
import {getCurrentUserGroupMentionKeys} from '@mm-redux/selectors/entities/groups';
|
||||
|
||||
import {getCurrentTeamId} from '@mm-redux/selectors/entities/teams';
|
||||
|
||||
import * as types from '@mm-redux/types';
|
||||
|
||||
export const getCurrentSearchForCurrentTeam = reselect.createSelector(
|
||||
(state: types.store.GlobalState) => state.entities.search.current,
|
||||
(state: GlobalState) => state.entities.search.current,
|
||||
getCurrentTeamId,
|
||||
(current, teamId) => {
|
||||
return current[teamId];
|
||||
},
|
||||
);
|
||||
|
||||
export const getAllUserMentionKeys: (state: GlobalState) => UserMentionKey[] = reselect.createSelector(
|
||||
getCurrentUserMentionKeys,
|
||||
(state: GlobalState) => getCurrentUserGroupMentionKeys(state),
|
||||
(userMentionKeys, groupMentionKeys) => {
|
||||
return userMentionKeys.concat(groupMentionKeys);
|
||||
},
|
||||
);
|
||||
|
||||
export const makeGetMentionKeysForPost: (state: GlobalState, disableGroupHighlight: boolean, mentionHighlightDisabled: boolean) => UserMentionKey[] = reselect.createSelector(
|
||||
getAllUserMentionKeys,
|
||||
getCurrentUserMentionKeys,
|
||||
(state: GlobalState, disableGroupHighlight: boolean) => disableGroupHighlight,
|
||||
(state: GlobalState, disableGroupHighlight: boolean, mentionHighlightDisabled: boolean) => mentionHighlightDisabled,
|
||||
(allMentionKeys, mentionKeysWithoutGroups, disableGroupHighlight = false, mentionHighlightDisabled = false) => {
|
||||
let mentionKeys = allMentionKeys;
|
||||
if (disableGroupHighlight) {
|
||||
mentionKeys = mentionKeysWithoutGroups;
|
||||
}
|
||||
|
||||
if (mentionHighlightDisabled) {
|
||||
const CHANNEL_MENTIONS = ['@all', '@channel', '@here'];
|
||||
mentionKeys = mentionKeys.filter((value) => !CHANNEL_MENTIONS.includes(value.key));
|
||||
}
|
||||
|
||||
return mentionKeys;
|
||||
},
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -57,6 +57,9 @@ export type GroupsState = {
|
|||
groups: {
|
||||
[x: string]: Group;
|
||||
};
|
||||
myGroups: {
|
||||
[x: string]: Group;
|
||||
};
|
||||
};
|
||||
export type GroupSearchOpts = {
|
||||
q: string;
|
||||
|
|
|
|||
|
|
@ -110,3 +110,8 @@ export type PostsState = {
|
|||
messagesHistory: MessageHistory;
|
||||
expandedURLs: Dictionary<string>;
|
||||
};
|
||||
|
||||
export type PostProps = {
|
||||
disable_group_highlight?: boolean;
|
||||
mentionHighlightDisabled: boolean;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue