Skip to content

Commit

Permalink
web: show exclusive titlebar in tablet/mobile mode
Browse files Browse the repository at this point in the history
  • Loading branch information
thecodrr committed Jan 1, 2025
1 parent bc80bc1 commit e4df0a0
Show file tree
Hide file tree
Showing 5 changed files with 137 additions and 49 deletions.
3 changes: 2 additions & 1 deletion apps/web/src/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@

.tabsScroll,
.titlebarLogo,
.theme-scope-titleBar {
.theme-scope-titleBar,
.route-container-header {
-webkit-app-region: drag;
}

Expand Down
57 changes: 18 additions & 39 deletions apps/web/src/components/editor/action-bar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,7 @@ import {
TableOfContents,
Trash,
Undo,
Unlock,
WindowClose,
WindowMaximize,
WindowMinimize,
WindowRestore
Unlock
} from "../icons";
import { ScrollContainer } from "@notesnook/ui";
import {
Expand Down Expand Up @@ -83,8 +79,8 @@ import { showPublishView } from "../publish-view";
import { restrictToHorizontalAxis } from "@dnd-kit/modifiers";
import useMobile from "../../hooks/use-mobile";
import { strings } from "@notesnook/intl";
import { TITLE_BAR_HEIGHT } from "../title-bar";
import { desktop } from "../../common/desktop-bridge";
import { TITLE_BAR_HEIGHT, getWindowControls } from "../title-bar";
import useTablet from "../../hooks/use-tablet";

export function EditorActionBar() {
const { isMaximized, isFullscreen, hasNativeWindowControls } =
Expand All @@ -102,6 +98,7 @@ export function EditorActionBar() {
const isNotePublished =
activeSession && db.monographs.isPublished(activeSession.id);
const isMobile = useMobile();
const isTablet = useTablet();

const tools = [
{
Expand Down Expand Up @@ -202,31 +199,13 @@ export function EditorActionBar() {
!isFocusMode,
onClick: () => useEditorStore.getState().toggleProperties()
},

{
title: strings.minimize(),
icon: WindowMinimize,
hidden: hasNativeWindowControls || isFullscreen,
enabled: true,
onClick: () => desktop?.window.minimze.mutate()
},
{
title: isMaximized ? strings.restore() : strings.maximize(),
icon: isMaximized ? WindowRestore : WindowMaximize,
enabled: true,
hidden: hasNativeWindowControls || isFullscreen,
onClick: () =>
isMaximized
? desktop?.window.restore.mutate()
: desktop?.window.maximize.mutate()
},
{
title: strings.close(),
icon: WindowClose,
hidden: hasNativeWindowControls || isFullscreen,
enabled: true,
onClick: () => window.close()
}
...getWindowControls(
hasNativeWindowControls,
isFullscreen,
isMaximized,
isTablet,
isMobile
)
];

return (
Expand Down Expand Up @@ -263,7 +242,7 @@ export function EditorActionBar() {
alignItems: "center",
bg: "transparent",
display: [
tool.hideOnMobile ? "none" : "flex",
"hideOnMobile" in tool && tool.hideOnMobile ? "none" : "flex",
tool.hidden ? "none" : "flex"
],
borderRadius: 0,
Expand Down Expand Up @@ -475,12 +454,12 @@ function Tab(props: TabProps) {
? Lock
: Unlock
: type === "readonly"
? Readonly
: type === "deleted"
? Trash
: isUnsaved
? NoteRemove
: Note;
? Readonly
: type === "deleted"
? Trash
: isUnsaved
? NoteRemove
: Note;
const { attributes, listeners, setNodeRef, transform, transition, active } =
useSortable({ id });

Expand Down
3 changes: 2 additions & 1 deletion apps/web/src/components/route-container/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ function Header(props: RouteContainerProps) {
alignItems: "center",
justifyContent: "center",
height: TITLE_BAR_HEIGHT,
zIndex: 2
zIndex: 2,
px: 1
}}
className="route-container-header search-container"
>
Expand Down
121 changes: 114 additions & 7 deletions apps/web/src/components/title-bar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,71 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
import { useWindowControls } from "../../hooks/use-window-controls";
import { isMac } from "../../utils/platform";
import { BaseThemeProvider } from "../theme-provider";
import { strings } from "@notesnook/intl";
import { desktop } from "../../common/desktop-bridge";
import {
WindowClose,
WindowMaximize,
WindowMinimize,
WindowRestore
} from "../icons";
import { Button, Flex } from "@theme-ui/components";
import useMobile from "../../hooks/use-mobile";
import useTablet from "../../hooks/use-tablet";

export function getWindowControls(
hasNativeWindowControls: boolean,
isFullscreen?: boolean,
isMaximized?: boolean,
isTablet?: boolean,
isMobile?: boolean
) {
if (isMobile || isTablet) return [];
return [
{
title: strings.minimize(),
icon: WindowMinimize,
hidden: hasNativeWindowControls || isFullscreen,
enabled: true,
onClick: () => desktop?.window.minimze.mutate()
},
{
title: isMaximized ? strings.restore() : strings.maximize(),
icon: isMaximized ? WindowRestore : WindowMaximize,
enabled: true,
hidden: hasNativeWindowControls || isFullscreen,
onClick: () =>
isMaximized
? desktop?.window.restore.mutate()
: desktop?.window.maximize.mutate()
},
{
title: strings.close(),
icon: WindowClose,
hidden: hasNativeWindowControls || isFullscreen,
enabled: true,
onClick: () => window.close()
}
];
}
export const TITLE_BAR_HEIGHT = 37;
export function TitleBar() {
const { isFullscreen } = useWindowControls();
export function TitleBar({ isUnderlay = isMac() }: { isUnderlay?: boolean }) {
const { isFullscreen, hasNativeWindowControls, isMaximized } =
useWindowControls();
const isTablet = useTablet();
const isMobile = useMobile();
if (
(!isMobile && !isTablet) ||
hasNativeWindowControls ||
(isFullscreen && isMac())
)
return null;

if (isFullscreen || !IS_DESKTOP_APP || !isMac()) return null;
const tools = getWindowControls(
hasNativeWindowControls,
isFullscreen,
isMaximized
);
return (
<BaseThemeProvider
scope="titleBar"
Expand All @@ -36,14 +95,62 @@ export function TitleBar() {
minHeight: TITLE_BAR_HEIGHT,
maxHeight: TITLE_BAR_HEIGHT,
display: "flex",
justifyContent: "space-between",
flexShrink: 0,
position: "absolute",
top: 0,
width: "100%",
zIndex: 1,
borderBottom: "1px solid var(--border)"
borderBottom: "1px solid var(--border)",
...(isUnderlay
? {
position: "absolute",
top: 0
}
: {})
}}
injectCssVars
></BaseThemeProvider>
>
{tools.length > 0 ? (
<svg
className="titlebarLogo"
style={{
alignSelf: "center",
height: 16,
width: 12,
marginRight: 10,
marginLeft: 10
}}
>
<use href="#themed-logo" />
</svg>
) : null}
<Flex sx={{ alignItems: "center" }}>
{tools.map((tool) => (
<Button
data-test-id={tool.title}
disabled={!tool.enabled}
variant={tool.title === "Close" ? "error" : "secondary"}
title={tool.title}
key={tool.title}
sx={{
height: "100%",
alignItems: "center",
bg: "transparent",
display: tool.hidden ? "none" : "flex",
borderRadius: 0,
flexShrink: 0,
"&:hover svg path": {
fill:
tool.title === "Close"
? "var(--accentForeground-error) !important"
: "var(--icon)"
}
}}
onClick={tool.onClick}
>
<tool.icon size={18} />
</Button>
))}
</Flex>
</BaseThemeProvider>
);
}
2 changes: 1 addition & 1 deletion apps/web/src/root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ export async function startApp() {
console.error(e);
root.render(
<>
<TitleBar />
<TitleBar isUnderlay={false} />
<ErrorComponent
error={e}
resetErrorBoundary={() => window.location.reload()}
Expand Down

0 comments on commit e4df0a0

Please sign in to comment.