diff --git a/web/navigation-panels/chat-thread-ancestors.css b/web/navigation-panels/chat-thread-ancestors.css index eb176823b..f54e208fa 100644 --- a/web/navigation-panels/chat-thread-ancestors.css +++ b/web/navigation-panels/chat-thread-ancestors.css @@ -1,51 +1,48 @@ -div.ancestorThreadsContainer { +.container { font-size: var(--xs-font-12); display: flex; align-items: center; - column-gap: 5px; + column-gap: 12px; + overflow: hidden; } -div.ancestorName { - display: flex; - align-items: center; - padding: 2px 6px; - border-radius: 2px; - box-sizing: border-box; - line-height: 1.5; -} - -button.seeFullStructure { - background-color: transparent; - border: none; - cursor: pointer; +.communityName { + color: var(--thread-ancestor-color); + font-size: var(--l-font-18); + font-weight: var(--semi-bold); + white-space: nowrap; } -div.ancestorKeyserver { +.ancestorThreadsContainer { + border: 1px solid var(--topbar-lines); + border-radius: 8px; display: flex; - align-items: center; + padding: 7px 12px; + margin-right: 16px; + overflow: hidden; } -div.ancestorKeyserverName { - border-radius: 0 2px 2px 0; +.ancestorName { + color: var(--thread-ancestor-color); + font-size: var(--xs-font-12); + font-weight: var(--semi-bold); + line-height: 1.5; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + flex-shrink: 1; } -svg.ancestorSeparator { - color: var(--thread-ancestor-separator-color); +.chatName { + flex-shrink: 0.5; } -div.ancestorKeyserverOperator { - display: flex; - column-gap: 5px; - padding: 0 5px; - align-items: center; - border: 1px solid var(--thread-ancestor-keyserver-border); - border-radius: 2px 0 0 2px; - height: 22px; - box-sizing: border-box; +svg.chevronRight { + color: var(--thread-ancestor-separator-color); + flex-shrink: 0; } -button.seeFullAncestor { - font-size: var(--xs-font-12); - font-weight: var(--semi-bold); - cursor: pointer; +svg.ancestorSeparator { + align-self: center; + padding: 0 8px; } diff --git a/web/navigation-panels/chat-thread-ancestors.react.js b/web/navigation-panels/chat-thread-ancestors.react.js index cb0f63233..75a136bf3 100644 --- a/web/navigation-panels/chat-thread-ancestors.react.js +++ b/web/navigation-panels/chat-thread-ancestors.react.js @@ -1,128 +1,73 @@ // @flow -import classNames from 'classnames'; +import classnames from 'classnames'; import * as React from 'react'; +import { ChevronRight } from 'react-feather'; -import SWMansionIcon from 'lib/components/SWMansionIcon.react.js'; import { useAncestorThreads } from 'lib/shared/ancestor-threads.js'; -import { colorIsDark } from 'lib/shared/thread-utils.js'; -import { useKeyserverAdmin } from 'lib/shared/user-utils.js'; import type { ThreadInfo } from 'lib/types/thread-types.js'; import { useResolvedThreadInfo } from 'lib/utils/entity-helpers.js'; import css from './chat-thread-ancestors.css'; -import CommIcon from '../CommIcon.react.js'; - -const SHOW_SEE_FULL_STRUCTURE = false; type ThreadAncestorsProps = { +threadInfo: ThreadInfo, }; function ThreadAncestors(props: ThreadAncestorsProps): React.Node { const { threadInfo } = props; - const { color: threadColor } = threadInfo; - const darkColor = colorIsDark(threadColor); - const threadColorStyle = React.useMemo( - () => ({ - backgroundColor: `#${threadColor}`, - color: darkColor - ? 'var(--thread-ancestor-color-light)' - : 'var(--thread-ancestor-color-dark)', - }), - [darkColor, threadColor], - ); - const fullStructureButtonColorStyle = React.useMemo( - () => ({ color: `#${threadColor}` }), - [threadColor], - ); - const ancestorThreads = useAncestorThreads(threadInfo); - - const community = ancestorThreads[0] ?? threadInfo; - const keyserverAdmin = useKeyserverAdmin(community); - const keyserverOwnerUsername = keyserverAdmin?.username; + const ancestorThreadsWithCommunity = useAncestorThreads(threadInfo); + const community = ancestorThreadsWithCommunity[0] ?? threadInfo; const resolvedCommunity = useResolvedThreadInfo(community); - const keyserverInfo = React.useMemo( - () => ( -
-
- - {keyserverOwnerUsername} -
-
- {resolvedCommunity.uiName} -
-
- ), - [resolvedCommunity.uiName, keyserverOwnerUsername, threadColorStyle], - ); + const threadHasNoAncestors = community === threadInfo; + + const ancestorThreads = ancestorThreadsWithCommunity.slice(1); - const middlePath = React.useMemo(() => { - if (ancestorThreads.length < 2) { + const chevronRight = React.useMemo(() => { + if (threadHasNoAncestors) { return null; } - return ( - <> - -
- … -
- - ); - }, [ancestorThreads.length, threadColorStyle]); - - const threadHasNoAncestors = community === threadInfo; + return ; + }, [threadHasNoAncestors]); const { uiName } = useResolvedThreadInfo(threadInfo); - const currentThread = React.useMemo(() => { + + const path = React.useMemo(() => { if (threadHasNoAncestors) { return null; } + const ancestors = ancestorThreads.map(ancestor => ( + + )); + const chatNameClasses = classnames(css.ancestorName, css.chatName); return ( - <> - -
- {uiName} -
- +
+ {ancestors} +
{uiName}
+
); - }, [threadHasNoAncestors, threadColorStyle, uiName]); + }, [ancestorThreads, threadHasNoAncestors, uiName]); - let seeFullStructure = null; - if (SHOW_SEE_FULL_STRUCTURE) { - seeFullStructure = ( - - ); - } + return ( +
+
{resolvedCommunity.uiName}
+ {chevronRight} + {path} +
+ ); +} +function ThreadAncestor(props: ThreadAncestorsProps): React.Node { + const { uiName } = useResolvedThreadInfo(props.threadInfo); + const chevronClasses = classnames(css.ancestorSeparator, css.chevronRight); return ( <> -
- {keyserverInfo} - {middlePath} - {currentThread} -
- {seeFullStructure} +
{uiName}
+ ); } export default ThreadAncestors; diff --git a/web/navigation-panels/nav-state-info-bar.css b/web/navigation-panels/nav-state-info-bar.css index d882131cd..8c7dec42a 100644 --- a/web/navigation-panels/nav-state-info-bar.css +++ b/web/navigation-panels/nav-state-info-bar.css @@ -1,39 +1,28 @@ div.topBarContainer { display: flex; background-color: var(--bg); align-items: center; - justify-content: space-between; - padding: 0 16px; color: var(--thread-top-bar-color); height: 56px; -} - -div.topBarThreadInfo { - height: 24px; - display: flex; - align-items: center; - column-gap: 8px; + overflow: hidden; } div.threadColorSquare { width: 24px; height: 24px; border-radius: 4px; -} - -p.threadTitle { - font-size: var(--m-font-16); - font-weight: var(--bold); + flex: 0 0 auto; + margin: 0 12px 0 16px; } div.hide { height: 0px; opacity: 0; transition: height 200ms ease-in-out, opacity 200ms ease-in-out; } div.show { height: 56px; opacity: 1; transition: height 200ms ease-in-out, opacity 200ms ease-in-out; } diff --git a/web/navigation-panels/nav-state-info-bar.react.js b/web/navigation-panels/nav-state-info-bar.react.js index 731d3cafb..7589c3ec1 100644 --- a/web/navigation-panels/nav-state-info-bar.react.js +++ b/web/navigation-panels/nav-state-info-bar.react.js @@ -1,78 +1,73 @@ // @flow import classnames from 'classnames'; import * as React from 'react'; import type { ThreadInfo } from 'lib/types/thread-types.js'; -import { useResolvedThreadInfo } from 'lib/utils/entity-helpers.js'; import ThreadAncestors from './chat-thread-ancestors.react.js'; import css from './nav-state-info-bar.css'; type NavStateInfoBarProps = { +threadInfo: ThreadInfo, }; function NavStateInfoBar(props: NavStateInfoBarProps): React.Node { const { threadInfo } = props; const threadBackgroundColorStyle = React.useMemo( () => ({ background: `#${threadInfo.color}`, }), [threadInfo.color], ); - const { uiName } = useResolvedThreadInfo(threadInfo); return ( <> -
-
-

{uiName}

- -
+
+ ); } type PossiblyEmptyNavStateInfoBarProps = { +threadInfoInput: ?ThreadInfo, }; function PossiblyEmptyNavStateInfoBar( props: PossiblyEmptyNavStateInfoBarProps, ): React.Node { const { threadInfoInput } = props; const [threadInfo, setThreadInfo] = React.useState(threadInfoInput); React.useEffect(() => { if (threadInfoInput !== threadInfo) { if (threadInfoInput) { setThreadInfo(threadInfoInput); } else { const timeout = setTimeout(() => { setThreadInfo(null); }, 200); return () => clearTimeout(timeout); } } }, [threadInfoInput, threadInfo]); const content = React.useMemo(() => { if (threadInfo) { return ; } else { return null; } }, [threadInfo]); const classes = classnames(css.topBarContainer, { [css.hide]: !threadInfoInput, [css.show]: threadInfoInput, }); return
{content}
; } export default PossiblyEmptyNavStateInfoBar; diff --git a/web/theme.css b/web/theme.css index 01372b642..a2cd0210b 100644 --- a/web/theme.css +++ b/web/theme.css @@ -1,214 +1,214 @@ :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-color: var(--shades-white-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-active-background: var(--violet-dark-100); --tabs-header-background-color: var(--shades-black-60); --tabs-header-background-color-pill: var(--shades-white-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-active-item-color: var(--shades-white-100); --drawer-open-community-bg: #191919; --active-drawer-item-bg: rgba(0, 0, 0, 0.5); --community-drawer-lines: rgba(255, 255, 255, 0.08); --topbar-button-bg: var(--shades-black-90); --filters-button-bg: var(--shades-black-100); --filters-button-border: var(--shades-black-80); --filters-button-hover-bg: var(--shades-black-90); --filter-panel-fg: var(--shades-black-60); --filter-panel-bg: #0d0d0d; --topbar-button-bg-hover: var(--shades-black-80); --topbar-button-fg: var(--shades-white-60); + --topbar-lines: rgba(255, 255, 255, 0.08); }