From 7d03c24b44a2f4eba86adf86954280fa73e726e4 Mon Sep 17 00:00:00 2001
From: hmhealey <harrisonmhealey@gmail.com>
Date: Fri, 2 Oct 2015 09:50:34 -0400
Subject: Changed direct channels in the sidebar to be displayed based on user
 preferences

---
 web/react/components/sidebar.jsx | 166 ++++++++++++++++++++++++++++++---------
 1 file changed, 129 insertions(+), 37 deletions(-)

(limited to 'web/react/components/sidebar.jsx')

diff --git a/web/react/components/sidebar.jsx b/web/react/components/sidebar.jsx
index 4ac1fd4a0..115e9c9c6 100644
--- a/web/react/components/sidebar.jsx
+++ b/web/react/components/sidebar.jsx
@@ -1,19 +1,20 @@
 // Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
 // See License.txt for license information.
 
-var ChannelStore = require('../stores/channel_store.jsx');
-var Client = require('../utils/client.jsx');
-var AsyncClient = require('../utils/async_client.jsx');
-var SocketStore = require('../stores/socket_store.jsx');
-var UserStore = require('../stores/user_store.jsx');
-var TeamStore = require('../stores/team_store.jsx');
-var BrowserStore = require('../stores/browser_store.jsx');
-var Utils = require('../utils/utils.jsx');
-var SidebarHeader = require('./sidebar_header.jsx');
-var SearchBox = require('./search_bar.jsx');
-var Constants = require('../utils/constants.jsx');
-var NewChannelFlow = require('./new_channel_flow.jsx');
-var UnreadChannelIndicator = require('./unread_channel_indicator.jsx');
+const AsyncClient = require('../utils/async_client.jsx');
+const BrowserStore = require('../stores/browser_store.jsx');
+const ChannelStore = require('../stores/channel_store.jsx');
+const Client = require('../utils/client.jsx');
+const Constants = require('../utils/constants.jsx');
+const PreferenceStore = require('../stores/preference_store.jsx');
+const NewChannelFlow = require('./new_channel_flow.jsx');
+const SearchBox = require('./search_bar.jsx');
+const SidebarHeader = require('./sidebar_header.jsx');
+const SocketStore = require('../stores/socket_store.jsx');
+const TeamStore = require('../stores/team_store.jsx');
+const UnreadChannelIndicator = require('./unread_channel_indicator.jsx');
+const UserStore = require('../stores/user_store.jsx');
+const Utils = require('../utils/utils.jsx');
 
 export default class Sidebar extends React.Component {
     constructor(props) {
@@ -23,6 +24,9 @@ export default class Sidebar extends React.Component {
         this.firstUnreadChannel = null;
         this.lastUnreadChannel = null;
 
+        this.getStateFromStores = this.getStateFromStores.bind(this);
+        //this.getDirectChannelsFromStores = this.getDirectChannelsFromStores.bind(this);
+
         this.onChange = this.onChange.bind(this);
         this.onScroll = this.onScroll.bind(this);
         this.onResize = this.onResize.bind(this);
@@ -36,7 +40,7 @@ export default class Sidebar extends React.Component {
         this.state = state;
     }
     getStateFromStores() {
-        var members = ChannelStore.getAllMembers();
+        const members = ChannelStore.getAllMembers();
         var teamMemberMap = UserStore.getActiveOnlyProfiles();
         var currentId = ChannelStore.getCurrentId();
 
@@ -48,11 +52,13 @@ export default class Sidebar extends React.Component {
             teammates.push(teamMemberMap[id]);
         }
 
+        const preferences = PreferenceStore.getPreferences('direct_channels', 'show_hide');
+
         // Create lists of all read and unread direct channels
-        var showDirectChannels = [];
-        var readDirectChannels = [];
+        var visibleDirectChannels = [];
+        var hiddenDirectChannels = [];
         for (var i = 0; i < teammates.length; i++) {
-            var teammate = teammates[i];
+            const teammate = teammates[i];
 
             if (teammate.id === UserStore.getCurrentId()) {
                 continue;
@@ -65,7 +71,7 @@ export default class Sidebar extends React.Component {
                 channelName = teammate.id + '__' + UserStore.getCurrentId();
             }
 
-            var channel = ChannelStore.getByName(channelName);
+            let channel = ChannelStore.getByName(channelName);
 
             if (channel == null) {
                 var tempChannel = {};
@@ -84,21 +90,44 @@ export default class Sidebar extends React.Component {
 
                 channel.status = UserStore.getStatus(teammate.id);
 
-                var channelMember = members[channel.id];
+                /*var channelMember = members[channel.id];
                 var msgCount = channel.total_msg_count - channelMember.msg_count;
                 if (msgCount > 0) {
-                    showDirectChannels.push(channel);
+                    visibleDirectChannels.push(channel);
                 } else if (currentId === channel.id) {
-                    showDirectChannels.push(channel);
+                    visibleDirectChannels.push(channel);
                 } else {
-                    readDirectChannels.push(channel);
-                }
+                    hiddenDirectChannels.push(channel);
+                }*/
+            } else {
+                channel = {};
+                channel.fake = true;
+                channel.name = channelName;
+                channel.display_name = teammate.username;
+                channel.teammate_username = teammate.username;
+                channel.status = UserStore.getStatus(teammate.id);
+                channel.last_post_at = 0;
+                channel.total_msg_count = 0;
+                channel.type = 'D';
+            }
+
+            if (preferences.some((preference) => (preference.alt_id === teammate.id && preference.value !== 'false'))) {
+                visibleDirectChannels.push(channel);
+            } else {
+                hiddenDirectChannels.push(channel);
             }
         }
 
-        // If we don't have MAX_DMS unread channels, sort the read list by last_post_at
-        if (showDirectChannels.length < Constants.MAX_DMS) {
-            readDirectChannels.sort(function sortByLastPost(a, b) {
+        function sortByDisplayName(a, b) {
+            return a.display_name.localeCompare(b.display_name);
+        }
+
+        visibleDirectChannels.sort(sortByDisplayName);
+        hiddenDirectChannels.sort(sortByDisplayName);
+
+        /*// If we don't have MAX_DMS unread channels, sort the read list by last_post_at
+        if (visibleDirectChannels.length < Constants.MAX_DMS) {
+            hiddenDirectChannels.sort(function sortByLastPost(a, b) {
                 // sort by last_post_at first
                 if (a.last_post_at > b.last_post_at) {
                     return -1;
@@ -118,13 +147,13 @@ export default class Sidebar extends React.Component {
             });
 
             var index = 0;
-            while (showDirectChannels.length < Constants.MAX_DMS && index < readDirectChannels.length) {
-                showDirectChannels.push(readDirectChannels[index]);
+            while (visibleDirectChannels.length < Constants.MAX_DMS && index < hiddenDirectChannels.length) {
+                visibleDirectChannels.push(hiddenDirectChannels[index]);
                 index++;
             }
-            readDirectChannels = readDirectChannels.slice(index);
+            hiddenDirectChannels = hiddenDirectChannels.slice(index);
 
-            showDirectChannels.sort(function directSort(a, b) {
+            visibleDirectChannels.sort(function directSort(a, b) {
                 if (a.display_name < b.display_name) {
                     return -1;
                 }
@@ -133,22 +162,84 @@ export default class Sidebar extends React.Component {
                 }
                 return 0;
             });
-        }
+        }*/
 
         return {
             activeId: currentId,
             channels: ChannelStore.getAll(),
             members: members,
-            showDirectChannels: showDirectChannels,
-            hideDirectChannels: readDirectChannels
+            visibleDirectChannels: visibleDirectChannels,
+            hiddenDirectChannels: hiddenDirectChannels
         };
     }
+
+    /*getDirectChannelsFromStores() {
+        const id = UserStore.getCurrentId();
+
+        const channels = [];
+        const preferences = PreferenceStore.getPreferences('direct_channels', 'show_hide');
+        for (const preference of preferences) {
+            if (preference.value !== 'true') {
+                continue;
+            }
+
+            const otherId = preference.alt_id;
+
+            if (otherId === id) {
+                continue;
+            }
+
+            const teammate = UserStore.getProfile(otherId);
+
+            if (!teammate) {
+                continue;
+            }
+
+            let channelName = '';
+            if (otherId > id) {
+                channelName = `${id}__${otherId}`;
+            } else {
+                channelName = `${otherId}__${id}`;
+            }
+
+            const channel = ChannelStore.getByName(channelName);
+
+            if (channel != null) {
+                channel.display_name = teammate.username;
+                channel.teammate_username = teammate.username;
+
+                channel.status = UserStore.getStatus(otherId);
+
+                channels.push(channel);
+            } else {
+                const tempChannel = {};
+                tempChannel.fake = true;
+                tempChannel.name = channelName;
+                tempChannel.display_name = teammate.username;
+                tempChannel.teammate_username = teammate.username;
+                tempChannel.status = UserStore.getStatus(teammate.id);
+                tempChannel.last_post_at = 0;
+                tempChannel.total_msg_count = 0;
+                tempChannel.type = 'D';
+                channels.push(tempChannel);
+            }
+        }
+
+        channels.sort((a, b) => a.display_name.localeCompare(b));
+
+        return channels;
+    }*/
+
     componentDidMount() {
         ChannelStore.addChangeListener(this.onChange);
         UserStore.addChangeListener(this.onChange);
         UserStore.addStatusesChangeListener(this.onChange);
         TeamStore.addChangeListener(this.onChange);
         SocketStore.addChangeListener(this.onSocketChange);
+        PreferenceStore.addChangeListener(this.onChange);
+
+        AsyncClient.getDirectChannels();
+
         $('.nav-pills__container').perfectScrollbar();
 
         this.updateTitle();
@@ -178,6 +269,7 @@ export default class Sidebar extends React.Component {
         UserStore.removeStatusesChangeListener(this.onChange);
         TeamStore.removeChangeListener(this.onChange);
         SocketStore.removeChangeListener(this.onSocketChange);
+        PreferenceStore.removeChangeListener(this.onChange);
     }
     onChange() {
         var newState = this.getStateFromStores();
@@ -464,7 +556,7 @@ export default class Sidebar extends React.Component {
         const privateChannels = this.state.channels.filter((channel) => channel.type === 'P');
         const privateChannelItems = privateChannels.map(this.createChannelElement);
 
-        const directMessageItems = this.state.showDirectChannels.map(this.createChannelElement);
+        const directMessageItems = this.state.visibleDirectChannels.map(this.createChannelElement);
 
         // update the favicon to show if there are any notifications
         var link = document.createElement('link');
@@ -484,7 +576,7 @@ export default class Sidebar extends React.Component {
         head.appendChild(link);
 
         var directMessageMore = null;
-        if (this.state.hideDirectChannels.length > 0) {
+        if (this.state.hiddenDirectChannels.length > 0) {
             directMessageMore = (
                 <li>
                     <a
@@ -492,9 +584,9 @@ export default class Sidebar extends React.Component {
                         data-toggle='modal'
                         className='nav-more'
                         data-target='#more_direct_channels'
-                        data-channels={JSON.stringify(this.state.hideDirectChannels)}
+                        data-channels={JSON.stringify(this.state.hiddenDirectChannels)}
                     >
-                        {'More (' + this.state.hideDirectChannels.length + ')'}
+                        {'More (' + this.state.hiddenDirectChannels.length + ')'}
                     </a>
                 </li>
             );
-- 
cgit v1.2.3-1-g7c22


From ed31538893ad2790de46ace7eeac5c1aa015a7f1 Mon Sep 17 00:00:00 2001
From: hmhealey <harrisonmhealey@gmail.com>
Date: Fri, 2 Oct 2015 14:25:55 -0400
Subject: Changed direct messages channels so users can show/hide them

---
 web/react/components/sidebar.jsx | 229 ++++++++++++++-------------------------
 1 file changed, 79 insertions(+), 150 deletions(-)

(limited to 'web/react/components/sidebar.jsx')

diff --git a/web/react/components/sidebar.jsx b/web/react/components/sidebar.jsx
index 115e9c9c6..449a3eaea 100644
--- a/web/react/components/sidebar.jsx
+++ b/web/react/components/sidebar.jsx
@@ -25,12 +25,12 @@ export default class Sidebar extends React.Component {
         this.lastUnreadChannel = null;
 
         this.getStateFromStores = this.getStateFromStores.bind(this);
-        //this.getDirectChannelsFromStores = this.getDirectChannelsFromStores.bind(this);
 
         this.onChange = this.onChange.bind(this);
         this.onScroll = this.onScroll.bind(this);
         this.onResize = this.onResize.bind(this);
         this.updateUnreadIndicators = this.updateUnreadIndicators.bind(this);
+        this.handleLeaveDirectChannel = this.handleLeaveDirectChannel.bind(this);
         this.createChannelElement = this.createChannelElement.bind(this);
 
         const state = this.getStateFromStores();
@@ -73,44 +73,19 @@ export default class Sidebar extends React.Component {
 
             let channel = ChannelStore.getByName(channelName);
 
-            if (channel == null) {
-                var tempChannel = {};
-                tempChannel.fake = true;
-                tempChannel.name = channelName;
-                tempChannel.display_name = teammate.username;
-                tempChannel.teammate_username = teammate.username;
-                tempChannel.status = UserStore.getStatus(teammate.id);
-                tempChannel.last_post_at = 0;
-                tempChannel.total_msg_count = 0;
-                tempChannel.type = 'D';
-                readDirectChannels.push(tempChannel);
-            } else {
-                channel.display_name = teammate.username;
-                channel.teammate_username = teammate.username;
-
-                channel.status = UserStore.getStatus(teammate.id);
-
-                /*var channelMember = members[channel.id];
-                var msgCount = channel.total_msg_count - channelMember.msg_count;
-                if (msgCount > 0) {
-                    visibleDirectChannels.push(channel);
-                } else if (currentId === channel.id) {
-                    visibleDirectChannels.push(channel);
-                } else {
-                    hiddenDirectChannels.push(channel);
-                }*/
-            } else {
+            if (!channel) {
                 channel = {};
                 channel.fake = true;
                 channel.name = channelName;
-                channel.display_name = teammate.username;
-                channel.teammate_username = teammate.username;
-                channel.status = UserStore.getStatus(teammate.id);
                 channel.last_post_at = 0;
                 channel.total_msg_count = 0;
                 channel.type = 'D';
             }
 
+            channel.display_name = teammate.username;
+            channel.teammate_id = teammate.id;
+            channel.status = UserStore.getStatus(teammate.id);
+
             if (preferences.some((preference) => (preference.alt_id === teammate.id && preference.value !== 'false'))) {
                 visibleDirectChannels.push(channel);
             } else {
@@ -118,51 +93,8 @@ export default class Sidebar extends React.Component {
             }
         }
 
-        function sortByDisplayName(a, b) {
-            return a.display_name.localeCompare(b.display_name);
-        }
-
-        visibleDirectChannels.sort(sortByDisplayName);
-        hiddenDirectChannels.sort(sortByDisplayName);
-
-        /*// If we don't have MAX_DMS unread channels, sort the read list by last_post_at
-        if (visibleDirectChannels.length < Constants.MAX_DMS) {
-            hiddenDirectChannels.sort(function sortByLastPost(a, b) {
-                // sort by last_post_at first
-                if (a.last_post_at > b.last_post_at) {
-                    return -1;
-                }
-                if (a.last_post_at < b.last_post_at) {
-                    return 1;
-                }
-
-                // if last_post_at is equal, sort by name
-                if (a.display_name < b.display_name) {
-                    return -1;
-                }
-                if (a.display_name > b.display_name) {
-                    return 1;
-                }
-                return 0;
-            });
-
-            var index = 0;
-            while (visibleDirectChannels.length < Constants.MAX_DMS && index < hiddenDirectChannels.length) {
-                visibleDirectChannels.push(hiddenDirectChannels[index]);
-                index++;
-            }
-            hiddenDirectChannels = hiddenDirectChannels.slice(index);
-
-            visibleDirectChannels.sort(function directSort(a, b) {
-                if (a.display_name < b.display_name) {
-                    return -1;
-                }
-                if (a.display_name > b.display_name) {
-                    return 1;
-                }
-                return 0;
-            });
-        }*/
+        visibleDirectChannels.sort(this.sortChannelsByDisplayName);
+        hiddenDirectChannels.sort(this.sortChannelsByDisplayName);
 
         return {
             activeId: currentId,
@@ -173,63 +105,6 @@ export default class Sidebar extends React.Component {
         };
     }
 
-    /*getDirectChannelsFromStores() {
-        const id = UserStore.getCurrentId();
-
-        const channels = [];
-        const preferences = PreferenceStore.getPreferences('direct_channels', 'show_hide');
-        for (const preference of preferences) {
-            if (preference.value !== 'true') {
-                continue;
-            }
-
-            const otherId = preference.alt_id;
-
-            if (otherId === id) {
-                continue;
-            }
-
-            const teammate = UserStore.getProfile(otherId);
-
-            if (!teammate) {
-                continue;
-            }
-
-            let channelName = '';
-            if (otherId > id) {
-                channelName = `${id}__${otherId}`;
-            } else {
-                channelName = `${otherId}__${id}`;
-            }
-
-            const channel = ChannelStore.getByName(channelName);
-
-            if (channel != null) {
-                channel.display_name = teammate.username;
-                channel.teammate_username = teammate.username;
-
-                channel.status = UserStore.getStatus(otherId);
-
-                channels.push(channel);
-            } else {
-                const tempChannel = {};
-                tempChannel.fake = true;
-                tempChannel.name = channelName;
-                tempChannel.display_name = teammate.username;
-                tempChannel.teammate_username = teammate.username;
-                tempChannel.status = UserStore.getStatus(teammate.id);
-                tempChannel.last_post_at = 0;
-                tempChannel.total_msg_count = 0;
-                tempChannel.type = 'D';
-                channels.push(tempChannel);
-            }
-        }
-
-        channels.sort((a, b) => a.display_name.localeCompare(b));
-
-        return channels;
-    }*/
-
     componentDidMount() {
         ChannelStore.addChangeListener(this.onChange);
         UserStore.addChangeListener(this.onChange);
@@ -414,7 +289,35 @@ export default class Sidebar extends React.Component {
             showBottomUnread
         });
     }
-    createChannelElement(channel, index) {
+
+    handleLeaveDirectChannel(channel) {
+        if (!channel.leaving) {
+            channel.leaving = true;
+
+            const preference = PreferenceStore.setPreferenceWithAltId('direct_channels', 'show_hide', channel.teammate_id, 'false');
+            AsyncClient.setPreferences(
+                [preference],
+                () => {
+                    channel.leaving = false;
+                },
+                () => {
+                    channel.leaving = false;
+                }
+            );
+
+            this.setState(this.getStateFromStores());
+        }
+
+        if (channel.id === this.state.activeId) {
+            Utils.switchChannel(ChannelStore.getByName(Constants.DEFAULT_CHANNEL));
+        }
+    }
+
+    sortChannelsByDisplayName(a, b) {
+        return a.display_name.localeCompare(b.display_name);
+    }
+
+    createChannelElement(channel, index, arr, handleClose) {
         var members = this.state.members;
         var activeId = this.state.activeId;
         var channelMember = members[channel.id];
@@ -497,8 +400,13 @@ export default class Sidebar extends React.Component {
 
         if (!channel.fake) {
             handleClick = function clickHandler(e) {
+                if (!e.target.attributes.getNamedItem('data-close')) {
+                    Utils.switchChannel(channel);
+                } else {
+                    handleClose(channel);
+                }
+
                 e.preventDefault();
-                Utils.switchChannel(channel);
             };
         } else if (channel.fake && teamURL) {
             // It's a direct message channel that doesn't exist yet so let's create it now
@@ -507,23 +415,40 @@ export default class Sidebar extends React.Component {
             if (this.state.loadingDMChannel === -1) {
                 handleClick = function clickHandler(e) {
                     e.preventDefault();
-                    this.setState({loadingDMChannel: index});
-
-                    Client.createDirectChannel(channel, otherUserId,
-                        function success(data) {
-                            this.setState({loadingDMChannel: -1});
-                            AsyncClient.getChannel(data.id);
-                            Utils.switchChannel(data);
-                        }.bind(this),
-                        function error() {
-                            this.setState({loadingDMChannel: -1});
-                            window.location.href = TeamStore.getCurrentTeamUrl() + '/channels/' + channel.name;
-                        }.bind(this)
-                    );
+
+                    if (!e.target.attributes.getNamedItem('data-close')) {
+                        this.setState({loadingDMChannel: index});
+
+                        Client.createDirectChannel(channel, otherUserId,
+                            function success(data) {
+                                this.setState({loadingDMChannel: -1});
+                                AsyncClient.getChannel(data.id);
+                                Utils.switchChannel(data);
+                            }.bind(this),
+                            function error() {
+                                this.setState({loadingDMChannel: -1});
+                                window.location.href = TeamStore.getCurrentTeamUrl() + '/channels/' + channel.name;
+                            }.bind(this)
+                        );
+                    } else {
+                        handleClose(channel);
+                    }
                 }.bind(this);
             }
         }
 
+        let closeButton = null;
+        if (handleClose) {
+            closeButton = (
+                <span
+                    className='sidebar-channel__close'
+                    data-close='true'
+                >
+                    {'×'}
+                </span>
+            );
+        }
+
         return (
             <li
                 key={channel.name}
@@ -538,6 +463,7 @@ export default class Sidebar extends React.Component {
                     {status}
                     {channel.display_name}
                     {badge}
+                    {closeButton}
                 </a>
             </li>
         );
@@ -556,7 +482,9 @@ export default class Sidebar extends React.Component {
         const privateChannels = this.state.channels.filter((channel) => channel.type === 'P');
         const privateChannelItems = privateChannels.map(this.createChannelElement);
 
-        const directMessageItems = this.state.visibleDirectChannels.map(this.createChannelElement);
+        const directMessageItems = this.state.visibleDirectChannels.map((channel, index, arr) => {
+            return this.createChannelElement(channel, index, arr, this.handleLeaveDirectChannel);
+        });
 
         // update the favicon to show if there are any notifications
         var link = document.createElement('link');
@@ -578,8 +506,9 @@ export default class Sidebar extends React.Component {
         var directMessageMore = null;
         if (this.state.hiddenDirectChannels.length > 0) {
             directMessageMore = (
-                <li>
+                <li key='more'>
                     <a
+                        key={`more${this.state.hiddenDirectChannels.length}`}
                         href='#'
                         data-toggle='modal'
                         className='nav-more'
-- 
cgit v1.2.3-1-g7c22


From 415f959614f6a3fd7fcb6551e32b722df2b015c5 Mon Sep 17 00:00:00 2001
From: hmhealey <harrisonmhealey@gmail.com>
Date: Mon, 5 Oct 2015 11:47:34 -0400
Subject: Made direct channels visible when receiving a message on one

---
 web/react/components/sidebar.jsx | 12 ++++++++++++
 1 file changed, 12 insertions(+)

(limited to 'web/react/components/sidebar.jsx')

diff --git a/web/react/components/sidebar.jsx b/web/react/components/sidebar.jsx
index 449a3eaea..de353deb4 100644
--- a/web/react/components/sidebar.jsx
+++ b/web/react/components/sidebar.jsx
@@ -71,6 +71,7 @@ export default class Sidebar extends React.Component {
                 channelName = teammate.id + '__' + UserStore.getCurrentId();
             }
 
+            let forceShow = false;
             let channel = ChannelStore.getByName(channelName);
 
             if (!channel) {
@@ -80,6 +81,11 @@ export default class Sidebar extends React.Component {
                 channel.last_post_at = 0;
                 channel.total_msg_count = 0;
                 channel.type = 'D';
+            } else {
+                const member = members[channel.id];
+                const msgCount = channel.total_msg_count - member.msg_count;
+
+                forceShow = currentId === channel.id || msgCount > 0;
             }
 
             channel.display_name = teammate.username;
@@ -87,6 +93,12 @@ export default class Sidebar extends React.Component {
             channel.status = UserStore.getStatus(teammate.id);
 
             if (preferences.some((preference) => (preference.alt_id === teammate.id && preference.value !== 'false'))) {
+                visibleDirectChannels.push(channel);
+            } else if (forceShow) {
+                // make sure that unread direct channels are visible
+                const preference = PreferenceStore.setPreferenceWithAltId('direct_channels', 'show_hide', teammate.id, 'true');
+                AsyncClient.setPreferences([preference]);
+
                 visibleDirectChannels.push(channel);
             } else {
                 hiddenDirectChannels.push(channel);
-- 
cgit v1.2.3-1-g7c22


From 599644fb2fa75d1760420806c8c821959fc6b645 Mon Sep 17 00:00:00 2001
From: hmhealey <harrisonmhealey@gmail.com>
Date: Mon, 5 Oct 2015 12:03:27 -0400
Subject: Renamed show_hide preference to show

---
 web/react/components/sidebar.jsx | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

(limited to 'web/react/components/sidebar.jsx')

diff --git a/web/react/components/sidebar.jsx b/web/react/components/sidebar.jsx
index de353deb4..97f705f32 100644
--- a/web/react/components/sidebar.jsx
+++ b/web/react/components/sidebar.jsx
@@ -52,7 +52,7 @@ export default class Sidebar extends React.Component {
             teammates.push(teamMemberMap[id]);
         }
 
-        const preferences = PreferenceStore.getPreferences('direct_channels', 'show_hide');
+        const preferences = PreferenceStore.getPreferences(Constants.Preferences.CATEGORY_DIRECT_CHANNELS, Constants.Preferences.NAME_SHOW);
 
         // Create lists of all read and unread direct channels
         var visibleDirectChannels = [];
@@ -96,7 +96,8 @@ export default class Sidebar extends React.Component {
                 visibleDirectChannels.push(channel);
             } else if (forceShow) {
                 // make sure that unread direct channels are visible
-                const preference = PreferenceStore.setPreferenceWithAltId('direct_channels', 'show_hide', teammate.id, 'true');
+                const preference = PreferenceStore.setPreferenceWithAltId(Constants.Preferences.CATEGORY_DIRECT_CHANNELS,
+                    Constants.Preferences.NAME_SHOW, teammate.id, 'true');
                 AsyncClient.setPreferences([preference]);
 
                 visibleDirectChannels.push(channel);
@@ -306,7 +307,8 @@ export default class Sidebar extends React.Component {
         if (!channel.leaving) {
             channel.leaving = true;
 
-            const preference = PreferenceStore.setPreferenceWithAltId('direct_channels', 'show_hide', channel.teammate_id, 'false');
+            const preference = PreferenceStore.setPreferenceWithAltId(Constants.Preferences.CATEGORY_DIRECT_CHANNELS,
+                Constants.Preferences.NAME_SHOW, channel.teammate_id, 'false');
             AsyncClient.setPreferences(
                 [preference],
                 () => {
-- 
cgit v1.2.3-1-g7c22


From ae0eb91180130e27767d797bc47376b88f62f88b Mon Sep 17 00:00:00 2001
From: hmhealey <harrisonmhealey@gmail.com>
Date: Mon, 5 Oct 2015 13:16:39 -0400
Subject: Hid the close button when the unread badge is visible and moved it to
 the right side of the sidebar

---
 web/react/components/sidebar.jsx | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'web/react/components/sidebar.jsx')

diff --git a/web/react/components/sidebar.jsx b/web/react/components/sidebar.jsx
index 97f705f32..2619798eb 100644
--- a/web/react/components/sidebar.jsx
+++ b/web/react/components/sidebar.jsx
@@ -452,10 +452,10 @@ export default class Sidebar extends React.Component {
         }
 
         let closeButton = null;
-        if (handleClose) {
+        if (handleClose && !badge) {
             closeButton = (
                 <span
-                    className='sidebar-channel__close'
+                    className='sidebar-channel__close pull-right'
                     data-close='true'
                 >
                     {'×'}
-- 
cgit v1.2.3-1-g7c22


From 097d236f437b0c5af167cd383c6ee4c3ee45f495 Mon Sep 17 00:00:00 2001
From: hmhealey <harrisonmhealey@gmail.com>
Date: Wed, 7 Oct 2015 11:34:29 -0400
Subject: Fixed edge cases with leaving a direct channel while viewing that
 channel

---
 web/react/components/sidebar.jsx | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

(limited to 'web/react/components/sidebar.jsx')

diff --git a/web/react/components/sidebar.jsx b/web/react/components/sidebar.jsx
index 2619798eb..54edb3c31 100644
--- a/web/react/components/sidebar.jsx
+++ b/web/react/components/sidebar.jsx
@@ -33,6 +33,8 @@ export default class Sidebar extends React.Component {
         this.handleLeaveDirectChannel = this.handleLeaveDirectChannel.bind(this);
         this.createChannelElement = this.createChannelElement.bind(this);
 
+        this.isLeaving = new Map();
+
         const state = this.getStateFromStores();
         state.modal = '';
         state.loadingDMChannel = -1;
@@ -85,7 +87,8 @@ export default class Sidebar extends React.Component {
                 const member = members[channel.id];
                 const msgCount = channel.total_msg_count - member.msg_count;
 
-                forceShow = currentId === channel.id || msgCount > 0;
+                // always show a channel if either it is the current one or if it is unread, but it is not currently being left
+                forceShow = (currentId === channel.id || msgCount > 0) && !this.isLeaving.get(channel.id);
             }
 
             channel.display_name = teammate.username;
@@ -93,8 +96,10 @@ export default class Sidebar extends React.Component {
             channel.status = UserStore.getStatus(teammate.id);
 
             if (preferences.some((preference) => (preference.alt_id === teammate.id && preference.value !== 'false'))) {
+                console.log(teammate.id + " is visible");
                 visibleDirectChannels.push(channel);
             } else if (forceShow) {
+                console.log(teammate.id + " needs to be visible");
                 // make sure that unread direct channels are visible
                 const preference = PreferenceStore.setPreferenceWithAltId(Constants.Preferences.CATEGORY_DIRECT_CHANNELS,
                     Constants.Preferences.NAME_SHOW, teammate.id, 'true');
@@ -304,18 +309,18 @@ export default class Sidebar extends React.Component {
     }
 
     handleLeaveDirectChannel(channel) {
-        if (!channel.leaving) {
-            channel.leaving = true;
+        if (!this.isLeaving.get(channel.id)) {
+            this.isLeaving.set(channel.id, true);
 
             const preference = PreferenceStore.setPreferenceWithAltId(Constants.Preferences.CATEGORY_DIRECT_CHANNELS,
                 Constants.Preferences.NAME_SHOW, channel.teammate_id, 'false');
             AsyncClient.setPreferences(
                 [preference],
                 () => {
-                    channel.leaving = false;
+                    this.isLeaving.set(channel.id, false);
                 },
                 () => {
-                    channel.leaving = false;
+                    this.isLeaving.set(channel.id, false);
                 }
             );
 
-- 
cgit v1.2.3-1-g7c22


From a2517ee991df84803ca508b556910e543c535c1d Mon Sep 17 00:00:00 2001
From: hmhealey <harrisonmhealey@gmail.com>
Date: Wed, 7 Oct 2015 13:07:59 -0400
Subject: Cleaned up JSX errors

---
 web/react/components/sidebar.jsx | 50 +++++++++++++++++++---------------------
 1 file changed, 24 insertions(+), 26 deletions(-)

(limited to 'web/react/components/sidebar.jsx')

diff --git a/web/react/components/sidebar.jsx b/web/react/components/sidebar.jsx
index 54edb3c31..431f2ce1b 100644
--- a/web/react/components/sidebar.jsx
+++ b/web/react/components/sidebar.jsx
@@ -76,19 +76,19 @@ export default class Sidebar extends React.Component {
             let forceShow = false;
             let channel = ChannelStore.getByName(channelName);
 
-            if (!channel) {
+            if (channel) {
+                const member = members[channel.id];
+                const msgCount = channel.total_msg_count - member.msg_count;
+
+                // always show a channel if either it is the current one or if it is unread, but it is not currently being left
+                forceShow = (currentId === channel.id || msgCount > 0) && !this.isLeaving.get(channel.id);
+            } else {
                 channel = {};
                 channel.fake = true;
                 channel.name = channelName;
                 channel.last_post_at = 0;
                 channel.total_msg_count = 0;
                 channel.type = 'D';
-            } else {
-                const member = members[channel.id];
-                const msgCount = channel.total_msg_count - member.msg_count;
-
-                // always show a channel if either it is the current one or if it is unread, but it is not currently being left
-                forceShow = (currentId === channel.id || msgCount > 0) && !this.isLeaving.get(channel.id);
             }
 
             channel.display_name = teammate.username;
@@ -96,10 +96,8 @@ export default class Sidebar extends React.Component {
             channel.status = UserStore.getStatus(teammate.id);
 
             if (preferences.some((preference) => (preference.alt_id === teammate.id && preference.value !== 'false'))) {
-                console.log(teammate.id + " is visible");
                 visibleDirectChannels.push(channel);
             } else if (forceShow) {
-                console.log(teammate.id + " needs to be visible");
                 // make sure that unread direct channels are visible
                 const preference = PreferenceStore.setPreferenceWithAltId(Constants.Preferences.CATEGORY_DIRECT_CHANNELS,
                     Constants.Preferences.NAME_SHOW, teammate.id, 'true');
@@ -117,9 +115,9 @@ export default class Sidebar extends React.Component {
         return {
             activeId: currentId,
             channels: ChannelStore.getAll(),
-            members: members,
-            visibleDirectChannels: visibleDirectChannels,
-            hiddenDirectChannels: hiddenDirectChannels
+            members,
+            visibleDirectChannels,
+            hiddenDirectChannels
         };
     }
 
@@ -419,10 +417,10 @@ export default class Sidebar extends React.Component {
 
         if (!channel.fake) {
             handleClick = function clickHandler(e) {
-                if (!e.target.attributes.getNamedItem('data-close')) {
-                    Utils.switchChannel(channel);
-                } else {
+                if (e.target.attributes.getNamedItem('data-close')) {
                     handleClose(channel);
+                } else {
+                    Utils.switchChannel(channel);
                 }
 
                 e.preventDefault();
@@ -435,22 +433,22 @@ export default class Sidebar extends React.Component {
                 handleClick = function clickHandler(e) {
                     e.preventDefault();
 
-                    if (!e.target.attributes.getNamedItem('data-close')) {
+                    if (e.target.attributes.getNamedItem('data-close')) {
+                        handleClose(channel);
+                    } else {
                         this.setState({loadingDMChannel: index});
 
                         Client.createDirectChannel(channel, otherUserId,
-                            function success(data) {
+                            (data) => {
                                 this.setState({loadingDMChannel: -1});
                                 AsyncClient.getChannel(data.id);
                                 Utils.switchChannel(data);
-                            }.bind(this),
-                            function error() {
+                            },
+                            () => {
                                 this.setState({loadingDMChannel: -1});
                                 window.location.href = TeamStore.getCurrentTeamUrl() + '/channels/' + channel.name;
-                            }.bind(this)
+                            }
                         );
-                    } else {
-                        handleClose(channel);
                     }
                 }.bind(this);
             }
@@ -578,7 +576,7 @@ export default class Sidebar extends React.Component {
                     <ul className='nav nav-pills nav-stacked'>
                         <li>
                             <h4>
-                                Channels
+                                {'Channels'}
                                 <a
                                     className='add-channel-btn'
                                     href='#'
@@ -597,7 +595,7 @@ export default class Sidebar extends React.Component {
                                 data-target='#more_channels'
                                 data-channeltype='O'
                             >
-                                More...
+                                {'More...'}
                             </a>
                         </li>
                     </ul>
@@ -605,7 +603,7 @@ export default class Sidebar extends React.Component {
                     <ul className='nav nav-pills nav-stacked'>
                         <li>
                             <h4>
-                                Private Groups
+                                {'Private Groups'}
                                 <a
                                     className='add-channel-btn'
                                     href='#'
@@ -618,7 +616,7 @@ export default class Sidebar extends React.Component {
                         {privateChannelItems}
                     </ul>
                     <ul className='nav nav-pills nav-stacked'>
-                        <li><h4>Direct Messages</h4></li>
+                        <li><h4>{'Direct Messages'}</h4></li>
                         {directMessageItems}
                         {directMessageMore}
                     </ul>
-- 
cgit v1.2.3-1-g7c22


From 2a39e8dbfab8506b09d0d030f87cac4c079b975a Mon Sep 17 00:00:00 2001
From: hmhealey <harrisonmhealey@gmail.com>
Date: Tue, 13 Oct 2015 11:52:17 -0400
Subject: Removed Preference.AltId

---
 web/react/components/sidebar.jsx | 16 +++++++---------
 1 file changed, 7 insertions(+), 9 deletions(-)

(limited to 'web/react/components/sidebar.jsx')

diff --git a/web/react/components/sidebar.jsx b/web/react/components/sidebar.jsx
index 431f2ce1b..82fc828eb 100644
--- a/web/react/components/sidebar.jsx
+++ b/web/react/components/sidebar.jsx
@@ -54,7 +54,7 @@ export default class Sidebar extends React.Component {
             teammates.push(teamMemberMap[id]);
         }
 
-        const preferences = PreferenceStore.getPreferences(Constants.Preferences.CATEGORY_DIRECT_CHANNELS, Constants.Preferences.NAME_SHOW);
+        const preferences = PreferenceStore.getPreferences(Constants.Preferences.CATEGORY_DIRECT_CHANNEL_SHOW);
 
         // Create lists of all read and unread direct channels
         var visibleDirectChannels = [];
@@ -95,13 +95,12 @@ export default class Sidebar extends React.Component {
             channel.teammate_id = teammate.id;
             channel.status = UserStore.getStatus(teammate.id);
 
-            if (preferences.some((preference) => (preference.alt_id === teammate.id && preference.value !== 'false'))) {
+            if (preferences.some((preference) => (preference.name === teammate.id && preference.value !== 'false'))) {
                 visibleDirectChannels.push(channel);
             } else if (forceShow) {
                 // make sure that unread direct channels are visible
-                const preference = PreferenceStore.setPreferenceWithAltId(Constants.Preferences.CATEGORY_DIRECT_CHANNELS,
-                    Constants.Preferences.NAME_SHOW, teammate.id, 'true');
-                AsyncClient.setPreferences([preference]);
+                const preference = PreferenceStore.setPreference(Constants.Preferences.CATEGORY_DIRECT_CHANNEL_SHOW, teammate.id, 'true');
+                AsyncClient.savePreferences([preference]);
 
                 visibleDirectChannels.push(channel);
             } else {
@@ -129,7 +128,7 @@ export default class Sidebar extends React.Component {
         SocketStore.addChangeListener(this.onSocketChange);
         PreferenceStore.addChangeListener(this.onChange);
 
-        AsyncClient.getDirectChannels();
+        AsyncClient.getDirectChannelPreferences();
 
         $('.nav-pills__container').perfectScrollbar();
 
@@ -310,9 +309,8 @@ export default class Sidebar extends React.Component {
         if (!this.isLeaving.get(channel.id)) {
             this.isLeaving.set(channel.id, true);
 
-            const preference = PreferenceStore.setPreferenceWithAltId(Constants.Preferences.CATEGORY_DIRECT_CHANNELS,
-                Constants.Preferences.NAME_SHOW, channel.teammate_id, 'false');
-            AsyncClient.setPreferences(
+            const preference = PreferenceStore.setPreference(Constants.Preferences.CATEGORY_DIRECT_CHANNEL_SHOW, channel.teammate_id, 'false');
+            AsyncClient.savePreferences(
                 [preference],
                 () => {
                     this.isLeaving.set(channel.id, false);
-- 
cgit v1.2.3-1-g7c22


From 97b2f6ffe7fa09a2188163740865322582b00b59 Mon Sep 17 00:00:00 2001
From: hmhealey <harrisonmhealey@gmail.com>
Date: Tue, 13 Oct 2015 15:18:01 -0400
Subject: Made further changes based on feedback

---
 web/react/components/sidebar.jsx | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

(limited to 'web/react/components/sidebar.jsx')

diff --git a/web/react/components/sidebar.jsx b/web/react/components/sidebar.jsx
index 82fc828eb..1caf4caa5 100644
--- a/web/react/components/sidebar.jsx
+++ b/web/react/components/sidebar.jsx
@@ -310,7 +310,9 @@ export default class Sidebar extends React.Component {
             this.isLeaving.set(channel.id, true);
 
             const preference = PreferenceStore.setPreference(Constants.Preferences.CATEGORY_DIRECT_CHANNEL_SHOW, channel.teammate_id, 'false');
-            AsyncClient.savePreferences(
+
+            // bypass AsyncClient since we've already saved the updated preferences
+            Client.savePreferences(
                 [preference],
                 () => {
                     this.isLeaving.set(channel.id, false);
-- 
cgit v1.2.3-1-g7c22

