Desktop improvements (#4492)
* Update version to non-promise interface * History navigation in sidebar
This commit is contained in:
@@ -2,6 +2,7 @@ import styled from "styled-components";
|
||||
import ActionButton, {
|
||||
Props as ActionButtonProps,
|
||||
} from "~/components/ActionButton";
|
||||
import { undraggableOnDesktop } from "~/styles";
|
||||
|
||||
type Props = ActionButtonProps & {
|
||||
width?: number | string;
|
||||
@@ -30,6 +31,7 @@ const NudeButton = styled(ActionButton).attrs((props: Props) => ({
|
||||
cursor: var(--pointer);
|
||||
user-select: none;
|
||||
color: inherit;
|
||||
${undraggableOnDesktop()}
|
||||
`;
|
||||
|
||||
export default NudeButton;
|
||||
|
||||
@@ -26,6 +26,7 @@ import Sidebar from "./Sidebar";
|
||||
import ArchiveLink from "./components/ArchiveLink";
|
||||
import Collections from "./components/Collections";
|
||||
import HeaderButton, { HeaderButtonProps } from "./components/HeaderButton";
|
||||
import HistoryNavigation from "./components/HistoryNavigation";
|
||||
import Section from "./components/Section";
|
||||
import SidebarAction from "./components/SidebarAction";
|
||||
import SidebarLink from "./components/SidebarLink";
|
||||
@@ -57,6 +58,7 @@ function AppSidebar() {
|
||||
|
||||
return (
|
||||
<Sidebar ref={handleSidebarRef}>
|
||||
<HistoryNavigation />
|
||||
{dndArea && (
|
||||
<DndProvider backend={HTML5Backend} options={html5Options}>
|
||||
<OrganizationMenu>
|
||||
@@ -72,6 +74,7 @@ function AppSidebar() {
|
||||
/>
|
||||
}
|
||||
style={
|
||||
// Move the logo over to align with smaller size
|
||||
Desktop.hasInsetTitlebar() ? { paddingLeft: 8 } : undefined
|
||||
}
|
||||
showDisclosure
|
||||
|
||||
@@ -13,6 +13,7 @@ import isCloudHosted from "~/utils/isCloudHosted";
|
||||
import Sidebar from "./Sidebar";
|
||||
import Header from "./components/Header";
|
||||
import HeaderButton from "./components/HeaderButton";
|
||||
import HistoryNavigation from "./components/HistoryNavigation";
|
||||
import Section from "./components/Section";
|
||||
import SidebarLink from "./components/SidebarLink";
|
||||
import Version from "./components/Version";
|
||||
@@ -29,6 +30,7 @@ function SettingsSidebar() {
|
||||
|
||||
return (
|
||||
<Sidebar>
|
||||
<HistoryNavigation />
|
||||
<HeaderButton
|
||||
title={t("Return to App")}
|
||||
image={<StyledBackIcon color="currentColor" />}
|
||||
|
||||
@@ -253,7 +253,7 @@ const Container = styled(Flex)<ContainerProps>`
|
||||
z-index: ${depths.sidebar};
|
||||
max-width: 70%;
|
||||
min-width: 280px;
|
||||
padding-top: ${Desktop.hasInsetTitlebar() ? 24 : 0}px;
|
||||
padding-top: ${Desktop.hasInsetTitlebar() ? 36 : 0}px;
|
||||
${draggableOnDesktop()}
|
||||
${fadeOnDesktopBackgrounded()}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ import { CollapsedIcon } from "outline-icons";
|
||||
import * as React from "react";
|
||||
import styled, { keyframes } from "styled-components";
|
||||
import usePersistedState from "~/hooks/usePersistedState";
|
||||
import { undraggableOnDesktop } from "~/styles";
|
||||
|
||||
type Props = {
|
||||
/** Unique header id – if passed the header will become toggleable */
|
||||
@@ -76,6 +77,7 @@ const Button = styled.button`
|
||||
border-radius: 4px;
|
||||
-webkit-appearance: none;
|
||||
transition: all 100ms ease;
|
||||
${undraggableOnDesktop()}
|
||||
|
||||
&:not(:disabled):hover,
|
||||
&:not(:disabled):active {
|
||||
|
||||
@@ -2,6 +2,7 @@ import { ExpandedIcon, MoreIcon } from "outline-icons";
|
||||
import * as React from "react";
|
||||
import styled from "styled-components";
|
||||
import Flex from "~/components/Flex";
|
||||
import { undraggableOnDesktop } from "~/styles";
|
||||
|
||||
export type HeaderButtonProps = React.ComponentProps<typeof Wrapper> & {
|
||||
title: React.ReactNode;
|
||||
@@ -26,6 +27,7 @@ const HeaderButton = React.forwardRef<HTMLButtonElement, HeaderButtonProps>(
|
||||
ref
|
||||
) => (
|
||||
<Wrapper
|
||||
role="button"
|
||||
justify="space-between"
|
||||
align="center"
|
||||
as="button"
|
||||
@@ -69,6 +71,7 @@ const Wrapper = styled(Flex)<{ minHeight: number }>`
|
||||
overflow: hidden;
|
||||
user-select: none;
|
||||
cursor: var(--pointer);
|
||||
${undraggableOnDesktop()}
|
||||
|
||||
&:active,
|
||||
&:hover,
|
||||
|
||||
81
app/components/Sidebar/components/HistoryNavigation.tsx
Normal file
81
app/components/Sidebar/components/HistoryNavigation.tsx
Normal file
@@ -0,0 +1,81 @@
|
||||
import { ArrowIcon } from "outline-icons";
|
||||
import * as React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import styled from "styled-components";
|
||||
import Flex from "~/components/Flex";
|
||||
import NudeButton from "~/components/NudeButton";
|
||||
import Tooltip from "~/components/Tooltip";
|
||||
import useKeyDown from "~/hooks/useKeyDown";
|
||||
import Desktop from "~/utils/Desktop";
|
||||
import { isMac } from "~/utils/browser";
|
||||
|
||||
function HistoryNavigation(props: React.ComponentProps<typeof Flex>) {
|
||||
const { t } = useTranslation();
|
||||
const [back, setBack] = React.useState(false);
|
||||
const [forward, setForward] = React.useState(false);
|
||||
|
||||
useKeyDown(
|
||||
(event) =>
|
||||
isMac()
|
||||
? event.metaKey && event.key === "["
|
||||
: event.altKey && event.key === "ArrowLeft",
|
||||
() => {
|
||||
setBack(true);
|
||||
setTimeout(() => setBack(false), 100);
|
||||
}
|
||||
);
|
||||
|
||||
useKeyDown(
|
||||
(event) =>
|
||||
isMac()
|
||||
? event.metaKey && event.key === "]"
|
||||
: event.altKey && event.key === "ArrowRight",
|
||||
() => {
|
||||
setForward(true);
|
||||
setTimeout(() => setForward(false), 100);
|
||||
}
|
||||
);
|
||||
|
||||
if (!Desktop.isMacApp()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Navigation gap={4} {...props}>
|
||||
<Tooltip tooltip={t("Go back")} delay={500}>
|
||||
<NudeButton onClick={() => Desktop.bridge.goBack()}>
|
||||
<Back color="currentColor" $active={back} />
|
||||
</NudeButton>
|
||||
</Tooltip>
|
||||
<Tooltip tooltip={t("Go forward")} delay={500}>
|
||||
<NudeButton onClick={() => Desktop.bridge.goForward()}>
|
||||
<Forward color="currentColor" $active={forward} />
|
||||
</NudeButton>
|
||||
</Tooltip>
|
||||
</Navigation>
|
||||
);
|
||||
}
|
||||
|
||||
const Navigation = styled(Flex)`
|
||||
position: absolute;
|
||||
right: 12px;
|
||||
top: 14px;
|
||||
`;
|
||||
|
||||
const Forward = styled(ArrowIcon)<{ $active: boolean }>`
|
||||
color: ${(props) => props.theme.textTertiary};
|
||||
opacity: ${(props) => (props.$active ? 1 : 0.5)};
|
||||
transition: color 100ms ease-in-out;
|
||||
|
||||
&:active,
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
`;
|
||||
|
||||
const Back = styled(Forward)`
|
||||
transform: rotate(180deg);
|
||||
flex-shrink: 0;
|
||||
`;
|
||||
|
||||
export default HistoryNavigation;
|
||||
12
app/typings/window.d.ts
vendored
12
app/typings/window.d.ts
vendored
@@ -9,7 +9,7 @@ declare global {
|
||||
/**
|
||||
* The version of the loaded application.
|
||||
*/
|
||||
version: () => Promise<string>;
|
||||
version: () => string;
|
||||
|
||||
/**
|
||||
* Restarts the application.
|
||||
@@ -61,6 +61,16 @@ declare global {
|
||||
* Registers a callback to be called when the application is ready to update.
|
||||
*/
|
||||
updateDownloaded: (callback: () => void) => void;
|
||||
|
||||
/**
|
||||
* Go back in history, if possible
|
||||
*/
|
||||
goBack: () => void;
|
||||
|
||||
/**
|
||||
* Go forward in history, if possible
|
||||
*/
|
||||
goForward: () => void;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -191,6 +191,8 @@
|
||||
"New nested document": "New nested document",
|
||||
"Document not supported – try Markdown, Plain text, HTML, or Word": "Document not supported – try Markdown, Plain text, HTML, or Word",
|
||||
"Empty": "Empty",
|
||||
"Go back": "Go back",
|
||||
"Go forward": "Go forward",
|
||||
"Starred documents could not be loaded": "Starred documents could not be loaded",
|
||||
"Starred": "Starred",
|
||||
"Show more": "Show more",
|
||||
|
||||
Reference in New Issue
Block a user