Add draft indicator to the channel item (#2150)
* Add draft indicator to the channel item * Feedback review
This commit is contained in:
parent
4cebbfdc94
commit
2567b7dc04
6 changed files with 196 additions and 21 deletions
|
|
@ -19,6 +19,7 @@ export default class ChannelIcon extends React.PureComponent {
|
|||
isActive: PropTypes.bool,
|
||||
isInfo: PropTypes.bool,
|
||||
isUnread: PropTypes.bool,
|
||||
hasDraft: PropTypes.bool,
|
||||
membersCount: PropTypes.number,
|
||||
size: PropTypes.number,
|
||||
status: PropTypes.string,
|
||||
|
|
@ -40,6 +41,7 @@ export default class ChannelIcon extends React.PureComponent {
|
|||
isActive,
|
||||
isUnread,
|
||||
isInfo,
|
||||
hasDraft,
|
||||
membersCount,
|
||||
size,
|
||||
status,
|
||||
|
|
@ -85,6 +87,13 @@ export default class ChannelIcon extends React.PureComponent {
|
|||
style={[style.icon, unreadIcon, activeIcon, {fontSize: size}]}
|
||||
/>
|
||||
);
|
||||
} else if (hasDraft) {
|
||||
icon = (
|
||||
<Icon
|
||||
name='pencil'
|
||||
style={[style.icon, unreadIcon, activeIcon, {fontSize: size}]}
|
||||
/>
|
||||
);
|
||||
} else if (type === General.OPEN_CHANNEL) {
|
||||
icon = (
|
||||
<Icon
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ exports[`ChannelItem should match snapshot 1`] = `
|
|||
delayPressOut={100}
|
||||
onLongPress={[Function]}
|
||||
onPress={[Function]}
|
||||
underlayColor="rgba(170,170,170,0.5)"
|
||||
underlayColor="rgba(69,120,191,0.5)"
|
||||
>
|
||||
<Component
|
||||
style={
|
||||
|
|
@ -36,6 +36,7 @@ exports[`ChannelItem should match snapshot 1`] = `
|
|||
>
|
||||
<ChannelIcon
|
||||
channelId="channel_id"
|
||||
hasDraft={false}
|
||||
isActive={false}
|
||||
isArchived={false}
|
||||
isInfo={false}
|
||||
|
|
@ -46,10 +47,30 @@ exports[`ChannelItem should match snapshot 1`] = `
|
|||
teammateDeletedAt={0}
|
||||
theme={
|
||||
Object {
|
||||
"sidebarText": "#aaa",
|
||||
"sidebarTextActiveBorder": "#aaa",
|
||||
"sidebarTextActiveColor": "#aaa",
|
||||
"sidebarTextHoverBg": "#aaa",
|
||||
"awayIndicator": "#ffbc42",
|
||||
"buttonBg": "#166de0",
|
||||
"buttonColor": "#ffffff",
|
||||
"centerChannelBg": "#ffffff",
|
||||
"centerChannelColor": "#3d3c40",
|
||||
"codeTheme": "github",
|
||||
"dndIndicator": "#f74343",
|
||||
"errorTextColor": "#fd5960",
|
||||
"linkColor": "#2389d7",
|
||||
"mentionBj": "#ffffff",
|
||||
"mentionColor": "#145dbf",
|
||||
"mentionHighlightBg": "#ffe577",
|
||||
"mentionHighlightLink": "#166de0",
|
||||
"newMessageSeparator": "#ff8800",
|
||||
"onlineIndicator": "#06d6a0",
|
||||
"sidebarBg": "#145dbf",
|
||||
"sidebarHeaderBg": "#1153ab",
|
||||
"sidebarHeaderTextColor": "#ffffff",
|
||||
"sidebarText": "#ffffff",
|
||||
"sidebarTextActiveBorder": "#579eff",
|
||||
"sidebarTextActiveColor": "#ffffff",
|
||||
"sidebarTextHoverBg": "#4578bf",
|
||||
"sidebarUnreadText": "#ffffff",
|
||||
"type": "Mattermost",
|
||||
}
|
||||
}
|
||||
type="O"
|
||||
|
|
@ -60,7 +81,7 @@ exports[`ChannelItem should match snapshot 1`] = `
|
|||
style={
|
||||
Array [
|
||||
Object {
|
||||
"color": "rgba(170,170,170,0.4)",
|
||||
"color": "rgba(255,255,255,0.4)",
|
||||
"flex": 1,
|
||||
"fontSize": 14,
|
||||
"fontWeight": "600",
|
||||
|
|
@ -70,7 +91,7 @@ exports[`ChannelItem should match snapshot 1`] = `
|
|||
"textAlignVertical": "center",
|
||||
},
|
||||
Object {
|
||||
"color": undefined,
|
||||
"color": "#ffffff",
|
||||
},
|
||||
]
|
||||
}
|
||||
|
|
@ -88,7 +109,7 @@ exports[`ChannelItem should match snapshot for deactivated user 1`] = `
|
|||
delayPressOut={100}
|
||||
onLongPress={[Function]}
|
||||
onPress={[Function]}
|
||||
underlayColor="rgba(170,170,170,0.5)"
|
||||
underlayColor="rgba(69,120,191,0.5)"
|
||||
>
|
||||
<Component
|
||||
style={
|
||||
|
|
@ -117,6 +138,7 @@ exports[`ChannelItem should match snapshot for deactivated user 1`] = `
|
|||
>
|
||||
<ChannelIcon
|
||||
channelId="channel_id"
|
||||
hasDraft={false}
|
||||
isActive={false}
|
||||
isArchived={false}
|
||||
isInfo={false}
|
||||
|
|
@ -127,10 +149,30 @@ exports[`ChannelItem should match snapshot for deactivated user 1`] = `
|
|||
teammateDeletedAt={100}
|
||||
theme={
|
||||
Object {
|
||||
"sidebarText": "#aaa",
|
||||
"sidebarTextActiveBorder": "#aaa",
|
||||
"sidebarTextActiveColor": "#aaa",
|
||||
"sidebarTextHoverBg": "#aaa",
|
||||
"awayIndicator": "#ffbc42",
|
||||
"buttonBg": "#166de0",
|
||||
"buttonColor": "#ffffff",
|
||||
"centerChannelBg": "#ffffff",
|
||||
"centerChannelColor": "#3d3c40",
|
||||
"codeTheme": "github",
|
||||
"dndIndicator": "#f74343",
|
||||
"errorTextColor": "#fd5960",
|
||||
"linkColor": "#2389d7",
|
||||
"mentionBj": "#ffffff",
|
||||
"mentionColor": "#145dbf",
|
||||
"mentionHighlightBg": "#ffe577",
|
||||
"mentionHighlightLink": "#166de0",
|
||||
"newMessageSeparator": "#ff8800",
|
||||
"onlineIndicator": "#06d6a0",
|
||||
"sidebarBg": "#145dbf",
|
||||
"sidebarHeaderBg": "#1153ab",
|
||||
"sidebarHeaderTextColor": "#ffffff",
|
||||
"sidebarText": "#ffffff",
|
||||
"sidebarTextActiveBorder": "#579eff",
|
||||
"sidebarTextActiveColor": "#ffffff",
|
||||
"sidebarTextHoverBg": "#4578bf",
|
||||
"sidebarUnreadText": "#ffffff",
|
||||
"type": "Mattermost",
|
||||
}
|
||||
}
|
||||
type="D"
|
||||
|
|
@ -141,7 +183,7 @@ exports[`ChannelItem should match snapshot for deactivated user 1`] = `
|
|||
style={
|
||||
Array [
|
||||
Object {
|
||||
"color": "rgba(170,170,170,0.4)",
|
||||
"color": "rgba(255,255,255,0.4)",
|
||||
"flex": 1,
|
||||
"fontSize": 14,
|
||||
"fontWeight": "600",
|
||||
|
|
@ -151,7 +193,109 @@ exports[`ChannelItem should match snapshot for deactivated user 1`] = `
|
|||
"textAlignVertical": "center",
|
||||
},
|
||||
Object {
|
||||
"color": undefined,
|
||||
"color": "#ffffff",
|
||||
},
|
||||
]
|
||||
}
|
||||
/>
|
||||
</Component>
|
||||
</Component>
|
||||
</TouchableHighlight>
|
||||
</AnimatedComponent>
|
||||
`;
|
||||
|
||||
exports[`ChannelItem should match snapshot with draft 1`] = `
|
||||
<AnimatedComponent>
|
||||
<TouchableHighlight
|
||||
activeOpacity={0.85}
|
||||
delayPressOut={100}
|
||||
onLongPress={[Function]}
|
||||
onPress={[Function]}
|
||||
underlayColor="rgba(69,120,191,0.5)"
|
||||
>
|
||||
<Component
|
||||
style={
|
||||
Array [
|
||||
Object {
|
||||
"flex": 1,
|
||||
"flexDirection": "row",
|
||||
"height": 44,
|
||||
},
|
||||
undefined,
|
||||
]
|
||||
}
|
||||
>
|
||||
<Component
|
||||
style={
|
||||
Array [
|
||||
Object {
|
||||
"alignItems": "center",
|
||||
"flex": 1,
|
||||
"flexDirection": "row",
|
||||
"paddingLeft": 16,
|
||||
},
|
||||
undefined,
|
||||
]
|
||||
}
|
||||
>
|
||||
<ChannelIcon
|
||||
channelId="channel_id"
|
||||
hasDraft={true}
|
||||
isActive={false}
|
||||
isArchived={false}
|
||||
isInfo={false}
|
||||
isUnread={true}
|
||||
membersCount={1}
|
||||
size={16}
|
||||
status="online"
|
||||
teammateDeletedAt={0}
|
||||
theme={
|
||||
Object {
|
||||
"awayIndicator": "#ffbc42",
|
||||
"buttonBg": "#166de0",
|
||||
"buttonColor": "#ffffff",
|
||||
"centerChannelBg": "#ffffff",
|
||||
"centerChannelColor": "#3d3c40",
|
||||
"codeTheme": "github",
|
||||
"dndIndicator": "#f74343",
|
||||
"errorTextColor": "#fd5960",
|
||||
"linkColor": "#2389d7",
|
||||
"mentionBj": "#ffffff",
|
||||
"mentionColor": "#145dbf",
|
||||
"mentionHighlightBg": "#ffe577",
|
||||
"mentionHighlightLink": "#166de0",
|
||||
"newMessageSeparator": "#ff8800",
|
||||
"onlineIndicator": "#06d6a0",
|
||||
"sidebarBg": "#145dbf",
|
||||
"sidebarHeaderBg": "#1153ab",
|
||||
"sidebarHeaderTextColor": "#ffffff",
|
||||
"sidebarText": "#ffffff",
|
||||
"sidebarTextActiveBorder": "#579eff",
|
||||
"sidebarTextActiveColor": "#ffffff",
|
||||
"sidebarTextHoverBg": "#4578bf",
|
||||
"sidebarUnreadText": "#ffffff",
|
||||
"type": "Mattermost",
|
||||
}
|
||||
}
|
||||
type="O"
|
||||
/>
|
||||
<Component
|
||||
ellipsizeMode="tail"
|
||||
numberOfLines={1}
|
||||
style={
|
||||
Array [
|
||||
Object {
|
||||
"color": "rgba(255,255,255,0.4)",
|
||||
"flex": 1,
|
||||
"fontSize": 14,
|
||||
"fontWeight": "600",
|
||||
"height": "100%",
|
||||
"lineHeight": 44,
|
||||
"paddingRight": 40,
|
||||
"textAlignVertical": "center",
|
||||
},
|
||||
Object {
|
||||
"color": "#ffffff",
|
||||
},
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ export default class ChannelItem extends PureComponent {
|
|||
isChannelMuted: PropTypes.bool,
|
||||
isMyUser: PropTypes.bool,
|
||||
isUnread: PropTypes.bool,
|
||||
hasDraft: PropTypes.bool,
|
||||
mentions: PropTypes.number.isRequired,
|
||||
navigator: PropTypes.object,
|
||||
onSelectChannel: PropTypes.func.isRequired,
|
||||
|
|
@ -92,6 +93,7 @@ export default class ChannelItem extends PureComponent {
|
|||
isChannelMuted,
|
||||
isMyUser,
|
||||
isUnread,
|
||||
hasDraft,
|
||||
mentions,
|
||||
shouldHideChannel,
|
||||
status,
|
||||
|
|
@ -167,6 +169,7 @@ export default class ChannelItem extends PureComponent {
|
|||
isActive={isActive}
|
||||
channelId={channelId}
|
||||
isUnread={isUnread}
|
||||
hasDraft={hasDraft && channelId !== currentChannelId}
|
||||
membersCount={displayName.split(',').length}
|
||||
size={16}
|
||||
status={status}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@
|
|||
import React from 'react';
|
||||
import {shallow} from 'enzyme';
|
||||
|
||||
import Preferences from 'mattermost-redux/constants/preferences';
|
||||
|
||||
import ChannelItem from './channel_item.js';
|
||||
|
||||
jest.mock('react-intl');
|
||||
|
|
@ -17,6 +19,7 @@ describe('ChannelItem', () => {
|
|||
isChannelMuted: false,
|
||||
isMyUser: true,
|
||||
isUnread: true,
|
||||
hasDraft: false,
|
||||
mentions: 0,
|
||||
navigator: {push: () => {}}, // eslint-disable-line no-empty-function
|
||||
onSelectChannel: () => {}, // eslint-disable-line no-empty-function
|
||||
|
|
@ -25,12 +28,7 @@ describe('ChannelItem', () => {
|
|||
status: 'online',
|
||||
teammateDeletedAt: 0,
|
||||
type: 'O',
|
||||
theme: {
|
||||
sidebarText: '#aaa',
|
||||
sidebarTextActiveBorder: '#aaa',
|
||||
sidebarTextActiveColor: '#aaa',
|
||||
sidebarTextHoverBg: '#aaa',
|
||||
},
|
||||
theme: Preferences.THEMES.default,
|
||||
unreadMsgs: 1,
|
||||
isArchived: false,
|
||||
};
|
||||
|
|
@ -56,4 +54,16 @@ describe('ChannelItem', () => {
|
|||
);
|
||||
expect(wrapper.getElement()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should match snapshot with draft', () => {
|
||||
const wrapper = shallow(
|
||||
<ChannelItem
|
||||
{...baseProps}
|
||||
hasDraft={true}
|
||||
/>,
|
||||
{context: {intl: {formatMessage: jest.fn()}}},
|
||||
);
|
||||
|
||||
expect(wrapper.getElement()).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@ import {getCurrentUserId, getUser} from 'mattermost-redux/selectors/entities/use
|
|||
import {isChannelMuted} from 'mattermost-redux/utils/channel_utils';
|
||||
import {displayUsername} from 'mattermost-redux/utils/user_utils';
|
||||
|
||||
import {getDraftForChannel} from 'app/selectors/views';
|
||||
|
||||
import ChannelItem from './channel_item';
|
||||
|
||||
function makeMapStateToProps() {
|
||||
|
|
@ -22,8 +24,9 @@ function makeMapStateToProps() {
|
|||
|
||||
return (state, ownProps) => {
|
||||
const channel = ownProps.channel || getChannel(state, {id: ownProps.channelId});
|
||||
const member = getMyChannelMember(state, ownProps.channelId);
|
||||
const member = getMyChannelMember(state, channel.id);
|
||||
const currentUserId = getCurrentUserId(state);
|
||||
const channelDraft = getDraftForChannel(state, channel.id);
|
||||
|
||||
let isMyUser = false;
|
||||
let teammateDeletedAt = 0;
|
||||
|
|
@ -75,6 +78,7 @@ function makeMapStateToProps() {
|
|||
fake: channel.fake,
|
||||
isChannelMuted: isChannelMuted(member),
|
||||
isMyUser,
|
||||
hasDraft: Boolean(channelDraft.draft || channelDraft.files.length),
|
||||
mentions: member ? member.mention_count : 0,
|
||||
shouldHideChannel,
|
||||
showUnreadForMsgs,
|
||||
|
|
|
|||
|
|
@ -26,6 +26,11 @@ export const getCurrentChannelDraft = createSelector(
|
|||
}
|
||||
);
|
||||
|
||||
export function getDraftForChannel(state, channelId) {
|
||||
const drafts = getChannelDrafts(state);
|
||||
return drafts[channelId] || emptyDraft;
|
||||
}
|
||||
|
||||
export const getThreadDraft = createSelector(
|
||||
getThreadDrafts,
|
||||
(state, rootId) => rootId,
|
||||
|
|
|
|||
Loading…
Reference in a new issue