Skip to content
This repository has been archived by the owner on Mar 13, 2024. It is now read-only.

Commit

Permalink
Merging of CSS styles into new sidebar code (#4998)
Browse files Browse the repository at this point in the history
* [MM-22291] Additional functionality from old sidebar

* PR feedback

* PR feedback

* Lank bline

* Lint again

* PR feedback

* Merge'd

* Actual functioning sidebar!

* Using react-custom-scrollbars again and fixed a few styling issues

* PR feedback

* Lint fixes

Co-authored-by: mattermod <[email protected]>
  • Loading branch information
devinbinnie and mattermod committed Mar 9, 2020
1 parent 3938a23 commit 0b7c625
Show file tree
Hide file tree
Showing 19 changed files with 1,052 additions and 84 deletions.
9 changes: 7 additions & 2 deletions components/sidebar/channel_filter/channel_filter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,13 @@ type State = {
export default class ChannelFilter extends React.PureComponent<Props, State> {
render() {
return (
<div>
{'Channel Filter'}
<div className='SidebarFilters'>
<a
href='#'
className='SidebarFilters_filterButton'
>
<i className='icon icon-filter-variant'/>
</a>
</div>
);
}
Expand Down
2 changes: 1 addition & 1 deletion components/sidebar/sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ export default class Sidebar extends React.PureComponent<Props, State> {

render() {
return (
<div className='sidebar--left'>
<div id='SidebarContainer'>
<SidebarHeader/>
<ChannelNavigator/>
<ChannelFilter/>
Expand Down
61 changes: 36 additions & 25 deletions components/sidebar/sidebar_category/sidebar_category.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import {isKeyPressed} from 'utils/utils';

type Props = {
category: any;
setChannelRef: (channelId: string, ref: HTMLDivElement) => void;
setChannelRef: (channelId: string, ref: HTMLLIElement) => void;
handleOpenMoreDirectChannelsModal: (e: Event) => void;
getChannelRef: (channelId: string) => HTMLDivElement | undefined;
getChannelRef: (channelId: string) => HTMLLIElement | undefined;
actions: {
setCollapsedState: (categoryId: string, isCollapsed: boolean) => void;
};
Expand All @@ -22,7 +22,7 @@ type State = {
};

export default class SidebarCategory extends React.PureComponent<Props, State> {
categoryTitleRef: React.RefObject<HTMLDivElement>;
categoryTitleRef: React.RefObject<HTMLButtonElement>;

constructor(props: Props) {
super(props);
Expand Down Expand Up @@ -86,42 +86,53 @@ export default class SidebarCategory extends React.PureComponent<Props, State> {
this.setState({isCollapsed: !isCollapsed}); // TODO: Won't be necessary after it's in redux
}

handleOpenDirectMessagesModal = (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
e.stopPropagation();
this.props.handleOpenMoreDirectChannelsModal(e.nativeEvent);
}

render() {
const {category} = this.props;
const {isCollapsed} = this.state;

const channels = category.channel_ids.map(this.renderChannel);

// TODO: temporary button, need better way of opening modal
let directMessagesModalButton;
if (category.id === 'direct') {
directMessagesModalButton = (
<div style={{fontWeight: 'bold'}}>
<a
href='#'
onClick={(e: React.MouseEvent<HTMLAnchorElement, MouseEvent>) => this.props.handleOpenMoreDirectChannelsModal(e.nativeEvent)}
>
{'+'}
</a>
</div>
<button
className='SidebarChannelGroupHeader_addButton'
onClick={this.handleOpenDirectMessagesModal}
>
<i className='icon-plus'/>
</button>
);
}

return (
<div>
<div
ref={this.categoryTitleRef}
className='a11y__section'
style={{display: 'flex'}}
onClick={this.handleCollapse}
>
{isCollapsed ? '+' : '-'}
<div>
{category.display_name}
</div>
{directMessagesModalButton}
<div className='SidebarChannelGroup'>
<div className='SidebarChannelGroupHeader'>
<button
ref={this.categoryTitleRef}
className='SidebarChannelGroupHeader_groupButton a11y__section'
style={{display: 'flex'}}
onClick={this.handleCollapse}
>
<i className={`icon icon-chevron-down ${isCollapsed ? 'icon-rotate-minus-90' : ''}`}/>
<div>
{category.display_name}
</div>
{directMessagesModalButton}
</button>
</div>
<div className='SidebarChannelGroup_content'>
<ul
role='list'
className='NavGroupContent'
>
{channels}
</ul>
</div>
{channels}
</div>
);
}
Expand Down
70 changes: 46 additions & 24 deletions components/sidebar/sidebar_category_list/sidebar_category_list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,43 @@

import React from 'react';
import {FormattedMessage} from 'react-intl';

import Scrollbars from 'react-custom-scrollbars';
import {Spring, SpringSystem, util as MathUtil} from 'rebound';

import {Channel} from 'mattermost-redux/types/channels';
import {Team} from 'mattermost-redux/types/teams';

import {redirectUserToDefaultTeam} from 'actions/global_actions';

import UnreadChannelIndicator from 'components/unread_channel_indicator';
import {Constants} from 'utils/constants';
import * as Utils from 'utils/utils';
import * as ChannelUtils from 'utils/channel_utils.jsx';

import SidebarCategory from '../sidebar_category';
import UnreadChannelIndicator from 'components/unread_channel_indicator';

export function renderView(props: any) {
return (
<div
{...props}
className='scrollbar--view'
/>);
}

export function renderThumbHorizontal(props: any) {
return (
<div
{...props}
className='scrollbar--horizontal'
/>);
}

export function renderThumbVertical(props: any) {
return (
<div
{...props}
className='scrollbar--vertical'
/>);
}

type Props = {
currentTeam: Team;
Expand All @@ -43,8 +66,8 @@ const scrollMargin = 15;
const scrollMarginWithUnread = 60;

export default class SidebarCategoryList extends React.PureComponent<Props, State> {
channelRefs: Map<string, HTMLDivElement>;
scrollbar: React.RefObject<HTMLDivElement>;
channelRefs: Map<string, HTMLLIElement>;
scrollbar: React.RefObject<Scrollbars>;
animate: SpringSystem;
scrollAnimation: Spring;
closedDirectChannel: boolean;
Expand Down Expand Up @@ -94,7 +117,7 @@ export default class SidebarCategoryList extends React.PureComponent<Props, Stat

// reset the scrollbar upon switching teams
if (this.props.currentTeam !== prevProps.currentTeam) {
this.scrollbar.current!.scrollTop = 0;
this.scrollbar.current!.scrollToTop();
}

// Scroll to selected channel so it's in view
Expand Down Expand Up @@ -129,7 +152,7 @@ export default class SidebarCategoryList extends React.PureComponent<Props, Stat
return this.channelRefs.get(channelId);
}

setChannelRef = (channelId: string, ref: HTMLDivElement) => {
setChannelRef = (channelId: string, ref: HTMLLIElement) => {
if (ref) {
this.channelRefs.set(channelId, ref);
} else {
Expand All @@ -149,7 +172,7 @@ export default class SidebarCategoryList extends React.PureComponent<Props, Stat

handleScrollAnimationUpdate = (spring: Spring) => {
const val = spring.getCurrentValue();
this.scrollbar.current!.scrollTop = val;
this.scrollbar.current!.scrollTop(val);
}

scrollToFirstUnreadChannel = () => {
Expand All @@ -173,8 +196,8 @@ export default class SidebarCategoryList extends React.PureComponent<Props, Stat
const top = element.offsetTop;
const bottom = top + element.offsetHeight;

const scrollTop = this.scrollbar.current!.scrollTop;
const scrollHeight = this.scrollbar.current!.clientHeight;
const scrollTop = this.scrollbar.current!.getScrollTop();
const scrollHeight = this.scrollbar.current!.getClientHeight();

if (top < scrollTop) {
// Scroll up to the item
Expand All @@ -201,7 +224,7 @@ export default class SidebarCategoryList extends React.PureComponent<Props, Stat

scrollToPosition = (scrollEnd: number) => {
// Stop the current animation before scrolling
this.scrollAnimation.setCurrentValue(this.scrollbar.current!.scrollTop).setAtRest();
this.scrollAnimation.setCurrentValue(this.scrollbar.current!.getScrollTop()).setAtRest();

this.scrollAnimation.setEndValue(scrollEnd);
}
Expand All @@ -218,7 +241,7 @@ export default class SidebarCategoryList extends React.PureComponent<Props, Stat
const firstUnreadElement = this.channelRefs.get(firstUnreadChannel);
const firstUnreadPosition = firstUnreadElement ? firstUnreadElement.offsetTop : null;

if (firstUnreadPosition && ((firstUnreadPosition + firstUnreadElement!.offsetHeight) - scrollMargin) < this.scrollbar.current!.scrollTop) {
if (firstUnreadPosition && ((firstUnreadPosition + firstUnreadElement!.offsetHeight) - scrollMargin) < this.scrollbar.current!.getScrollTop()) {
showTopUnread = true;
}
}
Expand All @@ -227,7 +250,7 @@ export default class SidebarCategoryList extends React.PureComponent<Props, Stat
const lastUnreadElement = this.channelRefs.get(lastUnreadChannel);
const lastUnreadPosition = lastUnreadElement ? lastUnreadElement.offsetTop : null;

if (lastUnreadPosition && (lastUnreadPosition + scrollMargin) > (this.scrollbar.current!.scrollTop + this.scrollbar.current!.clientHeight)) {
if (lastUnreadPosition && (lastUnreadPosition + scrollMargin) > (this.scrollbar.current!.getScrollTop() + this.scrollbar.current!.getClientHeight())) {
showBottomUnread = true;
}
}
Expand Down Expand Up @@ -343,7 +366,7 @@ export default class SidebarCategoryList extends React.PureComponent<Props, Stat

return (
<div
className='sidebar--left__list a11y__region'
className='SidebarNavContainer a11y__region'
data-a11y-sort-order='6'
>
<UnreadChannelIndicator
Expand All @@ -360,20 +383,19 @@ export default class SidebarCategoryList extends React.PureComponent<Props, Stat
extraClass='nav-pills__unread-indicator-bottom'
content={below}
/>
<div
<Scrollbars
ref={this.scrollbar}
style={{
position: 'absolute',
top: '0px',
bottom: '0px',
left: '0px',
right: '0px',
overflowY: 'scroll', // TODO: this should only be on hover
}}
autoHide={true}
autoHideTimeout={500}
autoHideDuration={500}
renderThumbHorizontal={renderThumbHorizontal}
renderThumbVertical={renderThumbVertical}
renderView={renderView}
onScroll={this.onScroll}
style={{position: 'absolute'}}
>
{renderedCategories}
</div>
</Scrollbars>
</div>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,11 @@ export default class SidebarBaseChannel extends React.PureComponent<Props, State

if (channel.type === Constants.OPEN_CHANNEL) {
return (
<GlobeIcon className='icon icon__globe'/>
<i className='icon-globe'/>
);
} else if (channel.type === Constants.PRIVATE_CHANNEL) {
return (
<LockIcon className='icon icon__lock'/>
<i className='icon-lock-outline'/>
);
}

Expand Down
19 changes: 9 additions & 10 deletions components/sidebar/sidebar_channel/sidebar_channel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import {Channel} from 'mattermost-redux/types/channels';

import Constants from 'utils/constants';

import ChannelMentionBadge from './channel_mention_badge';
import SidebarBaseChannel from './sidebar_base_channel';
import SidebarDirectChannel from './sidebar_direct_channel';
import SidebarGroupChannel from './sidebar_group_channel';
Expand Down Expand Up @@ -48,12 +47,12 @@ type Props = {
/**
* Gets the ref for a given channel id
*/
getChannelRef: (channelId: string) => HTMLDivElement | undefined;
getChannelRef: (channelId: string) => HTMLLIElement | undefined;

/**
* Sets the ref for the sidebar channel div element, so that it can be used by parent components
*/
setChannelRef: (channelId: string, ref: HTMLDivElement) => void;
setChannelRef: (channelId: string, ref: HTMLLIElement) => void;

/**
* If category is collapsed
Expand Down Expand Up @@ -99,7 +98,7 @@ export default class SidebarChannel extends React.PureComponent<Props, State> {
return this.props.getChannelRef(this.props.channel.id);
}

setRef = (ref: HTMLDivElement) => {
setRef = (ref: HTMLLIElement) => {
this.props.setChannelRef(this.props.channel.id, ref);
}

Expand All @@ -114,22 +113,22 @@ export default class SidebarChannel extends React.PureComponent<Props, State> {
}

return (
<div
<li
role='listitem'
draggable='false'
ref={this.setRef}
className={classNames('SidebarChannel', {
collapsed: this.isCollapsed(this.props),
unread: this.isUnread(),
active: this.props.isCurrentChannel,
})}
style={{
display: 'flex',
fontWeight: this.isUnread() ? 'bold' : 'inherit', // TODO temp styling
}}
onTransitionEnd={this.removeAnimation}
>
<ChannelComponent
channel={channel}
currentTeamName={currentTeamName}
/>
</div>
</li>
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ export default class SidebarChannelLink extends React.PureComponent<Props, State
channel={channel}
icon={icon}
/>
{label}
<span className='SidebarChannelLinkLabel'>{label}</span>
<ChannelMentionBadge
channelId={channel.id}
unreadMentions={unreadMentions}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {browserHistory} from 'utils/browser_history';
import {Constants} from 'utils/constants';

import ArchiveIcon from 'components/widgets/icons/archive_icon';
import StatusIcon from 'components/status_icon.jsx';
import StatusIconNew from 'components/status_icon_new';
import BotIcon from 'components/widgets/icons/bot_icon.jsx';
import SidebarChannelLink from '../sidebar_channel_link';

Expand Down Expand Up @@ -92,10 +92,19 @@ export default class SidebarDirectChannel extends React.PureComponent<Props, Sta
return icon;
}

let className = '';
if (channel.status === 'online') {
className = 'status-online';
} else if (channel.status === 'away') {
className = 'status-away';
} else if (channel.status === 'dnd') {
className = 'status-dnd';
}

return (
<StatusIcon
type='avatar'
<StatusIconNew
status={channel.status}
className={className}
/>
);
}
Expand Down
Loading

0 comments on commit 0b7c625

Please sign in to comment.