diff --git a/web/chat/thread-menu.css b/web/chat/thread-menu.css new file mode 100644 index 000000000..f7becfd3c --- /dev/null +++ b/web/chat/thread-menu.css @@ -0,0 +1,18 @@ +button.topBarMenuButton { + background-color: transparent; + border: none; + cursor: pointer; + color: var(--thread-top-bar-menu-color); +} + +div.topBarMenuActionList { + position: absolute; + right: 10px; + top: 55px; + z-index: 1; + display: flex; + flex-direction: column; + background-color: var(--thread-menu-bg); + border-radius: 4px; + padding: 4px 0; +} diff --git a/web/chat/thread-menu.react.js b/web/chat/thread-menu.react.js new file mode 100644 index 000000000..c66cfe353 --- /dev/null +++ b/web/chat/thread-menu.react.js @@ -0,0 +1,62 @@ +// @flow + +import * as React from 'react'; + +import { type ThreadInfo } from 'lib/types/thread-types'; + +import SWMansionIcon from '../SWMansionIcon.react'; +import css from './thread-menu.css'; + +type ThreadMenuProps = { + +threadInfo: ThreadInfo, +}; + +function ThreadMenu(props: ThreadMenuProps): React.Node { + const [isOpen, setIsOpen] = React.useState(false); + + // eslint-disable-next-line no-unused-vars + const { threadInfo } = props; + + const menuItems = []; + + const closeMenuCallback = React.useCallback(() => { + document.removeEventListener('click', closeMenuCallback); + if (isOpen) { + setIsOpen(false); + } + }, [isOpen]); + + React.useEffect(() => { + if (!document || !isOpen) { + return undefined; + } + document.addEventListener('click', closeMenuCallback); + return () => document.removeEventListener('click', closeMenuCallback); + }, [closeMenuCallback, isOpen]); + + const switchMenuCallback = React.useCallback(() => { + setIsOpen(isMenuOpen => !isMenuOpen); + }, []); + + if (menuItems.length === 0) { + return null; + } + + let menuActionList = null; + if (isOpen) { + menuActionList = ( +
{menuItems}
+ ); + } + + return ( +
+ + {menuActionList} +
+ ); +} + +export default ThreadMenu; diff --git a/web/chat/thread-top-bar.react.js b/web/chat/thread-top-bar.react.js index 07052c663..ed780057a 100644 --- a/web/chat/thread-top-bar.react.js +++ b/web/chat/thread-top-bar.react.js @@ -1,40 +1,38 @@ // @flow import * as React from 'react'; import type { ThreadInfo } from 'lib/types/thread-types'; -import SWMansionIcon from '../SWMansionIcon.react'; import ThreadAncestors from './chat-thread-ancestors.react'; +import ThreadMenu from './thread-menu.react'; import css from './thread-top-bar.css'; type threadTopBarProps = { +threadInfo: ThreadInfo, }; function ThreadTopBar(props: threadTopBarProps): React.Node { const { threadInfo } = props; const threadBackgroundColorStyle = React.useMemo( () => ({ background: `#${threadInfo.color}`, }), [threadInfo.color], ); return (

{threadInfo.uiName}

- +
); } export default ThreadTopBar; diff --git a/web/theme.css b/web/theme.css index e8ebfe436..6a70b5a78 100644 --- a/web/theme.css +++ b/web/theme.css @@ -1,104 +1,105 @@ :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; --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-primary: var(--violet-dark-100); --btn-bg-danger: var(--error-primary); --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); --selected-thread-bg: var(--shades-black-90); --chat-timestamp-color: var(--shades-black-60); --tool-tip-bg: var(--shades-black-80); --tool-tip-color: var(--shades-black-60); --border-color: var(--shades-black-60); --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); --unread-bg: var(--error-primary); --settings-btn-bg: var(--violet-dark-100); --modal-bg: var(--shades-black-90); --join-bg: var(--shades-black-90); --help-color: var(--shades-black-60); --breadcrumb-color: var(--shades-black-60); --breadcrumb-color-unread: var(--shades-white-60); --btn-secondary-border: var(--shades-black-60); --thread-color-read: var(--shades-black-60); --thread-from-color-read: var(--shades-black-80); --thread-last-message-color-read: var(--shades-black-60); --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); --text-message-default-background: var(--shades-black-80); --message-action-tooltip-bg: var(--shades-black-90); + --thread-menu-bg: var(--shades-black-90); }