Fix logo not being visible in auxiliary views when sidebar is collapsed (#347)

This commit is contained in:
Evan Simkowitz 2024-02-27 18:21:00 -08:00 committed by GitHub
parent 3f83441868
commit 314932d402
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 186 additions and 206 deletions

View File

@ -250,6 +250,36 @@ a.a-block {
} }
} }
.logo-button-container {
width: 105px;
flex-shrink: 0;
position: absolute;
z-index: 25;
top: 7px;
left: 0px;
display: flex;
flex-direction: row;
justify-content: flex-end;
align-items: center;
-webkit-app-region: drag;
pointer-events: none;
.logo-button {
width: 25px;
height: 25px;
margin-right: 6px;
cursor: pointer;
user-select: none;
-webkit-app-region: no-drag;
pointer-events: all;
&:hover {
background-color: #333;
border-radius: 4px;
}
}
}
.copied-indicator { .copied-indicator {
position: absolute; position: absolute;
top: 0; top: 0;
@ -641,42 +671,6 @@ a.a-block {
} }
} }
.mainview {
flex-grow: 1;
display: flex;
flex-direction: column;
position: relative;
border-radius: 0 var(--app-border-radius) var(--app-border-radius) 0;
border-bottom: 1px solid var(--app-border-color);
border-right: 1px solid var(--app-border-color);
border-left: 1px solid var(--app-border-color);
background-color: black;
&.is-hidden {
display: none;
}
.header {
-webkit-app-region: drag;
padding: 24px 18px;
margin: 0;
display: flex;
justify-content: space-between;
align-items: center;
.close-div {
-webkit-app-region: no-drag;
font-size: 1.5em;
}
&.bottom-border {
border-bottom: 1px solid white;
padding-bottom: 20px;
margin-bottom: 20px;
}
}
}
.settings-field { .settings-field {
display: flex; display: flex;
flex-direction: row; flex-direction: row;

View File

@ -8,7 +8,7 @@ import { boundMethod } from "autobind-decorator";
import { If } from "tsx-control-statements/components"; import { If } from "tsx-control-statements/components";
import dayjs from "dayjs"; import dayjs from "dayjs";
import localizedFormat from "dayjs/plugin/localizedFormat"; import localizedFormat from "dayjs/plugin/localizedFormat";
import { GlobalModel } from "@/models"; import { GlobalCommandRunner, GlobalModel } from "@/models";
import { isBlank } from "@/util/util"; import { isBlank } from "@/util/util";
import { WorkspaceView } from "./workspace/workspaceview"; import { WorkspaceView } from "./workspace/workspaceview";
import { PluginsView } from "./pluginsview/pluginsview"; import { PluginsView } from "./pluginsview/pluginsview";
@ -20,6 +20,7 @@ import { MainSideBar } from "./sidebar/sidebar";
import { DisconnectedModal, ClientStopModal } from "./common/modals"; import { DisconnectedModal, ClientStopModal } from "./common/modals";
import { ModalsProvider } from "./common/modals/provider"; import { ModalsProvider } from "./common/modals/provider";
import { ErrorBoundary } from "./common/error/errorboundary"; import { ErrorBoundary } from "./common/error/errorboundary";
import cn from "classnames";
import "./app.less"; import "./app.less";
dayjs.extend(localizedFormat); dayjs.extend(localizedFormat);
@ -37,7 +38,7 @@ class App extends React.Component<{}, {}> {
@boundMethod @boundMethod
handleContextMenu(e: any) { handleContextMenu(e: any) {
let isInNonTermInput = false; let isInNonTermInput = false;
let activeElem = document.activeElement; const activeElem = document.activeElement;
if (activeElem != null && activeElem.nodeName == "TEXTAREA") { if (activeElem != null && activeElem.nodeName == "TEXTAREA") {
if (!activeElem.classList.contains("xterm-helper-textarea")) { if (!activeElem.classList.contains("xterm-helper-textarea")) {
isInNonTermInput = true; isInNonTermInput = true;
@ -46,17 +47,13 @@ class App extends React.Component<{}, {}> {
if (activeElem != null && activeElem.nodeName == "INPUT" && activeElem.getAttribute("type") == "text") { if (activeElem != null && activeElem.nodeName == "INPUT" && activeElem.getAttribute("type") == "text") {
isInNonTermInput = true; isInNonTermInput = true;
} }
let opts: ContextMenuOpts = {}; const opts: ContextMenuOpts = {};
if (isInNonTermInput) { if (isInNonTermInput) {
opts.showCut = true; opts.showCut = true;
} }
let sel = window.getSelection(); const sel = window.getSelection();
if (!isBlank(sel?.toString())) { if (!isBlank(sel?.toString()) || isInNonTermInput) {
GlobalModel.contextEditMenu(e, opts); GlobalModel.contextEditMenu(e, opts);
} else {
if (isInNonTermInput) {
GlobalModel.contextEditMenu(e, opts);
}
} }
} }
@ -67,13 +64,19 @@ class App extends React.Component<{}, {}> {
})(); })();
} }
@boundMethod
openSidebar() {
const width = GlobalModel.mainSidebarModel.getWidth(true);
GlobalCommandRunner.clientSetSidebar(width, false);
}
render() { render() {
let remotesModel = GlobalModel.remotesModel; const remotesModel = GlobalModel.remotesModel;
let disconnected = !GlobalModel.ws.open.get() || !GlobalModel.waveSrvRunning.get(); const disconnected = !GlobalModel.ws.open.get() || !GlobalModel.waveSrvRunning.get();
let hasClientStop = GlobalModel.getHasClientStop(); const hasClientStop = GlobalModel.getHasClientStop();
let dcWait = this.dcWait.get(); const dcWait = this.dcWait.get();
let platform = GlobalModel.getPlatform(); const platform = GlobalModel.getPlatform();
let clientData = GlobalModel.clientData.get(); const clientData = GlobalModel.clientData.get();
// Previously, this is done in sidebar.tsx but it causes flicker when clientData is null cos screen-view shifts around. // Previously, this is done in sidebar.tsx but it causes flicker when clientData is null cos screen-view shifts around.
// Doing it here fixes the flicker cos app is not rendered until clientData is populated. // Doing it here fixes the flicker cos app is not rendered until clientData is populated.
@ -106,14 +109,22 @@ class App extends React.Component<{}, {}> {
setTimeout(() => this.updateDcWait(false), 0); setTimeout(() => this.updateDcWait(false), 0);
} }
// used to force a full reload of the application // used to force a full reload of the application
let renderVersion = GlobalModel.renderVersion.get(); const renderVersion = GlobalModel.renderVersion.get();
const sidebarCollapsed = GlobalModel.mainSidebarModel.getCollapsed();
return ( return (
<div <div
key={"version-" + renderVersion} key={"version-" + renderVersion}
id="main" id="main"
className={"platform-" + platform} className={cn("platform-" + platform, { "sidebar-collapsed": sidebarCollapsed })}
onContextMenu={this.handleContextMenu} onContextMenu={this.handleContextMenu}
> >
<If condition={sidebarCollapsed}>
<div key="logo-button" className="logo-button-container">
<div className="logo-button" onClick={this.openSidebar}>
<img src="public/logos/wave-logo.png" alt="logo" />
</div>
</div>
</If>
<div ref={this.mainContentRef} className="main-content"> <div ref={this.mainContentRef} className="main-content">
<MainSideBar parentRef={this.mainContentRef} clientData={clientData} /> <MainSideBar parentRef={this.mainContentRef} clientData={clientData} />
<ErrorBoundary> <ErrorBoundary>

View File

@ -16,6 +16,7 @@ import { ReactComponent as TrashIcon } from "@/assets/icons/favourites/trash.svg
import { ReactComponent as FavoritesIcon } from "@/assets/icons/favourites.svg"; import { ReactComponent as FavoritesIcon } from "@/assets/icons/favourites.svg";
import "./bookmarks.less"; import "./bookmarks.less";
import { MainView } from "../common/elements/mainview";
type BookmarkProps = { type BookmarkProps = {
bookmark: BookmarkType; bookmark: BookmarkType;
@ -23,10 +24,6 @@ type BookmarkProps = {
@mobxReact.observer @mobxReact.observer
class Bookmark extends React.Component<BookmarkProps, {}> { class Bookmark extends React.Component<BookmarkProps, {}> {
constructor(props: BookmarkProps) {
super(props);
}
@boundMethod @boundMethod
handleDeleteClick(): void { handleDeleteClick(): void {
let { bookmark } = this.props; let { bookmark } = this.props;
@ -45,14 +42,12 @@ class Bookmark extends React.Component<BookmarkProps, {}> {
handleEditCancel(): void { handleEditCancel(): void {
let model = GlobalModel.bookmarksModel; let model = GlobalModel.bookmarksModel;
model.cancelEdit(); model.cancelEdit();
return;
} }
@boundMethod @boundMethod
handleEditUpdate(): void { handleEditUpdate(): void {
let model = GlobalModel.bookmarksModel; let model = GlobalModel.bookmarksModel;
model.confirmEdit(); model.confirmEdit();
return;
} }
@boundMethod @boundMethod
@ -185,31 +180,15 @@ class Bookmark extends React.Component<BookmarkProps, {}> {
@mobxReact.observer @mobxReact.observer
class BookmarksView extends React.Component<{}, {}> { class BookmarksView extends React.Component<{}, {}> {
constructor(props: {}) {
super(props);
}
@boundMethod
closeView(): void {
GlobalModel.bookmarksModel.closeView();
}
render() { render() {
let isHidden = GlobalModel.activeMainView.get() != "bookmarks"; const isHidden = GlobalModel.activeMainView.get() != "bookmarks";
if (isHidden) { if (isHidden) {
return null; return null;
} }
let bookmarks = GlobalModel.bookmarksModel.bookmarks; let bookmarks = GlobalModel.bookmarksModel.bookmarks;
let idx: number = 0;
let bookmark: BookmarkType = null; let bookmark: BookmarkType = null;
return ( return (
<div className={cn("mainview", "bookmarks-view", { "is-hidden": isHidden })}> <MainView viewName="bookmarks" title="Bookmarks" onClose={GlobalModel.bookmarksModel.closeView}>
<div className="header bottom-border">
<div className="bookmarks-title text-primary">Favorites</div>
<div className="close-div hoverEffect" title="Close (Escape)" onClick={this.closeView}>
<i className="fa-sharp fa-solid fa-xmark"></i>
</div>
</div>
<div className="bookmarks-list"> <div className="bookmarks-list">
<For index="idx" each="bookmark" of={bookmarks}> <For index="idx" each="bookmark" of={bookmarks}>
<Bookmark key={bookmark.bookmarkid} bookmark={bookmark} /> <Bookmark key={bookmark.bookmarkid} bookmark={bookmark} />
@ -238,7 +217,7 @@ class BookmarksView extends React.Component<{}, {}> {
</div> </div>
</div> </div>
</If> </If>
</div> </MainView>
); );
} }
} }

View File

@ -12,6 +12,7 @@ import { commandRtnHandler, isBlank } from "@/util/util";
import * as appconst from "@/app/appconst"; import * as appconst from "@/app/appconst";
import "./clientsettings.less"; import "./clientsettings.less";
import { MainView } from "../common/elements/mainview";
@mobxReact.observer @mobxReact.observer
class ClientSettingsView extends React.Component<{ model: RemotesModel }, { hoveredItemId: string }> { class ClientSettingsView extends React.Component<{ model: RemotesModel }, { hoveredItemId: string }> {
@ -105,11 +106,6 @@ class ClientSettingsView extends React.Component<{ model: RemotesModel }, { hove
})(); })();
} }
@boundMethod
handleClose(): void {
GlobalModel.clientSettingsViewModel.closeView();
}
@boundMethod @boundMethod
handleChangeShortcut(newShortcut: string): void { handleChangeShortcut(newShortcut: string): void {
const prtn = GlobalCommandRunner.setGlobalShortcut(newShortcut); const prtn = GlobalCommandRunner.setGlobalShortcut(newShortcut);
@ -148,13 +144,11 @@ class ClientSettingsView extends React.Component<{ model: RemotesModel }, { hove
const curFontFamily = GlobalModel.getTermFontFamily(); const curFontFamily = GlobalModel.getTermFontFamily();
return ( return (
<div className={cn("mainview", "clientsettings-view")}> <MainView
<header className="header bottom-border"> viewName="clientsettings"
<div className="clientsettings-title text-primary">Client Settings</div> title="Client Settings"
<div className="close-div hoverEffect" title="Close (Escape)" onClick={this.handleClose}> onClose={GlobalModel.clientSettingsViewModel.closeView}
<i className="fa-sharp fa-solid fa-xmark"></i> >
</div>
</header>
<div className="content"> <div className="content">
<div className="settings-field"> <div className="settings-field">
<div className="settings-label">Term Font Size</div> <div className="settings-label">Term Font Size</div>
@ -259,7 +253,7 @@ class ClientSettingsView extends React.Component<{ model: RemotesModel }, { hove
</div> </div>
<SettingsError errorMessage={this.errorMessage} /> <SettingsError errorMessage={this.errorMessage} />
</div> </div>
</div> </MainView>
); );
} }
} }

View File

@ -0,0 +1,55 @@
.mainview {
flex-grow: 1;
display: flex;
flex-direction: column;
position: relative;
border-radius: 0 var(--app-border-radius) var(--app-border-radius) 0;
border-bottom: 1px solid var(--app-border-color);
border-right: 1px solid var(--app-border-color);
border-left: 1px solid var(--app-border-color);
background-color: var(--app-bg-color);
&.is-hidden {
display: none;
}
.header {
-webkit-app-region: drag;
display: flex;
justify-content: space-between;
flex-direction: row;
line-height: var(--screentabs-height);
vertical-align: middle;
padding: 0 10px 0 10px;
margin: 0;
.title {
font-size: 1.5em;
padding: 0 10px;
vertical-align: middle;
line-height: var(--screentabs-height);
color: var(--term-white);
margin: 0;
}
.close-div {
-webkit-app-region: no-drag;
font-size: 1.5em;
}
}
.bottom-border {
border-bottom: 1px solid var(--app-border-color);
margin-bottom: 10px;
}
}
// This ensures the tab bar does not collide with the floating logo. The floating logo sits above the sidebar when it is not collapsed, so no additional margin is needed in that case.
// More margin is given on macOS to account for the traffic light buttons
#main.platform-darwin.sidebar-collapsed .header {
margin-left: var(--floating-logo-width-darwin);
}
#main:not(.platform-darwin).sidebar-collapsed .header {
margin-left: var(--floating-logo-width);
}

View File

@ -0,0 +1,38 @@
// Copyright 2023, Command Line Inc.
// SPDX-License-Identifier: Apache-2.0
import * as React from "react";
import * as mobxReact from "mobx-react";
import cn from "classnames";
import { GlobalModel } from "@/models";
import "./mainview.less";
@mobxReact.observer
class MainView extends React.Component<{
viewName: string;
title: string;
onClose: () => void;
children: React.ReactNode;
}> {
render() {
// TODO: This is a workaround for History view not honoring the sidebar width. This is rooted in the table width for the history view, which uses `calc(100%-20px)`. To properly fix this, History view needs a full overhaul.
const width = window.innerWidth - 6 - GlobalModel.mainSidebarModel.getWidth();
return (
<div className={cn("mainview", `${this.props.viewName}-view`)} style={{ maxWidth: width }}>
<div className="header-container bottom-border">
<header className="header">
<div className="title text-primary">{this.props.title}</div>
<div className="close-div hoverEffect" title="Close (Escape)" onClick={this.props.onClose}>
<i className="fa-sharp fa-solid fa-xmark"></i>
</div>
</header>
</div>
{this.props.children}
</div>
);
}
}
export { MainView };

View File

View File

View File

@ -12,6 +12,7 @@ import { Button, Status, ShowWaveShellInstallPrompt } from "@/common/elements";
import * as util from "@/util/util"; import * as util from "@/util/util";
import "./connections.less"; import "./connections.less";
import { MainView } from "../common/elements/mainview";
@mobxReact.observer @mobxReact.observer
class ConnectionsView extends React.Component<{ model: RemotesModel }, { hoveredItemId: string }> { class ConnectionsView extends React.Component<{ model: RemotesModel }, { hoveredItemId: string }> {
@ -97,11 +98,6 @@ class ConnectionsView extends React.Component<{ model: RemotesModel }, { hovered
} }
} }
@boundMethod
handleClose(): void {
GlobalModel.connectionViewModel.closeView();
}
componentDidMount() { componentDidMount() {
if (this.tableRef.current != null) { if (this.tableRef.current != null) {
this.tableRszObs = new ResizeObserver(this.handleTableResize.bind(this)); this.tableRszObs = new ResizeObserver(this.handleTableResize.bind(this));
@ -130,13 +126,7 @@ class ConnectionsView extends React.Component<{ model: RemotesModel }, { hovered
let item: RemoteType = null; let item: RemoteType = null;
return ( return (
<div className={cn("mainview", "connections-view")}> <MainView viewName="connections" title="Connections" onClose={GlobalModel.connectionViewModel.closeView}>
<header className="header bottom-border">
<div className="connections-title text-primary">Connections</div>
<div className="close-div hoverEffect" title="Close (Escape)" onClick={this.handleClose}>
<i className="fa-sharp fa-solid fa-xmark"></i>
</div>
</header>
<table <table
className="connections-table" className="connections-table"
cellSpacing="0" cellSpacing="0"
@ -209,7 +199,7 @@ class ConnectionsView extends React.Component<{ model: RemotesModel }, { hovered
<div>No Connections Items Found</div> <div>No Connections Items Found</div>
</div> </div>
</If> </If>
</div> </MainView>
); );
} }
} }

View File

@ -1,10 +1,6 @@
.history-view { .history-view {
padding-bottom: 10px; padding-bottom: 10px;
.header {
padding: 18px 18px;
}
.icon { .icon {
width: 2em !important; width: 2em !important;
height: 1.3em !important; height: 1.3em !important;
@ -43,23 +39,7 @@
top: 0.5em; top: 0.5em;
} }
.close-div {
position: absolute;
right: 1em;
top: 0.8em;
cursor: pointer;
width: 1.5em;
height: 1.5em;
border-radius: 50%;
svg {
width: 1.5em;
height: 1.5em;
fill: var(--app-text-color);
}
}
.history-search { .history-search {
flex-grow: 1;
padding: 0 10px 10px 10px; padding: 0 10px 10px 10px;
input { input {

View File

@ -28,6 +28,7 @@ import { ReactComponent as CheckIcon } from "@/assets/icons/line/check.svg";
import { ReactComponent as CopyIcon } from "@/assets/icons/history/copy.svg"; import { ReactComponent as CopyIcon } from "@/assets/icons/history/copy.svg";
import "./history.less"; import "./history.less";
import { MainView } from "../common/elements/mainview";
dayjs.extend(customParseFormat); dayjs.extend(customParseFormat);
dayjs.extend(localizedFormat); dayjs.extend(localizedFormat);
@ -178,11 +179,6 @@ class HistoryView extends React.Component<{}, {}> {
remoteDropdownActive: OV<boolean> = mobx.observable.box(false, { name: "remoteDropdownActive" }); remoteDropdownActive: OV<boolean> = mobx.observable.box(false, { name: "remoteDropdownActive" });
copiedItemId: OV<string> = mobx.observable.box(null, { name: "copiedItemId" }); copiedItemId: OV<string> = mobx.observable.box(null, { name: "copiedItemId" });
@boundMethod
clickCloseHandler(): void {
GlobalModel.historyViewModel.closeView();
}
@boundMethod @boundMethod
handleNext() { handleNext() {
GlobalModel.historyViewModel.goNext(); GlobalModel.historyViewModel.goNext();
@ -206,7 +202,6 @@ class HistoryView extends React.Component<{}, {}> {
if (checkKeyPressed(waveEvent, "Enter")) { if (checkKeyPressed(waveEvent, "Enter")) {
e.preventDefault(); e.preventDefault();
GlobalModel.historyViewModel.submitSearch(); GlobalModel.historyViewModel.submitSearch();
return;
} }
} }
@ -229,10 +224,9 @@ class HistoryView extends React.Component<{}, {}> {
let numSelected = hvm.selectedItems.size; let numSelected = hvm.selectedItems.size;
if (numSelected > 0) { if (numSelected > 0) {
hvm.selectedItems.clear(); hvm.selectedItems.clear();
return;
} else { } else {
for (let i = 0; i < hvm.items.length; i++) { for (const element of hvm.items) {
hvm.selectedItems.set(hvm.items[i].historyid, true); hvm.selectedItems.set(element.historyid, true);
} }
} }
})(); })();
@ -302,7 +296,6 @@ class HistoryView extends React.Component<{}, {}> {
return; return;
} }
hvm.setFromDate(e.target.value); hvm.setFromDate(e.target.value);
return;
} }
@boundMethod @boundMethod
@ -399,7 +392,6 @@ class HistoryView extends React.Component<{}, {}> {
return null; return null;
} }
let hvm = GlobalModel.historyViewModel; let hvm = GlobalModel.historyViewModel;
let idx: number = 0;
let item: HistoryItem = null; let item: HistoryItem = null;
let items = hvm.items.slice(); let items = hvm.items.slice();
let nowDate = new Date(); let nowDate = new Date();
@ -410,32 +402,13 @@ class HistoryView extends React.Component<{}, {}> {
let offset = hvm.offset.get(); let offset = hvm.offset.get();
let numSelected = hvm.selectedItems.size; let numSelected = hvm.selectedItems.size;
let activeItemId = hvm.activeItem.get(); let activeItemId = hvm.activeItem.get();
let activeItem = hvm.getHistoryItemById(activeItemId);
let activeLine: LineType = null;
if (activeItem != null) {
activeLine = hvm.getLineById(activeItem.lineid);
}
let sessionIds = Object.keys(snames); let sessionIds = Object.keys(snames);
let sessionId: string = null; let sessionId: string = null;
let remoteIds = Object.keys(rnames); let remoteIds = Object.keys(rnames);
let remoteId: string = null; let remoteId: string = null;
// TODO: something is weird with how we calculate width for views. Before, history view was not honoring tab width. This fix is copied from workspaceview.tsx, which had a similar issue.
const width = window.innerWidth - 6 - GlobalModel.mainSidebarModel.getWidth();
return ( return (
<div <MainView viewName="history" title="History" onClose={GlobalModel.historyViewModel.closeView}>
className={cn("history-view", "mainview", { "is-hidden": isHidden })}
style={{
width: `${width}px`,
}}
>
<header key="header" className="header">
<div className="clientsettings-title text-primary">History</div>
<div className="close-div hoverEffect" title="Close (Escape)" onClick={this.clickCloseHandler}>
<i className="fa-sharp fa-solid fa-xmark"></i>
</div>
</header>
<div key="search" className="history-search"> <div key="search" className="history-search">
<div className="main-search field"> <div className="main-search field">
<TextField <TextField
@ -678,14 +651,13 @@ class HistoryView extends React.Component<{}, {}> {
<ChevronRightIcon className="icon" /> <ChevronRightIcon className="icon" />
</div> </div>
</div> </div>
</div> </MainView>
); );
} }
} }
class LineContainer extends React.Component<{ historyId: string; width: number }, {}> { class LineContainer extends React.Component<{ historyId: string; width: number }, {}> {
line: LineType; line: LineType;
cmd: Cmd;
historyItem: HistoryItem; historyItem: HistoryItem;
visible: OV<boolean> = mobx.observable.box(true); visible: OV<boolean> = mobx.observable.box(true);
overrideCollapsed: OV<boolean> = mobx.observable.box(false); overrideCollapsed: OV<boolean> = mobx.observable.box(false);
@ -698,7 +670,6 @@ class LineContainer extends React.Component<{ historyId: string; width: number }
return; return;
} }
this.line = hvm.getLineById(this.historyItem.lineid); this.line = hvm.getLineById(this.historyItem.lineid);
this.cmd = hvm.getCmdById(this.historyItem.lineid);
} }
@boundMethod @boundMethod

View File

@ -26,6 +26,11 @@
--screentabs-font-weight: 300; --screentabs-font-weight: 300;
--screentabs-selected-font-weight: 300; --screentabs-selected-font-weight: 300;
// floating logo settings
--floating-logo-width-darwin: 110px;
--floating-logo-width: 40px;
--floating-logo-height: var(--screentabs-height);
// global colors // global colors
--app-accent-color: rgb(88, 193, 66); --app-accent-color: rgb(88, 193, 66);
--app-error-color: rgb(204, 0, 0); --app-error-color: rgb(204, 0, 0);

View File

@ -8,7 +8,6 @@ import { boundMethod } from "autobind-decorator";
import cn from "classnames"; import cn from "classnames";
import { GlobalModel, GlobalCommandRunner, Screen } from "@/models"; import { GlobalModel, GlobalCommandRunner, Screen } from "@/models";
import { ActionsIcon, StatusIndicator, CenteredIcon } from "@/common/icons/icons"; import { ActionsIcon, StatusIndicator, CenteredIcon } from "@/common/icons/icons";
import { renderCmdText } from "@/elements";
import { ReactComponent as SquareIcon } from "@/assets/icons/tab/square.svg"; import { ReactComponent as SquareIcon } from "@/assets/icons/tab/square.svg";
import * as constants from "@/app/appconst"; import * as constants from "@/app/appconst";
import { Reorder } from "framer-motion"; import { Reorder } from "framer-motion";

View File

@ -91,34 +91,6 @@
overflow: hidden; overflow: hidden;
height: var(--screentabs-height); height: var(--screentabs-height);
&.sidebar-collapsed .logo-button-container {
width: 105px;
flex-shrink: 0;
display: flex;
flex-direction: row;
justify-content: flex-end;
align-items: center;
-webkit-app-region: drag;
.logo-button {
width: 25px;
height: 25px;
margin-right: 6px;
cursor: pointer;
user-select: none;
-webkit-app-region: no-drag;
&:hover {
background-color: #333;
border-radius: 4px;
}
}
}
.logo-button {
width: 20px;
}
&:hover { &:hover {
z-index: 200; z-index: 200;
} }
@ -206,3 +178,13 @@
height: 100%; height: 100%;
} }
} }
// This ensures the tab bar does not collide with the floating logo. The floating logo sits above the sidebar when it is not collapsed, so no additional margin is needed in that case.
// More margin is given on macOS to account for the traffic light buttons
#main.platform-darwin.sidebar-collapsed .screen-tabs-container {
margin-left: var(--floating-logo-width-darwin);
}
#main:not(.platform-darwin).sidebar-collapsed .screen-tabs-container {
margin-left: var(--floating-logo-width);
}

View File

@ -168,12 +168,6 @@ class ScreenTabs extends React.Component<
// For touchpad events, do nothing and let the browser handle it // For touchpad events, do nothing and let the browser handle it
} }
@boundMethod
openSidebar() {
const width = GlobalModel.mainSidebarModel.getWidth(true);
GlobalCommandRunner.clientSetSidebar(width, false);
}
render() { render() {
let { showingScreens } = this.state; let { showingScreens } = this.state;
let { session } = this.props; let { session } = this.props;
@ -183,20 +177,8 @@ class ScreenTabs extends React.Component<
let screen: Screen | null = null; let screen: Screen | null = null;
let index = 0; let index = 0;
let activeScreenId = this.getActiveScreenId(); let activeScreenId = this.getActiveScreenId();
const sidebarCollapsed = GlobalModel.mainSidebarModel.getCollapsed();
return ( return (
<div <div className="screen-tabs-container">
className={cn("screen-tabs-container", {
"sidebar-collapsed": sidebarCollapsed,
})}
>
<If condition={sidebarCollapsed}>
<div key="logo-button" className="logo-button-container">
<div className="logo-button" onClick={this.openSidebar}>
<img src="public/logos/wave-logo.png" alt="logo" />
</div>
</div>
</If>
{/* Inner container ensures that hovering over the scrollbar doesn't trigger the hover effect on the tabs. This prevents weird flickering of the icons when the mouse is moved over the scrollbar. */} {/* Inner container ensures that hovering over the scrollbar doesn't trigger the hover effect on the tabs. This prevents weird flickering of the icons when the mouse is moved over the scrollbar. */}
<div <div
key="container-inner" key="container-inner"