diff options
author | Alexander Smaga <smagaan@gmail.com> | 2016-10-26 15:20:45 +0300 |
---|---|---|
committer | Christopher Speller <crspeller@gmail.com> | 2016-10-26 08:20:45 -0400 |
commit | b354d25d3731b53613489d95cfa4c946cf8e0888 (patch) | |
tree | b1e11d3c9eef60cd9d8bd7a51b16dc49cff01af7 /webapp/utils/channel_utils.jsx | |
parent | 66ed155a58b6f0f365db26fa9e4e605d3d4a61a2 (diff) | |
download | chat-b354d25d3731b53613489d95cfa4c946cf8e0888.tar.gz chat-b354d25d3731b53613489d95cfa4c946cf8e0888.tar.bz2 chat-b354d25d3731b53613489d95cfa4c946cf8e0888.zip |
GH-4095 Favorite/Starred Channels (#4222)
Diffstat (limited to 'webapp/utils/channel_utils.jsx')
-rw-r--r-- | webapp/utils/channel_utils.jsx | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/webapp/utils/channel_utils.jsx b/webapp/utils/channel_utils.jsx new file mode 100644 index 000000000..119021fce --- /dev/null +++ b/webapp/utils/channel_utils.jsx @@ -0,0 +1,135 @@ + +import Constants from 'utils/constants.jsx'; +const Preferences = Constants.Preferences; + +import * as Utils from 'utils/utils.jsx'; + +import UserStore from 'stores/user_store.jsx'; +import TeamStore from 'stores/team_store.jsx'; +import PreferenceStore from 'stores/preference_store.jsx'; +import LocalizationStore from 'stores/localization_store.jsx'; + +/** + * Returns list of sorted channels grouped by type. Favorites here is considered as separated type. + * + * Example: { + * publicChannels: [...], + * privateChannels: [...], + * directChannels: [...], + * directNonTeamChannels: [...], + * favoriteChannels: [...] + * } + */ +export function buildDisplayableChannelList(persistentChannels) { + const missingDMChannels = createMissingDirectChannels(persistentChannels); + + const channels = persistentChannels.concat(missingDMChannels).map(completeDirectChannelInfo); + channels.sort(sortChannelsByDisplayName); + + const favoriteChannels = channels.filter(isFavoriteChannel); + const notFavoriteChannels = channels.filter(not(isFavoriteChannel)); + const directChannels = notFavoriteChannels.filter(andX(isDirectChannel, isDirectChannelVisible)); + + return { + favoriteChannels, + publicChannels: notFavoriteChannels.filter(isOpenChannel), + privateChannels: notFavoriteChannels.filter(isPrivateChannel), + directChannels: directChannels.filter(isConnectedToTeamMember), + directNonTeamChannels: directChannels.filter(not(isConnectedToTeamMember)) + }; +} + +export function isFavoriteChannel(channel) { + return PreferenceStore.getBool(Preferences.CATEGORY_FAVORITE_CHANNEL, channel.id); +} + +export function isOpenChannel(channel) { + return channel.type === Constants.OPEN_CHANNEL; +} + +export function isPrivateChannel(channel) { + return channel.type === Constants.PRIVATE_CHANNEL; +} + +export function isDirectChannel(channel) { + return channel.type === Constants.DM_CHANNEL; +} + +export function isDirectChannelVisible(channel) { + const channelId = Utils.getUserIdFromChannelName(channel); + + return PreferenceStore.getBool(Preferences.CATEGORY_DIRECT_CHANNEL_SHOW, channelId); +} + +export function completeDirectChannelInfo(channel) { + if (!isDirectChannel(channel)) { + return channel; + } + + const dmChannelClone = JSON.parse(JSON.stringify(channel)); + const teammateId = Utils.getUserIdFromChannelName(channel); + + return Object.assign(dmChannelClone, { + display_name: Utils.displayUsername(teammateId), + teammate_id: teammateId, + status: UserStore.getStatus(teammateId) || 'offline' + }); +} + +export function sortChannelsByDisplayName(a, b) { + const locale = LocalizationStore.getLocale(); + + return buildDisplayNameAndTypeComparable(a).localeCompare(buildDisplayNameAndTypeComparable(b), locale, {numeric: true}); +} + +/* + * not exported helpers + */ + +function createMissingDirectChannels(channels) { + const directChannelsDisplayPreferences = PreferenceStore.getCategory(Preferences.CATEGORY_DIRECT_CHANNEL_SHOW); + + return Array. + from(directChannelsDisplayPreferences). + filter((entry) => entry[1] === 'true'). + map((entry) => entry[0]). + filter((teammateId) => !channels.some(Utils.isDirectChannelForUser.bind(null, teammateId))). + map(createFakeChannelCurried(UserStore.getCurrentId())); +} + +function createFakeChannel(userId, otherUserId) { + return { + name: Utils.getDirectChannelName(userId, otherUserId), + last_post_at: 0, + total_msg_count: 0, + type: Constants.DM_CHANNEL, + fake: true + }; +} + +function createFakeChannelCurried(userId) { + return (otherUserId) => createFakeChannel(userId, otherUserId); +} + +function isConnectedToTeamMember(channel) { + return isTeamMember(channel.teammate_id); +} + +function isTeamMember(userId) { + return TeamStore.hasActiveMemberInTeam(TeamStore.getCurrentId(), userId); +} + +function not(f) { + return (...args) => !f(...args); +} + +function andX(...fns) { + return (...args) => fns.every((f) => f(...args)); +} + +const defaultPrefix = 'D'; // fallback for future types +const typeToPrefixMap = {[Constants.OPEN_CHANNEL]: 'A', [Constants.PRIVATE_CHANNEL]: 'B', [Constants.DM_CHANNEL]: 'C'}; + +function buildDisplayNameAndTypeComparable(channel) { + return (typeToPrefixMap[channel.type] || defaultPrefix) + channel.display_name + channel.name; +} |