forked from Ivasoft/mattermost-mobile
Adds muted state to channel list in sidebar (#6042)
* Sorting categories body in the observable * Adds muted state to channel list in sidebar * update snapshots Co-authored-by: Elias Nahum <nahumhbl@gmail.com> Co-authored-by: Shaz Amjad <shaz.amjad@me.com>
This commit is contained in:
@@ -18,6 +18,7 @@ type ChannelIconProps = {
|
||||
isArchived?: boolean;
|
||||
isInfo?: boolean;
|
||||
isUnread?: boolean;
|
||||
isMuted?: boolean;
|
||||
membersCount?: number;
|
||||
name: string;
|
||||
shared: boolean;
|
||||
@@ -73,6 +74,9 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => {
|
||||
groupInfo: {
|
||||
color: theme.centerChannelColor,
|
||||
},
|
||||
muted: {
|
||||
opacity: 0.4,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
@@ -82,6 +86,7 @@ const ChannelIcon = ({
|
||||
isArchived = false,
|
||||
isInfo = false,
|
||||
isUnread = false,
|
||||
isMuted = false,
|
||||
membersCount = 0,
|
||||
name,
|
||||
shared,
|
||||
@@ -99,6 +104,7 @@ const ChannelIcon = ({
|
||||
let unreadGroupBox;
|
||||
let activeGroup;
|
||||
let unreadGroup;
|
||||
let mutedStyle;
|
||||
|
||||
if (isUnread) {
|
||||
unreadIcon = styles.iconUnread;
|
||||
@@ -118,6 +124,10 @@ const ChannelIcon = ({
|
||||
activeGroup = styles.groupInfo;
|
||||
}
|
||||
|
||||
if (isMuted) {
|
||||
mutedStyle = styles.muted;
|
||||
}
|
||||
|
||||
let icon;
|
||||
if (isArchived) {
|
||||
icon = (
|
||||
@@ -180,7 +190,7 @@ const ChannelIcon = ({
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={[styles.container, {width: size, height: size}, style]}>
|
||||
<View style={[styles.container, {width: size, height: size}, style, mutedStyle]}>
|
||||
{icon}
|
||||
</View>
|
||||
);
|
||||
|
||||
@@ -65,6 +65,7 @@ Object {
|
||||
"width": 24,
|
||||
},
|
||||
undefined,
|
||||
undefined,
|
||||
]
|
||||
}
|
||||
>
|
||||
@@ -104,6 +105,7 @@ Object {
|
||||
"paddingLeft": 12,
|
||||
},
|
||||
false,
|
||||
false,
|
||||
]
|
||||
}
|
||||
>
|
||||
|
||||
@@ -14,7 +14,7 @@ type Props = {
|
||||
category: CategoryModel;
|
||||
};
|
||||
|
||||
const extractKey = (item: any) => item;
|
||||
const extractKey = (item: string) => item;
|
||||
|
||||
const CategoryBody = ({currentChannelId, sortedIds, category}: Props) => {
|
||||
const ChannelItem = useCallback(({item}: {item: string}) => {
|
||||
|
||||
@@ -58,6 +58,7 @@ exports[`components/channel_list/categories/body/channel/item should match snaps
|
||||
"width": 24,
|
||||
},
|
||||
undefined,
|
||||
undefined,
|
||||
]
|
||||
}
|
||||
>
|
||||
@@ -120,6 +121,7 @@ exports[`components/channel_list/categories/body/channel/item should match snaps
|
||||
"paddingLeft": 12,
|
||||
},
|
||||
false,
|
||||
false,
|
||||
]
|
||||
}
|
||||
>
|
||||
|
||||
@@ -34,6 +34,7 @@ describe('components/channel_list/categories/body/channel/item', () => {
|
||||
isActive={false}
|
||||
isOwnDirectMessage={false}
|
||||
myChannel={myChannel}
|
||||
isMuted={false}
|
||||
collapsed={false}
|
||||
/>,
|
||||
);
|
||||
|
||||
@@ -39,6 +39,9 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => ({
|
||||
highlight: {
|
||||
color: theme.sidebarText,
|
||||
},
|
||||
muted: {
|
||||
color: changeOpacity(theme.sidebarText, 0.4),
|
||||
},
|
||||
}));
|
||||
|
||||
const textStyle = StyleSheet.create({
|
||||
@@ -50,18 +53,19 @@ type Props = {
|
||||
channel: Pick<ChannelModel, 'deleteAt' | 'displayName' | 'name' | 'shared' | 'type'>;
|
||||
isActive: boolean;
|
||||
isOwnDirectMessage: boolean;
|
||||
isMuted: boolean;
|
||||
myChannel: MyChannelModel;
|
||||
collapsed: boolean;
|
||||
}
|
||||
|
||||
const ChannelListItem = ({channel, isActive, isOwnDirectMessage, myChannel, collapsed}: Props) => {
|
||||
const ChannelListItem = ({channel, isActive, isOwnDirectMessage, isMuted, myChannel, collapsed}: Props) => {
|
||||
const {formatMessage} = useIntl();
|
||||
const theme = useTheme();
|
||||
const styles = getStyleSheet(theme);
|
||||
const serverUrl = useServerUrl();
|
||||
|
||||
// Make it brighter if it's highlighted, or has unreads
|
||||
const bright = myChannel.isUnread || myChannel.mentionsCount > 0;
|
||||
// Make it brighter if it's not muted, and highlighted or has unreads
|
||||
const bright = !isMuted && (myChannel.isUnread || myChannel.mentionsCount > 0);
|
||||
|
||||
const sharedValue = useSharedValue(collapsed && !bright);
|
||||
|
||||
@@ -89,7 +93,8 @@ const ChannelListItem = ({channel, isActive, isOwnDirectMessage, myChannel, coll
|
||||
bright ? textStyle.bright : textStyle.regular,
|
||||
styles.text,
|
||||
bright && styles.highlight,
|
||||
], [bright, styles]);
|
||||
isMuted && styles.muted,
|
||||
], [bright, styles, isMuted]);
|
||||
|
||||
let displayName = channel.displayName;
|
||||
if (isOwnDirectMessage) {
|
||||
|
||||
@@ -15,6 +15,7 @@ import ChannelListItem from './channel_list_item';
|
||||
import type {WithDatabaseArgs} from '@typings/database/database';
|
||||
import type ChannelModel from '@typings/database/models/servers/channel';
|
||||
import type MyChannelModel from '@typings/database/models/servers/my_channel';
|
||||
import type MyChannelSettingsModel from '@typings/database/models/servers/my_channel_settings';
|
||||
import type SystemModel from '@typings/database/models/servers/system';
|
||||
|
||||
const {SERVER: {MY_CHANNEL, SYSTEM}} = MM_TABLES;
|
||||
@@ -27,6 +28,8 @@ const enhance = withObservables(['channelId'], ({channelId, database}: {channelI
|
||||
);
|
||||
|
||||
const channel = myChannel.pipe(switchMap((my) => my.channel.observe()));
|
||||
const settings = channel.pipe(switchMap((c) => c.settings.observe()));
|
||||
|
||||
const isOwnDirectMessage = combineLatest([currentUserId, channel]).pipe(
|
||||
switchMap(([userId, ch]) => {
|
||||
if (ch?.type === General.DM_CHANNEL) {
|
||||
@@ -39,6 +42,9 @@ const enhance = withObservables(['channelId'], ({channelId, database}: {channelI
|
||||
);
|
||||
return {
|
||||
isOwnDirectMessage,
|
||||
isMuted: settings.pipe(
|
||||
switchMap((s: MyChannelSettingsModel) => of$(s.notifyProps?.mark_unread === 'mention')),
|
||||
),
|
||||
myChannel,
|
||||
channel: channel.pipe(
|
||||
switchMap((c: ChannelModel) => of$({
|
||||
|
||||
@@ -80,7 +80,13 @@ export default class CategoryModel extends Model implements CategoryInterface {
|
||||
@lazy channels = this.collections.
|
||||
get<ChannelModel>(CHANNEL).
|
||||
query(
|
||||
Q.on(CATEGORY_CHANNEL, 'category_id', this.id),
|
||||
Q.experimentalJoinTables([MY_CHANNEL, CATEGORY_CHANNEL]),
|
||||
Q.on(CATEGORY_CHANNEL,
|
||||
Q.and(
|
||||
Q.on(MY_CHANNEL, Q.where('id', Q.notEq(''))),
|
||||
Q.where('category_id', this.id),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
/** myChannels : Retrieves all myChannels that are part of this category */
|
||||
|
||||
@@ -28,6 +28,7 @@ class TestHelper {
|
||||
this.basicChannel = null;
|
||||
this.basicChannelMember = null;
|
||||
this.basicMyChannel = null;
|
||||
this.basicMyChannelSettings = null;
|
||||
this.basicPost = null;
|
||||
this.basicRoles = null;
|
||||
this.basicScheme = null;
|
||||
@@ -74,6 +75,10 @@ class TestHelper {
|
||||
channels: [this.basicChannel],
|
||||
myChannels: [this.basicMyChannel],
|
||||
});
|
||||
await operator.handleMyChannelSettings({
|
||||
prepareRecordsOnly: false,
|
||||
settings: [this.basicMyChannelSettings],
|
||||
});
|
||||
|
||||
const systems = await prepareCommonSystemValues(operator, {
|
||||
config: {},
|
||||
@@ -222,6 +227,20 @@ class TestHelper {
|
||||
};
|
||||
};
|
||||
|
||||
fakeMyChannelSettings = (channelId) => {
|
||||
return {
|
||||
id: channelId,
|
||||
channel_id: channelId,
|
||||
notify_props: JSON.stringify({
|
||||
desktop: 'default',
|
||||
email: 'default',
|
||||
mark_unread: 'all',
|
||||
push: 'default',
|
||||
ignore_channel_mentions: 'default',
|
||||
}),
|
||||
};
|
||||
};
|
||||
|
||||
fakeEmail = () => {
|
||||
return 'success' + this.generateId() + '@simulator.amazonses.com';
|
||||
};
|
||||
@@ -401,6 +420,7 @@ class TestHelper {
|
||||
this.basicCategoryChannel = this.fakeCategoryChannelWithId(this.basicTeam.id, this.basicCategory.id, this.basicChannel.id);
|
||||
this.basicChannelMember = this.fakeChannelMember(this.basicUser.id, this.basicChannel.id);
|
||||
this.basicMyChannel = this.fakeMyChannel(this.basicChannel.id);
|
||||
this.basicMyChannelSettings = this.fakeMyChannelSettings(this.basicChannel.id);
|
||||
this.basicPost = {...this.fakePostWithId(this.basicChannel.id), create_at: 1507841118796};
|
||||
this.basicRoles = {
|
||||
system_admin: {
|
||||
|
||||
Reference in New Issue
Block a user