diff --git a/web/sidebar/community-drawer-item-community.react.js b/web/sidebar/community-drawer-item-community.react.js new file mode 100644 index 000000000..b03ae53ed --- /dev/null +++ b/web/sidebar/community-drawer-item-community.react.js @@ -0,0 +1,25 @@ +// @flow + +import classnames from 'classnames'; +import * as React from 'react'; + +import css from './community-drawer-item.css'; +import type { DrawerItemProps } from './community-drawer-item.react.js'; +import CommunityDrawerItem from './community-drawer-item.react.js'; + +function CommunityDrawerItemCommunity(props: DrawerItemProps): React.Node { + const classes = classnames({ + [css.communityBase]: true, + [css.communityExpanded]: props.expanded, + }); + return ( +
+ +
+ ); +} + +const MemoizedCommunityDrawerItemCommunity: React.ComponentType = React.memo( + CommunityDrawerItemCommunity, +); +export default MemoizedCommunityDrawerItemCommunity; diff --git a/web/sidebar/community-drawer-item.css b/web/sidebar/community-drawer-item.css new file mode 100644 index 000000000..ab77b9688 --- /dev/null +++ b/web/sidebar/community-drawer-item.css @@ -0,0 +1,66 @@ +.threadEntry { + display: flex; + flex-direction: row; + margin-top: 8px; + margin-bottom: 8px; +} + +.threadListContainer { + display: flex; + flex-direction: column; +} + +.titleWrapper { + overflow: hidden; +} + +.title { + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + color: var(--drawer-item-color); + line-height: 24px; +} + +.titleLevel0 { + font-size: var(--l-font-18); + font-weight: var(--semi-bold); +} + +.titleLevel1, +.titleLevel2 { + font-size: var(--m-font-16); + font-weight: var(--semi-bold); +} + +.buttonContainer { + width: 24px; + align-items: center; + justify-content: center; + display: flex; +} + +.chatItem { + margin-left: 16px; +} + +.communityBase { + padding: 2px; + padding-right: 24px; + padding-left: 8px; + overflow: hidden; +} + +.communityExpanded { + background-color: var(--drawer-open-community-bg); + border-top-right-radius: 8px; + border-bottom-right-radius: 8px; +} + +.subchannelsButton { + margin-left: 24px; + margin-bottom: 6px; + margin-top: 4px; + display: flex; + align-items: center; +} diff --git a/web/sidebar/community-drawer-item.react.js b/web/sidebar/community-drawer-item.react.js new file mode 100644 index 000000000..4d7bc9252 --- /dev/null +++ b/web/sidebar/community-drawer-item.react.js @@ -0,0 +1,135 @@ +// @flow + +import classnames from 'classnames'; +import * as React from 'react'; + +import type { CommunityDrawerItemData } from 'lib/utils/drawer-utils.react.js'; +import { useResolvedThreadInfo } from 'lib/utils/entity-helpers.js'; + +import css from './community-drawer-item.css'; +import { ExpandButton } from './expand-buttons.react.js'; +import SubchannelsButton from './subchannels-button.react.js'; +import { useSelector } from '../redux/redux-utils.js'; +import { + useOnClickThread, + useThreadIsActive, +} from '../selectors/thread-selectors.js'; + +export type DrawerItemProps = { + +itemData: CommunityDrawerItemData, + +toggleExpanded: (threadID: string) => void, + +expanded: boolean, +}; + +function CommunityDrawerItem(props: DrawerItemProps): React.Node { + const { + itemData: { threadInfo, itemChildren, hasSubchannelsButton, labelStyle }, + expanded, + toggleExpanded, + } = props; + + const children = React.useMemo(() => { + if (!expanded) { + return null; + } + if (hasSubchannelsButton) { + return ( +
+ +
+ ); + } + if (!itemChildren) { + return null; + } + return itemChildren.map(item => ( + + )); + }, [expanded, hasSubchannelsButton, itemChildren, threadInfo]); + + const onExpandToggled = React.useCallback( + () => toggleExpanded(threadInfo.id), + [toggleExpanded, threadInfo.id], + ); + + const itemExpandButton = React.useMemo(() => { + if (itemChildren?.length === 0 && !hasSubchannelsButton) { + return ( +
+ +
+ ); + } + return ( +
+ +
+ ); + }, [itemChildren?.length, hasSubchannelsButton, onExpandToggled, expanded]); + + const active = useThreadIsActive(threadInfo.id); + const isCreateMode = useSelector( + state => state.navInfo.chatMode === 'create', + ); + const onClick = useOnClickThread(threadInfo); + const selectItemIfNotActiveCreation = React.useCallback( + (event: SyntheticEvent) => { + if (!isCreateMode || !active) { + onClick(event); + } + }, + [isCreateMode, active, onClick], + ); + + const { uiName } = useResolvedThreadInfo(threadInfo); + const titleLabel = classnames(css.title, css[labelStyle]); + + return ( + <> +
+ {itemExpandButton} + +
{uiName}
+
+
+
{children}
+ + ); +} + +export type CommunityDrawerItemChatProps = { + +itemData: CommunityDrawerItemData, +}; + +function CommunityDrawerItemChat( + props: CommunityDrawerItemChatProps, +): React.Node { + const [expanded, setExpanded] = React.useState(false); + + const toggleExpanded = React.useCallback(() => { + setExpanded(isExpanded => !isExpanded); + }, []); + + return ( +
+ +
+ ); +} + +const MemoizedCommunityDrawerItemChat: React.ComponentType = React.memo( + CommunityDrawerItemChat, +); + +const MemoizedCommunityDrawerItem: React.ComponentType = React.memo( + CommunityDrawerItem, +); + +export default MemoizedCommunityDrawerItem; diff --git a/web/theme.css b/web/theme.css index db2510b75..26c5b2e24 100644 --- a/web/theme.css +++ b/web/theme.css @@ -1,199 +1,201 @@ :root { /* Never use color values defined here directly in CSS. Add color variables to "Color Theme" below The reason we never use color values defined here directly in CSS is 1. It makes changing themes from light / dark / user generated impossible. 2. Gives the programmer context into the color being used. 3. If our color system changes it's much easier to change color values in one place. Add a color value to the theme below, and then use it in your CSS. naming convention: - bg: background. - fg: foreground. - color: text-color */ --shades-white-100: #ffffff; --shades-white-90: #f5f5f5; --shades-white-80: #ebebeb; --shades-white-70: #e0e0e0; --shades-white-60: #cccccc; --shades-black-100: #0a0a0a; --shades-black-90: #1f1f1f; --shades-black-80: #404040; --shades-black-70: #666666; --shades-black-60: #808080; --violet-dark-100: #7e57c2; --violet-dark-80: #6d49ab; --violet-dark-60: #563894; --violet-dark-40: #44297a; --violet-dark-20: #331f5c; --violet-light-100: #ae94db; --violet-light-80: #b9a4df; --violet-light-60: #d3c6ec; --violet-light-40: #e8e0f5; --violet-light-20: #f3f0fa; --success-light-10: #d5f6e3; --success-light-50: #6cdf9c; --success-primary: #00c853; --success-dark-50: #029841; --success-dark-90: #034920; --error-light-10: #feebe6; --error-light-50: #f9947b; --error-primary: #f53100; --error-dark-50: #b62602; --error-dark-90: #4f1203; --logo-bg: #111827; --spoiler-color: #33332c; --loading-foreground: #1b0e38; --bg: var(--shades-black-100); --fg: var(--shades-white-100); --color-disabled: var(--shades-black-60); --text-input-bg: var(--shades-black-80); --text-input-color: var(--shades-white-60); --text-input-placeholder: var(--shades-white-60); --border: var(--shades-black-80); --error: var(--error-primary); --success: var(--success-dark-50); /* Color Theme */ --btn-bg-filled: var(--violet-dark-100); --btn-bg-outline: var(--shades-black-90); --btn-bg-success: var(--success-dark-50); --btn-bg-danger: var(--error-primary); --btn-bg-disabled: var(--shades-black-80); --btn-disabled-color: var(--shades-black-60); --chat-bg: var(--violet-dark-80); --chat-confirmation-icon: var(--violet-dark-100); --keyserver-selection: var(--violet-dark-60); --thread-selection: var(--violet-light-80); --thread-hover-bg: var(--shades-black-80); --thread-active-bg: var(--shades-black-80); --chat-timestamp-color: var(--shades-black-60); --tool-tip-bg: var(--shades-black-80); --tool-tip-color: var(--shades-white-60); --border-color: var(--shades-black-80); --calendar-chevron: var(--shades-black-60); --calendar-day-bg: var(--shades-black-60); --calendar-day-selected-color: var(--violet-dark-80); --community-bg: var(--shades-black-90); --community-settings-selected: var(--violet-dark-60); --unread-bg: var(--error-primary); --settings-btn-bg: var(--violet-dark-100); --modal-bg: var(--shades-black-90); --modal-fg: var(--shades-white-60); --join-bg: var(--shades-black-90); --help-color: var(--shades-black-60); --breadcrumb-color: var(--shades-white-60); --breadcrumb-color-unread: var(--shades-white-60); --btn-outline-border: var(--shades-black-60); --thread-color-read: var(--shades-black-60); --thread-preview-secondary: var(--shades-black-70); --relationship-button-green: var(--success-dark-50); --relationship-button-red: var(--error-primary); --relationship-button-text: var(--fg); --disconnected-bar-alert-bg: var(--error-dark-50); --disconnected-bar-alert-color: var(--shades-white-100); --disconnected-bar-connecting-bg: var(--shades-white-70); --disconnected-bar-connecting-color: var(--shades-black-100); --permission-color: var(--shades-white-60); --thread-top-bar-color: var(--shades-white-100); --thread-top-bar-menu-color: var(--shades-white-70); --thread-ancestor-keyserver-border: var(--shades-black-70); --thread-ancestor-color-light: var(--shades-white-70); --thread-ancestor-color-dark: var(--shades-black-100); --thread-ancestor-separator-color: var(--shades-white-60); --text-message-default-background: var(--shades-black-80); --message-action-tooltip-bg: var(--shades-black-90); --message-action-tooltip-bg-light: var(--shades-black-80); --menu-bg: var(--shades-black-90); --menu-bg-light: var(--shades-black-80); --menu-separator-color: var(--shades-black-80); --menu-color: var(--shades-black-60); --menu-color-light: var(--shades-white-60); --menu-color-hover: var(--shades-white-100); --menu-color-dangerous: var(--error-primary); --menu-color-dangerous-hover: var(--error-light-50); --app-list-icon-read-only-color: var(--shades-black-60); --app-list-icon-enabled-color: var(--success-primary); --app-list-icon-disabled-color: var(--shades-white-80); --account-settings-label: var(--shades-black-60); --account-button-color: var(--violet-dark-100); --chat-thread-list-color-active: var(--shades-white-60); --chat-thread-list-menu-color: var(--shades-white-60); --chat-thread-list-menu-bg: var(--shades-black-80); --chat-thread-list-menu-active-color: var(--shades-white-60); --chat-thread-list-menu-active-bg: var(--shades-black-90); --search-clear-color: var(--shades-white-100); --search-clear-bg: var(--shades-black-70); --search-input-color: var(--shades-white-100); --search-input-placeholder: var(--shades-black-60); --search-icon-color: var(--shades-black-60); --tabs-header-active-color: var(--shades-white-100); --tabs-header-active-border: var(--violet-light-100); --tabs-header-background-color: var(--shades-black-60); --tabs-header-background-border: var(--shades-black-80); --tabs-header-background-color-hover: var(--shades-white-80); --tabs-header-background-border-hover: var(--shades-black-70); --members-modal-member-text: var(--shades-black-60); --members-modal-member-text-hover: var(--shades-white-100); --label-default-bg: var(--violet-dark-80); --label-default-color: var(--shades-white-80); --subchannels-modal-color: var(--shades-black-60); --subchannels-modal-color-hover: var(--shades-white-100); --color-selector-active-bg: var(--shades-black-80); --relationship-modal-color: var(--shades-black-60); --arrow-extension-color: var(--shades-black-60); --modal-close-color: var(--shades-black-60); --modal-close-color-hover: var(--shades-white-100); --add-members-group-header-color: var(--shades-black-60); --add-members-item-color: var(--shades-black-60); --add-members-item-color-hover: var(--shades-white-100); --add-members-item-disabled-color: var(--shades-black-80); --add-members-item-disabled-color-hover: var(--shades-black-60); --add-members-remove-pending-color: var(--error-primary); --add-members-remove-pending-color-hover: var(--error-light-50); --radio-border: var(--shades-black-70); --radio-color: var(--shades-white-60); --notification-settings-option-selected-bg: var(--shades-black-80); --notification-settings-option-title-color: var(--shades-white-90); --notification-settings-option-color: var(--shades-white-60); --notification-settings-option-invalid-color: var(--shades-black-80); --notification-settings-option-invalid-selected-color: var(--shades-black-60); --danger-zone-subheading-color: var(--shades-white-60); --danger-zone-explanation-color: var(--shades-black-60); --thread-creation-search-container-bg: var(--shades-black-90); --thread-creation-close-search-color: var(--shades-black-60); --thread-creation-search-item-bg-hover: var(--shades-black-80); --thread-creation-search-item-info-color: var(--shades-black-60); --chat-message-list-active-border: #5989d6; --sidebars-modal-color: var(--shades-black-60); --sidebars-modal-color-hover: var(--shades-white-100); --inline-engagement-bg: var(--shades-black-70); --inline-engagement-bg-hover: var(--shades-black-80); --inline-engagement-color: var(--fg); --compose-subchannel-header-fg: var(--shades-black-60); --compose-subchannel-header-bg: var(--shades-black-80); --compose-subchannel-label-color: var(--shades-black-60); --compose-subchannel-mark-color: var(--violet-light-100); --enum-option-icon-color: var(--violet-dark-100); --show-password-bg-hover: var(--shades-black-70); --typeahead-overlay-light: var(--shades-black-80); --typeahead-overlay-dark: var(--shades-black-90); --typeahead-overlay-text: var(--shades-white-100); --typeahead-overlay-shadow-primary: rgba(0, 0, 0, 0.25); --typeahead-overlay-shadow-secondary: rgba(0, 0, 0, 0.4); --spoiler-text-color: var(--spoiler-color); --spoiler-background-color: var(--spoiler-color); --purple-link: var(--violet-light-100); --drawer-expand-button: var(--shades-black-60); --drawer-expand-button-disabled: var(--shades-black-80); + --drawer-item-color: var(--shades-white-60); + --drawer-open-community-bg: #191919; }