diff --git a/app/components/loading_placeholder/__snapshots__/loading_placeholder.test.js.snap b/app/components/loading_placeholder/__snapshots__/loading_placeholder.test.js.snap
new file mode 100644
index 000000000..f387312c0
--- /dev/null
+++ b/app/components/loading_placeholder/__snapshots__/loading_placeholder.test.js.snap
@@ -0,0 +1,153 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`LoadingPlaceholder should match snapshot 1`] = `
+ShallowWrapper {
+ "length": 1,
+ Symbol(enzyme.__root__): [Circular],
+ Symbol(enzyme.__unrendered__): ,
+ Symbol(enzyme.__renderer__): Object {
+ "batchedUpdates": [Function],
+ "getNode": [Function],
+ "render": [Function],
+ "simulateEvent": [Function],
+ "unmount": [Function],
+ },
+ Symbol(enzyme.__node__): Object {
+ "instance": null,
+ "key": undefined,
+ "nodeType": "class",
+ "props": Object {
+ "accessible": true,
+ "allowFontScaling": true,
+ "children": Array [
+ ,
+ ,
+ ],
+ "ellipsizeMode": "tail",
+ },
+ "ref": null,
+ "rendered": Array [
+ Object {
+ "instance": null,
+ "key": undefined,
+ "nodeType": "class",
+ "props": Object {
+ "defaultMessage": "Loading",
+ "id": "loading_screen.loading",
+ },
+ "ref": null,
+ "rendered": null,
+ "type": [Function],
+ },
+ Object {
+ "instance": null,
+ "key": undefined,
+ "nodeType": "class",
+ "props": Object {
+ "animationDelay": 300,
+ "minOpacity": 0.4,
+ "numberOfDots": 3,
+ "style": Object {
+ "fontSize": 28,
+ "letterSpacing": -3,
+ "lineHeight": 30,
+ "marginLeft": 5,
+ },
+ },
+ "ref": null,
+ "rendered": null,
+ "type": [Function],
+ },
+ ],
+ "type": [Function],
+ },
+ Symbol(enzyme.__nodes__): Array [
+ Object {
+ "instance": null,
+ "key": undefined,
+ "nodeType": "class",
+ "props": Object {
+ "accessible": true,
+ "allowFontScaling": true,
+ "children": Array [
+ ,
+ ,
+ ],
+ "ellipsizeMode": "tail",
+ },
+ "ref": null,
+ "rendered": Array [
+ Object {
+ "instance": null,
+ "key": undefined,
+ "nodeType": "class",
+ "props": Object {
+ "defaultMessage": "Loading",
+ "id": "loading_screen.loading",
+ },
+ "ref": null,
+ "rendered": null,
+ "type": [Function],
+ },
+ Object {
+ "instance": null,
+ "key": undefined,
+ "nodeType": "class",
+ "props": Object {
+ "animationDelay": 300,
+ "minOpacity": 0.4,
+ "numberOfDots": 3,
+ "style": Object {
+ "fontSize": 28,
+ "letterSpacing": -3,
+ "lineHeight": 30,
+ "marginLeft": 5,
+ },
+ },
+ "ref": null,
+ "rendered": null,
+ "type": [Function],
+ },
+ ],
+ "type": [Function],
+ },
+ ],
+ Symbol(enzyme.__options__): Object {
+ "adapter": ReactSixteenAdapter {
+ "options": Object {
+ "enableComponentDidUpdateOnSetState": true,
+ },
+ },
+ },
+}
+`;
diff --git a/app/components/loading_placeholder/index.js b/app/components/loading_placeholder/index.js
new file mode 100644
index 000000000..e2dc72fb9
--- /dev/null
+++ b/app/components/loading_placeholder/index.js
@@ -0,0 +1,28 @@
+// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
+// See LICENSE.txt for license information.
+
+import React from 'react';
+import AnimatedEllipsis from 'react-native-animated-ellipsis';
+import FormattedText from 'app/components/formatted_text';
+
+import {Text} from 'react-native';
+
+const LoadingPlaceholder = () => (
+
+
+
+
+);
+
+export default LoadingPlaceholder;
diff --git a/app/components/loading_placeholder/loading_placeholder.test.js b/app/components/loading_placeholder/loading_placeholder.test.js
new file mode 100644
index 000000000..96293f111
--- /dev/null
+++ b/app/components/loading_placeholder/loading_placeholder.test.js
@@ -0,0 +1,19 @@
+// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
+// See LICENSE.txt for license information.
+
+import React from 'react';
+import {configure, shallow} from 'enzyme';
+import Adapter from 'enzyme-adapter-react-16';
+configure({adapter: new Adapter()});
+
+import LoadingPlaceholder from './index.js';
+
+describe('LoadingPlaceholder', () => {
+ test('should match snapshot', () => {
+ const wrapper = shallow(
+
+ );
+
+ expect(wrapper).toMatchSnapshot();
+ });
+});
diff --git a/app/components/sidebars/main/channels_list/channel_item/__snapshots__/channel_item.test.js.snap b/app/components/sidebars/main/channels_list/channel_item/__snapshots__/channel_item.test.js.snap
index 0fcd3bb59..cba55a39a 100644
--- a/app/components/sidebars/main/channels_list/channel_item/__snapshots__/channel_item.test.js.snap
+++ b/app/components/sidebars/main/channels_list/channel_item/__snapshots__/channel_item.test.js.snap
@@ -121,7 +121,9 @@ ShallowWrapper {
},
]
}
- />
+ >
+
+
,
@@ -200,7 +202,9 @@ ShallowWrapper {
},
]
}
- />
+ >
+
+
,
"delayPressOut": 100,
@@ -271,7 +275,9 @@ ShallowWrapper {
},
]
}
- />
+ >
+
+
,
],
"style": Array [
@@ -334,7 +340,9 @@ ShallowWrapper {
},
]
}
- />,
+ >
+
+ ,
undefined,
],
"style": Array [
@@ -382,7 +390,7 @@ ShallowWrapper {
"props": Object {
"accessible": true,
"allowFontScaling": true,
- "children": undefined,
+ "children": ,
"ellipsizeMode": "tail",
"numberOfLines": 1,
"style": Array [
@@ -402,7 +410,15 @@ ShallowWrapper {
],
},
"ref": null,
- "rendered": null,
+ "rendered": Object {
+ "instance": null,
+ "key": undefined,
+ "nodeType": "function",
+ "props": Object {},
+ "ref": null,
+ "rendered": null,
+ "type": [Function],
+ },
"type": [Function],
},
undefined,
@@ -496,7 +512,9 @@ ShallowWrapper {
},
]
}
- />
+ >
+
+
,
@@ -575,7 +593,9 @@ ShallowWrapper {
},
]
}
- />
+ >
+
+
,
"delayPressOut": 100,
@@ -646,7 +666,9 @@ ShallowWrapper {
},
]
}
- />
+ >
+
+
,
],
"style": Array [
@@ -709,7 +731,9 @@ ShallowWrapper {
},
]
}
- />,
+ >
+
+ ,
undefined,
],
"style": Array [
@@ -757,7 +781,7 @@ ShallowWrapper {
"props": Object {
"accessible": true,
"allowFontScaling": true,
- "children": undefined,
+ "children": ,
"ellipsizeMode": "tail",
"numberOfLines": 1,
"style": Array [
@@ -777,7 +801,15 @@ ShallowWrapper {
],
},
"ref": null,
- "rendered": null,
+ "rendered": Object {
+ "instance": null,
+ "key": undefined,
+ "nodeType": "function",
+ "props": Object {},
+ "ref": null,
+ "rendered": null,
+ "type": [Function],
+ },
"type": [Function],
},
undefined,
@@ -818,3 +850,854 @@ ShallowWrapper {
},
}
`;
+
+exports[`ChannelItem should match snapshot for no displayName 1`] = `
+ShallowWrapper {
+ "length": 1,
+ Symbol(enzyme.__root__): [Circular],
+ Symbol(enzyme.__unrendered__): ,
+ Symbol(enzyme.__renderer__): Object {
+ "batchedUpdates": [Function],
+ "getNode": [Function],
+ "render": [Function],
+ "simulateEvent": [Function],
+ "unmount": [Function],
+ },
+ Symbol(enzyme.__node__): Object {
+ "instance": null,
+ "key": undefined,
+ "nodeType": "class",
+ "props": Object {
+ "children":
+
+
+
+
+
+
+
+
+ ,
+ },
+ "ref": [Function],
+ "rendered": Object {
+ "instance": null,
+ "key": undefined,
+ "nodeType": "class",
+ "props": Object {
+ "activeOpacity": 0.85,
+ "children":
+
+
+
+
+
+
+ ,
+ "delayPressOut": 100,
+ "onLongPress": [Function],
+ "onPress": [Function],
+ "underlayColor": "rgba(170,170,170,0.5)",
+ },
+ "ref": null,
+ "rendered": Object {
+ "instance": null,
+ "key": undefined,
+ "nodeType": "class",
+ "props": Object {
+ "children": Array [
+ undefined,
+
+
+
+
+
+ ,
+ ],
+ "style": Array [
+ Object {
+ "flex": 1,
+ "flexDirection": "row",
+ "height": 44,
+ },
+ undefined,
+ ],
+ },
+ "ref": null,
+ "rendered": Array [
+ undefined,
+ Object {
+ "instance": null,
+ "key": undefined,
+ "nodeType": "class",
+ "props": Object {
+ "children": Array [
+ ,
+
+
+ ,
+ undefined,
+ ],
+ "style": Array [
+ Object {
+ "alignItems": "center",
+ "flex": 1,
+ "flexDirection": "row",
+ "paddingLeft": 16,
+ },
+ undefined,
+ ],
+ },
+ "ref": null,
+ "rendered": Array [
+ Object {
+ "instance": null,
+ "key": undefined,
+ "nodeType": "class",
+ "props": Object {
+ "channelId": "channel_id",
+ "isActive": false,
+ "isArchived": false,
+ "isInfo": false,
+ "isUnread": true,
+ "membersCount": 1,
+ "size": 16,
+ "status": "online",
+ "teammateDeletedAt": 0,
+ "theme": Object {
+ "sidebarText": "#aaa",
+ "sidebarTextActiveBorder": "#aaa",
+ "sidebarTextActiveColor": "#aaa",
+ "sidebarTextHoverBg": "#aaa",
+ },
+ "type": "O",
+ },
+ "ref": null,
+ "rendered": null,
+ "type": [Function],
+ },
+ Object {
+ "instance": null,
+ "key": undefined,
+ "nodeType": "class",
+ "props": Object {
+ "accessible": true,
+ "allowFontScaling": true,
+ "children": ,
+ "ellipsizeMode": "tail",
+ "numberOfLines": 1,
+ "style": Array [
+ Object {
+ "color": "rgba(170,170,170,0.4)",
+ "flex": 1,
+ "fontSize": 14,
+ "fontWeight": "600",
+ "height": "100%",
+ "lineHeight": 44,
+ "paddingRight": 40,
+ "textAlignVertical": "center",
+ },
+ Object {
+ "color": undefined,
+ },
+ ],
+ },
+ "ref": null,
+ "rendered": Object {
+ "instance": null,
+ "key": undefined,
+ "nodeType": "function",
+ "props": Object {},
+ "ref": null,
+ "rendered": null,
+ "type": [Function],
+ },
+ "type": [Function],
+ },
+ undefined,
+ ],
+ "type": [Function],
+ },
+ ],
+ "type": [Function],
+ },
+ "type": [Function],
+ },
+ "type": [Function],
+ },
+ Symbol(enzyme.__nodes__): Array [
+ Object {
+ "instance": null,
+ "key": undefined,
+ "nodeType": "class",
+ "props": Object {
+ "children":
+
+
+
+
+
+
+
+
+ ,
+ },
+ "ref": [Function],
+ "rendered": Object {
+ "instance": null,
+ "key": undefined,
+ "nodeType": "class",
+ "props": Object {
+ "activeOpacity": 0.85,
+ "children":
+
+
+
+
+
+
+ ,
+ "delayPressOut": 100,
+ "onLongPress": [Function],
+ "onPress": [Function],
+ "underlayColor": "rgba(170,170,170,0.5)",
+ },
+ "ref": null,
+ "rendered": Object {
+ "instance": null,
+ "key": undefined,
+ "nodeType": "class",
+ "props": Object {
+ "children": Array [
+ undefined,
+
+
+
+
+
+ ,
+ ],
+ "style": Array [
+ Object {
+ "flex": 1,
+ "flexDirection": "row",
+ "height": 44,
+ },
+ undefined,
+ ],
+ },
+ "ref": null,
+ "rendered": Array [
+ undefined,
+ Object {
+ "instance": null,
+ "key": undefined,
+ "nodeType": "class",
+ "props": Object {
+ "children": Array [
+ ,
+
+
+ ,
+ undefined,
+ ],
+ "style": Array [
+ Object {
+ "alignItems": "center",
+ "flex": 1,
+ "flexDirection": "row",
+ "paddingLeft": 16,
+ },
+ undefined,
+ ],
+ },
+ "ref": null,
+ "rendered": Array [
+ Object {
+ "instance": null,
+ "key": undefined,
+ "nodeType": "class",
+ "props": Object {
+ "channelId": "channel_id",
+ "isActive": false,
+ "isArchived": false,
+ "isInfo": false,
+ "isUnread": true,
+ "membersCount": 1,
+ "size": 16,
+ "status": "online",
+ "teammateDeletedAt": 0,
+ "theme": Object {
+ "sidebarText": "#aaa",
+ "sidebarTextActiveBorder": "#aaa",
+ "sidebarTextActiveColor": "#aaa",
+ "sidebarTextHoverBg": "#aaa",
+ },
+ "type": "O",
+ },
+ "ref": null,
+ "rendered": null,
+ "type": [Function],
+ },
+ Object {
+ "instance": null,
+ "key": undefined,
+ "nodeType": "class",
+ "props": Object {
+ "accessible": true,
+ "allowFontScaling": true,
+ "children": ,
+ "ellipsizeMode": "tail",
+ "numberOfLines": 1,
+ "style": Array [
+ Object {
+ "color": "rgba(170,170,170,0.4)",
+ "flex": 1,
+ "fontSize": 14,
+ "fontWeight": "600",
+ "height": "100%",
+ "lineHeight": 44,
+ "paddingRight": 40,
+ "textAlignVertical": "center",
+ },
+ Object {
+ "color": undefined,
+ },
+ ],
+ },
+ "ref": null,
+ "rendered": Object {
+ "instance": null,
+ "key": undefined,
+ "nodeType": "function",
+ "props": Object {},
+ "ref": null,
+ "rendered": null,
+ "type": [Function],
+ },
+ "type": [Function],
+ },
+ undefined,
+ ],
+ "type": [Function],
+ },
+ ],
+ "type": [Function],
+ },
+ "type": [Function],
+ },
+ "type": [Function],
+ },
+ ],
+ Symbol(enzyme.__options__): Object {
+ "adapter": ReactSixteenAdapter {
+ "options": Object {
+ "enableComponentDidUpdateOnSetState": true,
+ },
+ },
+ "context": Object {
+ "intl": Object {
+ "formatMessage": [MockFunction] {
+ "calls": Array [
+ Array [
+ Object {
+ "defaultMessage": "{displayName} (you)",
+ "id": "channel_header.directchannel.you",
+ },
+ Object {
+ "displayname": "",
+ },
+ ],
+ ],
+ },
+ },
+ },
+ },
+}
+`;
diff --git a/app/components/sidebars/main/channels_list/channel_item/channel_item.js b/app/components/sidebars/main/channels_list/channel_item/channel_item.js
index c87678098..cce3eca36 100644
--- a/app/components/sidebars/main/channels_list/channel_item/channel_item.js
+++ b/app/components/sidebars/main/channels_list/channel_item/channel_item.js
@@ -14,6 +14,7 @@ import {intlShape} from 'react-intl';
import Badge from 'app/components/badge';
import ChannelIcon from 'app/components/channel_icon';
+import LoadingPlaceholder from 'app/components/loading_placeholder';
import {preventDoubleTap} from 'app/utils/tap';
import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme';
@@ -113,14 +114,6 @@ export default class ChannelItem extends PureComponent {
const {intl} = this.context;
- let channelDisplayName = displayName;
- if (isMyUser) {
- channelDisplayName = intl.formatMessage({
- id: 'channel_header.directchannel.you',
- defaultMessage: '{displayName} (you)',
- }, {displayname: displayName});
- }
-
const style = getStyleSheet(theme);
const isActive = channelId === currentChannelId;
@@ -140,6 +133,20 @@ export default class ChannelItem extends PureComponent {
extraTextStyle = style.textUnread;
}
+ let channelDisplayName = displayName;
+ if (isMyUser) {
+ channelDisplayName = intl.formatMessage({
+ id: 'channel_header.directchannel.you',
+ defaultMessage: '{displayName} (you)',
+ }, {displayname: displayName});
+ }
+
+ if (!channelDisplayName) {
+ channelDisplayName = (
+
+ );
+ }
+
let badge;
if (mentions) {
badge = (
diff --git a/app/components/sidebars/main/channels_list/channel_item/channel_item.test.js b/app/components/sidebars/main/channels_list/channel_item/channel_item.test.js
index 3ce307c00..7f4bd614f 100644
--- a/app/components/sidebars/main/channels_list/channel_item/channel_item.test.js
+++ b/app/components/sidebars/main/channels_list/channel_item/channel_item.test.js
@@ -45,4 +45,18 @@ describe('ChannelItem', () => {
expect(wrapper).toMatchSnapshot();
});
+
+ test('should match snapshot for no displayName', () => {
+ const props = {
+ ...baseProps,
+ displayName: '',
+ };
+
+ const wrapper = shallow(
+ ,
+ {context: {intl: {formatMessage: jest.fn()}}},
+ );
+
+ expect(wrapper).toMatchSnapshot();
+ });
});
diff --git a/app/components/sidebars/main/channels_list/channel_item/index.js b/app/components/sidebars/main/channels_list/channel_item/index.js
index 2e0e1435d..6fbd29625 100644
--- a/app/components/sidebars/main/channels_list/channel_item/index.js
+++ b/app/components/sidebars/main/channels_list/channel_item/index.js
@@ -10,9 +10,10 @@ import {
getMyChannelMember,
shouldHideDefaultChannel,
} from 'mattermost-redux/selectors/entities/channels';
-import {getTheme} from 'mattermost-redux/selectors/entities/preferences';
+import {getTheme, getTeammateNameDisplaySetting} from 'mattermost-redux/selectors/entities/preferences';
import {getCurrentUserId, getUser} from 'mattermost-redux/selectors/entities/users';
import {isChannelMuted} from 'mattermost-redux/utils/channel_utils';
+import {displayUsername} from 'mattermost-redux/utils/user_utils';
import ChannelItem from './channel_item';
@@ -26,12 +27,15 @@ function makeMapStateToProps() {
let isMyUser = false;
let teammateDeletedAt = 0;
+ let displayName = channel.display_name;
if (channel.type === General.DM_CHANNEL && channel.teammate_id) {
isMyUser = channel.teammate_id === currentUserId;
const teammate = getUser(state, channel.teammate_id);
if (teammate && teammate.delete_at) {
teammateDeletedAt = teammate.delete_at;
}
+ const teammateNameDisplay = getTeammateNameDisplaySetting(state);
+ displayName = displayUsername(teammate, teammateNameDisplay, false);
}
const currentChannelId = getCurrentChannelId(state);
@@ -57,10 +61,9 @@ function makeMapStateToProps() {
if (member && member.notify_props) {
showUnreadForMsgs = member.notify_props.mark_unread !== General.MENTION;
}
-
return {
currentChannelId,
- displayName: channel.display_name,
+ displayName,
fake: channel.fake,
isChannelMuted: isChannelMuted(member),
isMyUser,
diff --git a/package-lock.json b/package-lock.json
index ef5f3fe17..753ab065f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -10108,8 +10108,8 @@
}
},
"mattermost-redux": {
- "version": "github:mattermost/mattermost-redux#12353bc88f20dde53b6191747790c6a82b8dd527",
- "from": "github:mattermost/mattermost-redux#12353bc88f20dde53b6191747790c6a82b8dd527",
+ "version": "github:mattermost/mattermost-redux#f13022064f1ed24a0d1c085f433490f9d40cfc2f",
+ "from": "github:mattermost/mattermost-redux#f13022064f1ed24a0d1c085f433490f9d40cfc2f",
"requires": {
"deep-equal": "1.0.1",
"eslint-plugin-header": "1.2.0",
@@ -14626,6 +14626,13 @@
"prop-types": "^15.5.10"
}
},
+ "react-native-animated-ellipsis": {
+ "version": "github:sudheerDev/react-native-animated-ellipsis#326167b8e0fa3b6f0422c06be412bf177b725666",
+ "from": "github:sudheerDev/react-native-animated-ellipsis#326167b8e0fa3b6f0422c06be412bf177b725666",
+ "requires": {
+ "prop-types": "^15.5.10"
+ }
+ },
"react-native-bottom-sheet": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/react-native-bottom-sheet/-/react-native-bottom-sheet-1.0.3.tgz",
diff --git a/package.json b/package.json
index 414e85b9f..0df80744e 100644
--- a/package.json
+++ b/package.json
@@ -15,13 +15,14 @@
"intl": "1.2.5",
"jail-monkey": "1.0.0",
"jsc-android": "216113.0.3",
- "mattermost-redux": "github:mattermost/mattermost-redux#12353bc88f20dde53b6191747790c6a82b8dd527",
+ "mattermost-redux": "github:mattermost/mattermost-redux#f13022064f1ed24a0d1c085f433490f9d40cfc2f",
"mime-db": "1.33.0",
"prop-types": "15.6.1",
"react": "16.3.2",
"react-intl": "2.4.0",
"react-native": "github:enahum/react-native#mm",
"react-native-animatable": "1.2.4",
+ "react-native-animated-ellipsis": "sudheerDev/react-native-animated-ellipsis.git#326167b8e0fa3b6f0422c06be412bf177b725666",
"react-native-bottom-sheet": "1.0.3",
"react-native-button": "2.3.0",
"react-native-circular-progress": "0.2.0",