diff --git a/app/actions/definitions/navigation.tsx b/app/actions/definitions/navigation.tsx index 234a23bda..d2f0c6dda 100644 --- a/app/actions/definitions/navigation.tsx +++ b/app/actions/definitions/navigation.tsx @@ -14,6 +14,7 @@ import { BrowserIcon, } from "outline-icons"; import * as React from "react"; +import { isMac } from "@shared/utils/browser"; import { developersUrl, changelogUrl, @@ -26,7 +27,6 @@ import KeyboardShortcuts from "~/scenes/KeyboardShortcuts"; import { createAction } from "~/actions"; import { NavigationSection, RecentSearchesSection } from "~/actions/sections"; import Desktop from "~/utils/Desktop"; -import { isMac } from "~/utils/browser"; import history from "~/utils/history"; import isCloudHosted from "~/utils/isCloudHosted"; import { diff --git a/app/components/Header.tsx b/app/components/Header.tsx index 0ffc82cc7..e86e634be 100644 --- a/app/components/Header.tsx +++ b/app/components/Header.tsx @@ -6,6 +6,7 @@ import * as React from "react"; import styled from "styled-components"; import breakpoint from "styled-components-breakpoint"; import { depths, s } from "@shared/styles"; +import { supportsPassiveListener } from "@shared/utils/browser"; import Button from "~/components/Button"; import Fade from "~/components/Fade"; import Flex from "~/components/Flex"; @@ -14,7 +15,6 @@ import useMobile from "~/hooks/useMobile"; import useStores from "~/hooks/useStores"; import { draggableOnDesktop, fadeOnDesktopBackgrounded } from "~/styles"; import Desktop from "~/utils/Desktop"; -import { supportsPassiveListener } from "~/utils/browser"; type Props = { left?: React.ReactNode; diff --git a/app/components/Sidebar/components/HistoryNavigation.tsx b/app/components/Sidebar/components/HistoryNavigation.tsx index 1bd8640cf..7e73945d6 100644 --- a/app/components/Sidebar/components/HistoryNavigation.tsx +++ b/app/components/Sidebar/components/HistoryNavigation.tsx @@ -3,12 +3,12 @@ import * as React from "react"; import { useTranslation } from "react-i18next"; import styled from "styled-components"; import { s } from "@shared/styles"; +import { isMac } from "@shared/utils/browser"; 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) { const { t } = useTranslation(); diff --git a/app/hooks/useWindowScrollPosition.ts b/app/hooks/useWindowScrollPosition.ts index e00641309..4f3cf2b33 100644 --- a/app/hooks/useWindowScrollPosition.ts +++ b/app/hooks/useWindowScrollPosition.ts @@ -2,7 +2,7 @@ // maintained. import throttle from "lodash/throttle"; import { useState, useEffect } from "react"; -import { supportsPassiveListener } from "~/utils/browser"; +import { supportsPassiveListener } from "@shared/utils/browser"; const getPosition = () => ({ x: window.pageXOffset, diff --git a/app/scenes/Document/components/MultiplayerEditor.tsx b/app/scenes/Document/components/MultiplayerEditor.tsx index 8660ccff9..9b508b59f 100644 --- a/app/scenes/Document/components/MultiplayerEditor.tsx +++ b/app/scenes/Document/components/MultiplayerEditor.tsx @@ -6,6 +6,7 @@ import { useHistory } from "react-router-dom"; import { IndexeddbPersistence } from "y-indexeddb"; import * as Y from "yjs"; import MultiplayerExtension from "@shared/editor/extensions/Multiplayer"; +import { supportsPassiveListener } from "@shared/utils/browser"; import Editor, { Props as EditorProps } from "~/components/Editor"; import env from "~/env"; import useCurrentUser from "~/hooks/useCurrentUser"; @@ -16,7 +17,6 @@ import useStores from "~/hooks/useStores"; import useToasts from "~/hooks/useToasts"; import { AwarenessChangeEvent } from "~/types"; import Logger from "~/utils/Logger"; -import { supportsPassiveListener } from "~/utils/browser"; import { homePath } from "~/utils/routeHelpers"; type Props = EditorProps & { diff --git a/app/scenes/KeyboardShortcuts.tsx b/app/scenes/KeyboardShortcuts.tsx index 385c0ff32..f7ae2f280 100644 --- a/app/scenes/KeyboardShortcuts.tsx +++ b/app/scenes/KeyboardShortcuts.tsx @@ -2,10 +2,10 @@ import * as React from "react"; import { useTranslation } from "react-i18next"; import styled from "styled-components"; import { s } from "@shared/styles"; +import { isMac } from "@shared/utils/browser"; import Flex from "~/components/Flex"; import InputSearch from "~/components/InputSearch"; import Key from "~/components/Key"; -import { isMac } from "~/utils/browser"; import { metaDisplay, altDisplay } from "~/utils/keyboard"; function KeyboardShortcuts() { diff --git a/app/styles/index.ts b/app/styles/index.ts index 3c0026d6d..296e17477 100644 --- a/app/styles/index.ts +++ b/app/styles/index.ts @@ -1,5 +1,5 @@ +import { isTouchDevice } from "@shared/utils/browser"; import Desktop from "~/utils/Desktop"; -import { isTouchDevice } from "~/utils/browser"; /** * Returns "hover" on a non-touch device and "active" on a touch device. To diff --git a/app/utils/Desktop.ts b/app/utils/Desktop.ts index e0dd60816..d31809d6e 100644 --- a/app/utils/Desktop.ts +++ b/app/utils/Desktop.ts @@ -1,4 +1,4 @@ -import { isMac, isWindows } from "./browser"; +import { isMac, isWindows } from "@shared/utils/browser"; export default class Desktop { /** diff --git a/app/utils/keyboard.ts b/app/utils/keyboard.ts index 627ea1ba5..d90944c05 100644 --- a/app/utils/keyboard.ts +++ b/app/utils/keyboard.ts @@ -1,4 +1,4 @@ -import { isMac } from "~/utils/browser"; +import { isMac } from "@shared/utils/browser"; export const altDisplay = isMac() ? "⌥" : "Alt"; diff --git a/shared/editor/lib/isModKey.ts b/shared/editor/lib/isModKey.ts deleted file mode 100644 index 468a0af6b..000000000 --- a/shared/editor/lib/isModKey.ts +++ /dev/null @@ -1,6 +0,0 @@ -const SSR = typeof window === "undefined"; -const isMac = !SSR && window.navigator.platform === "MacIntel"; - -export default function isModKey(event: KeyboardEvent | MouseEvent): boolean { - return isMac ? event.metaKey : event.ctrlKey; -} diff --git a/shared/editor/nodes/CodeFence.ts b/shared/editor/nodes/CodeFence.ts index 2dbc2fb2f..fd1a452a8 100644 --- a/shared/editor/nodes/CodeFence.ts +++ b/shared/editor/nodes/CodeFence.ts @@ -58,6 +58,7 @@ import { Primitive } from "utility-types"; import { Dictionary } from "~/hooks/useDictionary"; import { UserPreferences } from "../../types"; import Storage from "../../utils/Storage"; +import { isMac } from "../../utils/browser"; import { newlineInCode, insertSpaceTab, @@ -208,14 +209,22 @@ export default class CodeFence extends Node { } keys({ type, schema }: { type: NodeType; schema: Schema }) { - return { + const output = { "Shift-Ctrl-\\": toggleBlockType(type, schema.nodes.paragraph), Tab: insertSpaceTab, Enter: newlineInCode, "Shift-Enter": newlineInCode, - "Ctrl-a": moveToPreviousNewline, - "Ctrl-e": moveToNextNewline, }; + + if (isMac()) { + return { + ...output, + "Ctrl-a": moveToPreviousNewline, + "Ctrl-e": moveToNextNewline, + }; + } + + return output; } get plugins() { diff --git a/app/utils/browser.ts b/shared/utils/browser.ts similarity index 89% rename from app/utils/browser.ts rename to shared/utils/browser.ts index ac642149a..42c4aed34 100644 --- a/app/utils/browser.ts +++ b/shared/utils/browser.ts @@ -1,8 +1,10 @@ +const SSR = typeof window === "undefined"; + /** * Returns true if the client is a touch device. */ export function isTouchDevice(): boolean { - if (typeof window === "undefined") { + if (SSR) { return false; } return window.matchMedia?.("(hover: none) and (pointer: coarse)")?.matches; @@ -12,6 +14,9 @@ export function isTouchDevice(): boolean { * Returns true if the client is running on a Mac. */ export function isMac(): boolean { + if (SSR) { + return false; + } return window.navigator.platform === "MacIntel"; } @@ -19,6 +24,9 @@ export function isMac(): boolean { * Returns true if the client is running on Windows. */ export function isWindows(): boolean { + if (SSR) { + return false; + } return window.navigator.platform === "Win32"; }