mirror of
https://github.com/streetwriters/notesnook.git
synced 2025-12-22 22:49:45 +01:00
mobile: editor ui overhaul
This commit is contained in:
@@ -21,13 +21,14 @@ import { useThemeColors } from "@notesnook/theme";
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { View } from "react-native";
|
import { View } from "react-native";
|
||||||
import { FlatList } from "react-native-actions-sheet";
|
import { FlatList } from "react-native-actions-sheet";
|
||||||
|
import Icon from "react-native-vector-icons/MaterialCommunityIcons";
|
||||||
import { db } from "../../common/database";
|
import { db } from "../../common/database";
|
||||||
import { DDS } from "../../services/device-detection";
|
import { DDS } from "../../services/device-detection";
|
||||||
import { eSendEvent, presentSheet } from "../../services/event-manager";
|
import { eSendEvent, presentSheet } from "../../services/event-manager";
|
||||||
import { ColorValues } from "../../utils/colors";
|
|
||||||
import { eOnLoadNote } from "../../utils/events";
|
import { eOnLoadNote } from "../../utils/events";
|
||||||
import { fluidTabsRef } from "../../utils/global-refs";
|
import { fluidTabsRef } from "../../utils/global-refs";
|
||||||
import { AppFontSize } from "../../utils/size";
|
import { AppFontSize } from "../../utils/size";
|
||||||
|
import { DefaultAppStyles } from "../../utils/styles";
|
||||||
import SheetProvider from "../sheet-provider";
|
import SheetProvider from "../sheet-provider";
|
||||||
import { IconButton } from "../ui/icon-button";
|
import { IconButton } from "../ui/icon-button";
|
||||||
import { Pressable } from "../ui/pressable";
|
import { Pressable } from "../ui/pressable";
|
||||||
@@ -38,8 +39,6 @@ import { DateMeta } from "./date-meta";
|
|||||||
import { Items } from "./items";
|
import { Items } from "./items";
|
||||||
import Notebooks from "./notebooks";
|
import Notebooks from "./notebooks";
|
||||||
import { TagStrip, Tags } from "./tags";
|
import { TagStrip, Tags } from "./tags";
|
||||||
import Icon from "react-native-vector-icons/MaterialCommunityIcons";
|
|
||||||
import { DefaultAppStyles } from "../../utils/styles";
|
|
||||||
|
|
||||||
const Line = ({ top = 6, bottom = 6 }) => {
|
const Line = ({ top = 6, bottom = 6 }) => {
|
||||||
const { colors } = useThemeColors();
|
const { colors } = useThemeColors();
|
||||||
|
|||||||
@@ -29,6 +29,10 @@ import { ColorTags } from "./color-tags";
|
|||||||
import { strings } from "@notesnook/intl";
|
import { strings } from "@notesnook/intl";
|
||||||
import { DefaultAppStyles } from "../../utils/styles";
|
import { DefaultAppStyles } from "../../utils/styles";
|
||||||
import ManageTags from "../../screens/manage-tags";
|
import ManageTags from "../../screens/manage-tags";
|
||||||
|
import {
|
||||||
|
paddingTop,
|
||||||
|
paddingVertical
|
||||||
|
} from "deprecated-react-native-prop-types/DeprecatedLayoutPropTypes";
|
||||||
|
|
||||||
export const Tags = ({ item, close }) => {
|
export const Tags = ({ item, close }) => {
|
||||||
const { colors } = useThemeColors();
|
const { colors } = useThemeColors();
|
||||||
@@ -86,7 +90,6 @@ export const TagStrip = ({ item, close }) => {
|
|||||||
flexDirection: "row",
|
flexDirection: "row",
|
||||||
flexWrap: "wrap",
|
flexWrap: "wrap",
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
marginTop: DefaultAppStyles.GAP_VERTICAL,
|
|
||||||
gap: 5
|
gap: 5
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@@ -107,16 +110,13 @@ const TagItem = ({ tag, close }) => {
|
|||||||
|
|
||||||
const style = {
|
const style = {
|
||||||
paddingHorizontal: 0,
|
paddingHorizontal: 0,
|
||||||
borderRadius: 100,
|
paddingVertical: DefaultAppStyles.GAP_VERTICAL_SMALL
|
||||||
marginTop: 0,
|
|
||||||
backgroundColor: "transparent"
|
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<Button
|
<Button
|
||||||
onPress={onPress}
|
onPress={onPress}
|
||||||
title={"#" + tag.title}
|
title={"#" + tag.title}
|
||||||
type="plain"
|
type="plain"
|
||||||
height={20}
|
|
||||||
fontSize={AppFontSize.xs}
|
fontSize={AppFontSize.xs}
|
||||||
style={style}
|
style={style}
|
||||||
textStyle={{
|
textStyle={{
|
||||||
|
|||||||
@@ -89,10 +89,10 @@ function getSize() {
|
|||||||
xs: normalize(13.5) * scale.fontScale,
|
xs: normalize(13.5) * scale.fontScale,
|
||||||
sm: normalize(14.5) * scale.fontScale,
|
sm: normalize(14.5) * scale.fontScale,
|
||||||
md: normalize(16.5) * scale.fontScale,
|
md: normalize(16.5) * scale.fontScale,
|
||||||
lg: normalize(22) * scale.fontScale,
|
lg: normalize(20) * scale.fontScale,
|
||||||
xl: normalize(24) * scale.fontScale,
|
xl: normalize(22) * scale.fontScale,
|
||||||
xxl: normalize(28) * scale.fontScale,
|
xxl: normalize(25) * scale.fontScale,
|
||||||
xxxl: normalize(32) * scale.fontScale
|
xxxl: normalize(30) * scale.fontScale
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
325
apps/mobile/package-lock.json
generated
325
apps/mobile/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -33,6 +33,10 @@
|
|||||||
color: var(--nn_primary_placeholder) !important;
|
color: var(--nn_primary_placeholder) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.main-editor *:first-child {
|
||||||
|
margin-top: 0.5em !important;
|
||||||
|
}
|
||||||
|
|
||||||
#root {
|
#root {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
@@ -558,12 +558,28 @@ const Tiptap = ({
|
|||||||
height: "100%",
|
height: "100%",
|
||||||
display: "flex",
|
display: "flex",
|
||||||
flexDirection: "column",
|
flexDirection: "column",
|
||||||
position: "relative"
|
position: "relative",
|
||||||
|
paddingTop: "12px"
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{settings.noHeader || tab.session?.locked ? null : (
|
{settings.noHeader || tab.session?.locked ? null : (
|
||||||
<>
|
<>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
flexDirection: "row",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
padding: "0px 16px"
|
||||||
|
}}
|
||||||
|
>
|
||||||
<Tags settings={settings} loading={controller.loading} />
|
<Tags settings={settings} loading={controller.loading} />
|
||||||
|
<StatusBar
|
||||||
|
container={containerRef}
|
||||||
|
loading={controller.loading}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<Title
|
<Title
|
||||||
titlePlaceholder={controller.titlePlaceholder}
|
titlePlaceholder={controller.titlePlaceholder}
|
||||||
readonly={settings.readonly}
|
readonly={settings.readonly}
|
||||||
@@ -574,11 +590,6 @@ const Tiptap = ({
|
|||||||
timeFormat={settings.timeFormat}
|
timeFormat={settings.timeFormat}
|
||||||
loading={controller.loading}
|
loading={controller.loading}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<StatusBar
|
|
||||||
container={containerRef}
|
|
||||||
loading={controller.loading}
|
|
||||||
/>
|
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@@ -918,7 +929,7 @@ const TiptapProvider = (): JSX.Element => {
|
|||||||
editorContainer.classList.add("selectable", "main-editor", "searching");
|
editorContainer.classList.add("selectable", "main-editor", "searching");
|
||||||
editorContainer.style.flex = "1";
|
editorContainer.style.flex = "1";
|
||||||
editorContainer.style.cursor = "text";
|
editorContainer.style.cursor = "text";
|
||||||
editorContainer.style.padding = "0px 12px";
|
editorContainer.style.padding = "0px 16px";
|
||||||
editorContainer.style.color = colors.primary.paragraph;
|
editorContainer.style.color = colors.primary.paragraph;
|
||||||
editorContainer.style.fontSize = `${settings.fontSize}px`;
|
editorContainer.style.fontSize = `${settings.fontSize}px`;
|
||||||
editorContainer.style.fontFamily =
|
editorContainer.style.fontFamily =
|
||||||
|
|||||||
@@ -58,6 +58,43 @@ const MenuItem = (props: any) => (
|
|||||||
<MenuItemInner {...props} className={menuItemClassName} />
|
<MenuItemInner {...props} className={menuItemClassName} />
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const iconButtonStyle: React.CSSProperties = {
|
||||||
|
borderWidth: 0,
|
||||||
|
borderRadius: 100,
|
||||||
|
color: "var(--nn_primary_icon)",
|
||||||
|
width: 39,
|
||||||
|
height: 39,
|
||||||
|
display: "flex",
|
||||||
|
justifyContent: "center",
|
||||||
|
alignItems: "center",
|
||||||
|
position: "relative"
|
||||||
|
};
|
||||||
|
|
||||||
|
function IconButton({
|
||||||
|
onPress,
|
||||||
|
children,
|
||||||
|
fwdRef,
|
||||||
|
style = {},
|
||||||
|
preventDefault = false
|
||||||
|
}: {
|
||||||
|
onPress?: () => void;
|
||||||
|
children: React.ReactNode;
|
||||||
|
fwdRef?: any;
|
||||||
|
style?: React.CSSProperties;
|
||||||
|
preventDefault?: boolean;
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
onPress={onPress}
|
||||||
|
fwdRef={fwdRef}
|
||||||
|
preventDefault={preventDefault}
|
||||||
|
style={{ ...iconButtonStyle, ...style }}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const Button = ({
|
const Button = ({
|
||||||
onPress,
|
onPress,
|
||||||
children,
|
children,
|
||||||
@@ -120,7 +157,8 @@ function Header({
|
|||||||
backgroundColor: "var(--nn_primary_background)",
|
backgroundColor: "var(--nn_primary_background)",
|
||||||
position: "sticky",
|
position: "sticky",
|
||||||
width: "100vw",
|
width: "100vw",
|
||||||
zIndex: 999
|
zIndex: 999,
|
||||||
|
borderBottom: "0.5px solid var(--nn_primary_separator)"
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{noHeader ? null : (
|
{noHeader ? null : (
|
||||||
@@ -132,51 +170,39 @@ function Header({
|
|||||||
flexDirection: "row",
|
flexDirection: "row",
|
||||||
paddingTop: insets.top,
|
paddingTop: insets.top,
|
||||||
height: 50,
|
height: 50,
|
||||||
alignItems: "center"
|
alignItems: "center",
|
||||||
|
paddingLeft: 12,
|
||||||
|
paddingRight: 16
|
||||||
}}
|
}}
|
||||||
id="header"
|
id="header"
|
||||||
>
|
>
|
||||||
{settings.deviceMode !== "mobile" && !settings.fullscreen ? (
|
{settings.deviceMode !== "mobile" && !settings.fullscreen ? (
|
||||||
<div />
|
<div />
|
||||||
) : (
|
) : (
|
||||||
<Button
|
<IconButton
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
post(EditorEvents.back, undefined, tab.id, tab.session?.noteId);
|
post(EditorEvents.back, undefined, tab.id, tab.session?.noteId);
|
||||||
}}
|
}}
|
||||||
preventDefault={false}
|
style={{ width: 40, height: 40 }}
|
||||||
style={{
|
|
||||||
borderWidth: 0,
|
|
||||||
borderRadius: 100,
|
|
||||||
color: "var(--nn_primary_icon)",
|
|
||||||
marginLeft: 6,
|
|
||||||
width: 40,
|
|
||||||
height: 40,
|
|
||||||
display: "flex",
|
|
||||||
justifyContent: "center",
|
|
||||||
alignItems: "center",
|
|
||||||
flexDirection: "column",
|
|
||||||
position: "relative"
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<ArrowBackIcon
|
<ArrowBackIcon
|
||||||
size={28 * settings.fontScale}
|
size={25 * settings.fontScale}
|
||||||
style={{
|
style={{ position: "absolute" }}
|
||||||
position: "absolute"
|
|
||||||
}}
|
|
||||||
color="var(--nn_primary_icon)"
|
color="var(--nn_primary_icon)"
|
||||||
/>
|
/>
|
||||||
</Button>
|
</IconButton>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
flexDirection: "row"
|
flexDirection: "row",
|
||||||
|
gap: 8
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{settings.deviceMode !== "mobile" && !settings.fullscreen ? (
|
{settings.deviceMode !== "mobile" && !settings.fullscreen ? (
|
||||||
<Button
|
<IconButton
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
post(
|
post(
|
||||||
EditorEvents.fullscreen,
|
EditorEvents.fullscreen,
|
||||||
@@ -185,32 +211,17 @@ function Header({
|
|||||||
tab.session?.noteId
|
tab.session?.noteId
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
preventDefault={false}
|
|
||||||
style={{
|
|
||||||
borderWidth: 0,
|
|
||||||
borderRadius: 100,
|
|
||||||
color: "var(--nn_primary_icon)",
|
|
||||||
marginRight: 10,
|
|
||||||
width: 39,
|
|
||||||
height: 39,
|
|
||||||
display: "flex",
|
|
||||||
justifyContent: "center",
|
|
||||||
alignItems: "center",
|
|
||||||
position: "relative"
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<FullscreenIcon
|
<FullscreenIcon
|
||||||
size={25 * settings.fontScale}
|
size={25 * settings.fontScale}
|
||||||
style={{
|
style={{ position: "absolute" }}
|
||||||
position: "absolute"
|
|
||||||
}}
|
|
||||||
color="var(--nn_primary_icon)"
|
color="var(--nn_primary_icon)"
|
||||||
/>
|
/>
|
||||||
</Button>
|
</IconButton>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
{tab.session?.readonly ? (
|
{tab.session?.readonly ? (
|
||||||
<Button
|
<IconButton
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
post(
|
post(
|
||||||
"editor-events:disable-readonly-mode",
|
"editor-events:disable-readonly-mode",
|
||||||
@@ -218,46 +229,20 @@ function Header({
|
|||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
fwdRef={btnRef}
|
fwdRef={btnRef}
|
||||||
preventDefault={false}
|
style={{ color: "var(--nn_primary_accent)" }}
|
||||||
style={{
|
|
||||||
borderWidth: 0,
|
|
||||||
borderRadius: 100,
|
|
||||||
color: "var(--nn_primary_accent)",
|
|
||||||
marginRight: 12,
|
|
||||||
width: 39,
|
|
||||||
height: 39,
|
|
||||||
display: "flex",
|
|
||||||
justifyContent: "center",
|
|
||||||
alignItems: "center",
|
|
||||||
position: "relative"
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<PencilLockIcon
|
<PencilLockIcon
|
||||||
size={25 * settings.fontScale}
|
size={25 * settings.fontScale}
|
||||||
style={{
|
style={{ position: "absolute" }}
|
||||||
position: "absolute"
|
|
||||||
}}
|
|
||||||
color="var(--nn_primary_accent)"
|
color="var(--nn_primary_accent)"
|
||||||
/>
|
/>
|
||||||
</Button>
|
</IconButton>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
<Button
|
<IconButton
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
editor?.commands.undo();
|
editor?.commands.undo();
|
||||||
}}
|
}}
|
||||||
style={{
|
|
||||||
borderWidth: 0,
|
|
||||||
borderRadius: 100,
|
|
||||||
color: "var(--nn_primary_icon)",
|
|
||||||
marginRight: 10,
|
|
||||||
width: 39,
|
|
||||||
height: 39,
|
|
||||||
display: "flex",
|
|
||||||
justifyContent: "center",
|
|
||||||
alignItems: "center",
|
|
||||||
position: "relative"
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<ArrowULeftTopIcon
|
<ArrowULeftTopIcon
|
||||||
color={
|
color={
|
||||||
@@ -266,28 +251,14 @@ function Header({
|
|||||||
: "var(--nn_primary_icon)"
|
: "var(--nn_primary_icon)"
|
||||||
}
|
}
|
||||||
size={25 * settings.fontScale}
|
size={25 * settings.fontScale}
|
||||||
style={{
|
style={{ position: "absolute" }}
|
||||||
position: "absolute"
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
</Button>
|
</IconButton>
|
||||||
|
|
||||||
<Button
|
<IconButton
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
editor?.commands.redo();
|
editor?.commands.redo();
|
||||||
}}
|
}}
|
||||||
style={{
|
|
||||||
borderWidth: 0,
|
|
||||||
borderRadius: 100,
|
|
||||||
color: "var(--nn_primary_icon)",
|
|
||||||
marginRight: 10,
|
|
||||||
width: 39,
|
|
||||||
height: 39,
|
|
||||||
display: "flex",
|
|
||||||
justifyContent: "center",
|
|
||||||
alignItems: "center",
|
|
||||||
position: "relative"
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<ArrowURightTopIcon
|
<ArrowURightTopIcon
|
||||||
color={
|
color={
|
||||||
@@ -296,13 +267,11 @@ function Header({
|
|||||||
: "var(--nn_primary_icon)"
|
: "var(--nn_primary_icon)"
|
||||||
}
|
}
|
||||||
size={25 * settings.fontScale}
|
size={25 * settings.fontScale}
|
||||||
style={{
|
style={{ position: "absolute" }}
|
||||||
position: "absolute"
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
</Button>
|
</IconButton>
|
||||||
|
|
||||||
<Button
|
<IconButton
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
post(
|
post(
|
||||||
EditorEvents.showTabs,
|
EditorEvents.showTabs,
|
||||||
@@ -311,26 +280,13 @@ function Header({
|
|||||||
tab.session?.noteId
|
tab.session?.noteId
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
preventDefault={false}
|
|
||||||
style={{
|
|
||||||
borderWidth: 0,
|
|
||||||
borderRadius: 100,
|
|
||||||
color: "var(--nn_primary_icon)",
|
|
||||||
marginRight: 12,
|
|
||||||
width: 39,
|
|
||||||
height: 39,
|
|
||||||
display: "flex",
|
|
||||||
justifyContent: "center",
|
|
||||||
alignItems: "center",
|
|
||||||
position: "relative"
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
border: "2px solid var(--nn_primary_icon)",
|
border: "2px solid var(--nn_primary_icon)",
|
||||||
width: 19 * settings.fontScale,
|
width: 17 * settings.fontScale,
|
||||||
height: 19 * settings.fontScale,
|
height: 17 * settings.fontScale,
|
||||||
minWidth: 19 * settings.fontScale,
|
minWidth: 17 * settings.fontScale,
|
||||||
borderRadius: 5,
|
borderRadius: 5,
|
||||||
display: "flex",
|
display: "flex",
|
||||||
justifyContent: "center",
|
justifyContent: "center",
|
||||||
@@ -348,9 +304,9 @@ function Header({
|
|||||||
{openedTabsCount}
|
{openedTabsCount}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</Button>
|
</IconButton>
|
||||||
|
|
||||||
<Button
|
<IconButton
|
||||||
fwdRef={btnRef}
|
fwdRef={btnRef}
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
if (tab.session?.locked) {
|
if (tab.session?.locked) {
|
||||||
@@ -364,38 +320,21 @@ function Header({
|
|||||||
setOpen(!isOpen);
|
setOpen(!isOpen);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
preventDefault={false}
|
|
||||||
style={{
|
|
||||||
borderWidth: 0,
|
|
||||||
borderRadius: 100,
|
|
||||||
color: "var(--nn_primary_icon)",
|
|
||||||
marginRight: 12,
|
|
||||||
width: 39,
|
|
||||||
height: 39,
|
|
||||||
display: "flex",
|
|
||||||
justifyContent: "center",
|
|
||||||
alignItems: "center",
|
|
||||||
position: "relative"
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
{tab.session?.locked ? (
|
{tab.session?.locked ? (
|
||||||
<DotsHorizontalIcon
|
<DotsHorizontalIcon
|
||||||
size={25 * settings.fontScale}
|
size={25 * settings.fontScale}
|
||||||
style={{
|
style={{ position: "absolute" }}
|
||||||
position: "absolute"
|
|
||||||
}}
|
|
||||||
color="var(--nn_primary_icon)"
|
color="var(--nn_primary_icon)"
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<DotsVerticalIcon
|
<DotsVerticalIcon
|
||||||
size={25 * settings.fontScale}
|
size={25 * settings.fontScale}
|
||||||
style={{
|
style={{ position: "absolute" }}
|
||||||
position: "absolute"
|
|
||||||
}}
|
|
||||||
color="var(--nn_primary_icon)"
|
color="var(--nn_primary_icon)"
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</Button>
|
</IconButton>
|
||||||
|
|
||||||
<ControlledMenu
|
<ControlledMenu
|
||||||
align="end"
|
align="end"
|
||||||
@@ -470,7 +409,7 @@ function Header({
|
|||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
gap: 10,
|
gap: 8,
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
flexDirection: "row",
|
flexDirection: "row",
|
||||||
justifyContent: "center",
|
justifyContent: "center",
|
||||||
@@ -478,7 +417,7 @@ function Header({
|
|||||||
paddingTop: 5
|
paddingTop: 5
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Button
|
<IconButton
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
post(
|
post(
|
||||||
EditorEvents.goBack,
|
EditorEvents.goBack,
|
||||||
@@ -488,17 +427,6 @@ function Header({
|
|||||||
);
|
);
|
||||||
setOpen(false);
|
setOpen(false);
|
||||||
}}
|
}}
|
||||||
style={{
|
|
||||||
borderWidth: 0,
|
|
||||||
borderRadius: 100,
|
|
||||||
color: "var(--nn_primary_icon)",
|
|
||||||
width: 39,
|
|
||||||
height: 39,
|
|
||||||
display: "flex",
|
|
||||||
justifyContent: "center",
|
|
||||||
alignItems: "center",
|
|
||||||
position: "relative"
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<ArrowBackIcon
|
<ArrowBackIcon
|
||||||
color={
|
color={
|
||||||
@@ -507,13 +435,11 @@ function Header({
|
|||||||
: "var(--nn_primary_icon)"
|
: "var(--nn_primary_icon)"
|
||||||
}
|
}
|
||||||
size={25 * settings.fontScale}
|
size={25 * settings.fontScale}
|
||||||
style={{
|
style={{ position: "absolute" }}
|
||||||
position: "absolute"
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
</Button>
|
</IconButton>
|
||||||
|
|
||||||
<Button
|
<IconButton
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
post(
|
post(
|
||||||
EditorEvents.goForward,
|
EditorEvents.goForward,
|
||||||
@@ -523,17 +449,6 @@ function Header({
|
|||||||
);
|
);
|
||||||
setOpen(false);
|
setOpen(false);
|
||||||
}}
|
}}
|
||||||
style={{
|
|
||||||
borderWidth: 0,
|
|
||||||
borderRadius: 100,
|
|
||||||
color: "var(--nn_primary_icon)",
|
|
||||||
width: 39,
|
|
||||||
height: 39,
|
|
||||||
display: "flex",
|
|
||||||
justifyContent: "center",
|
|
||||||
alignItems: "center",
|
|
||||||
position: "relative"
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<ArrowForwardIcon
|
<ArrowForwardIcon
|
||||||
color={
|
color={
|
||||||
@@ -542,37 +457,22 @@ function Header({
|
|||||||
: "var(--nn_primary_icon)"
|
: "var(--nn_primary_icon)"
|
||||||
}
|
}
|
||||||
size={25 * settings.fontScale}
|
size={25 * settings.fontScale}
|
||||||
style={{
|
style={{ position: "absolute" }}
|
||||||
position: "absolute"
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
</Button>
|
</IconButton>
|
||||||
|
|
||||||
<Button
|
<IconButton
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
editor?.commands.startSearch();
|
editor?.commands.startSearch();
|
||||||
setOpen(false);
|
setOpen(false);
|
||||||
}}
|
}}
|
||||||
style={{
|
|
||||||
borderWidth: 0,
|
|
||||||
borderRadius: 100,
|
|
||||||
color: "var(--nn_primary_icon)",
|
|
||||||
width: 39,
|
|
||||||
height: 39,
|
|
||||||
display: "flex",
|
|
||||||
justifyContent: "center",
|
|
||||||
alignItems: "center",
|
|
||||||
position: "relative"
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<MagnifyIcon
|
<MagnifyIcon
|
||||||
size={28 * settings.fontScale}
|
size={25 * settings.fontScale}
|
||||||
style={{
|
style={{ position: "absolute" }}
|
||||||
position: "absolute"
|
|
||||||
}}
|
|
||||||
color="var(--nn_primary_icon)"
|
color="var(--nn_primary_icon)"
|
||||||
/>
|
/>
|
||||||
</Button>
|
</IconButton>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<MenuItem
|
<MenuItem
|
||||||
@@ -584,7 +484,7 @@ function Header({
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<PlusIcon
|
<PlusIcon
|
||||||
size={22 * settings.fontScale}
|
size={20 * settings.fontScale}
|
||||||
color="var(--nn_primary_icon)"
|
color="var(--nn_primary_icon)"
|
||||||
/>
|
/>
|
||||||
<span
|
<span
|
||||||
@@ -605,7 +505,7 @@ function Header({
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<TableOfContentsIcon
|
<TableOfContentsIcon
|
||||||
size={22 * settings.fontScale}
|
size={20 * settings.fontScale}
|
||||||
color="var(--nn_primary_icon)"
|
color="var(--nn_primary_icon)"
|
||||||
/>
|
/>
|
||||||
<span
|
<span
|
||||||
@@ -625,7 +525,7 @@ function Header({
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<ArrowTopIcon
|
<ArrowTopIcon
|
||||||
size={22 * settings.fontScale}
|
size={20 * settings.fontScale}
|
||||||
color="var(--nn_primary_icon)"
|
color="var(--nn_primary_icon)"
|
||||||
/>
|
/>
|
||||||
<span
|
<span
|
||||||
@@ -646,7 +546,7 @@ function Header({
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<ArrowDownIcon
|
<ArrowDownIcon
|
||||||
size={22 * settings.fontScale}
|
size={20 * settings.fontScale}
|
||||||
color="var(--nn_primary_icon)"
|
color="var(--nn_primary_icon)"
|
||||||
/>
|
/>
|
||||||
<span
|
<span
|
||||||
@@ -666,7 +566,7 @@ function Header({
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<DotsHorizontalIcon
|
<DotsHorizontalIcon
|
||||||
size={22 * settings.fontScale}
|
size={20 * settings.fontScale}
|
||||||
color="var(--nn_primary_icon)"
|
color="var(--nn_primary_icon)"
|
||||||
/>
|
/>
|
||||||
<span
|
<span
|
||||||
|
|||||||
@@ -29,19 +29,13 @@ function StatusBar({
|
|||||||
container: RefObject<HTMLDivElement>;
|
container: RefObject<HTMLDivElement>;
|
||||||
loading?: boolean;
|
loading?: boolean;
|
||||||
}) {
|
}) {
|
||||||
const [status, setStatus] = useState({
|
|
||||||
date: "",
|
|
||||||
saved: ""
|
|
||||||
});
|
|
||||||
const tab = useTabContext();
|
const tab = useTabContext();
|
||||||
const [sticky, setSticky] = useState(false);
|
const [showChars, setShowChars] = useState(false);
|
||||||
const stickyRef = useRef(false);
|
|
||||||
const prevScroll = useRef(0);
|
|
||||||
const lastStickyChangeTime = useRef(0);
|
|
||||||
const [words, setWords] = useState(strings.totalWords(0));
|
const [words, setWords] = useState(strings.totalWords(0));
|
||||||
const currentWords = useRef(words);
|
const currentWords = useRef(words);
|
||||||
|
const [chars, setChars] = useState(0);
|
||||||
const statusBar = useRef({
|
const statusBar = useRef({
|
||||||
set: setStatus,
|
set: () => {},
|
||||||
updateWords: () => {
|
updateWords: () => {
|
||||||
const editor = editors[tab.id];
|
const editor = editors[tab.id];
|
||||||
if (!editor) return;
|
if (!editor) return;
|
||||||
@@ -57,110 +51,44 @@ function StatusBar({
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
globalThis.statusBars[tab.id] = statusBar;
|
globalThis.statusBars[tab.id] = statusBar;
|
||||||
|
if (showChars) {
|
||||||
|
editors[tab.id]?.on("selectionUpdate", (event) => {
|
||||||
|
setChars(event.editor.extensionStorage.characterCount.characters());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (editors[tab.id]) {
|
||||||
|
setChars(
|
||||||
|
editors[tab.id]?.extensionStorage.characterCount.characters() || 0
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
globalThis.statusBars[tab.id] = undefined;
|
globalThis.statusBars[tab.id] = undefined;
|
||||||
};
|
};
|
||||||
}, [tab.id, statusBar]);
|
}, [tab.id, statusBar, showChars]);
|
||||||
|
|
||||||
const scrollState = useRef({
|
|
||||||
isMovingUp: false,
|
|
||||||
startingOffset: 0
|
|
||||||
});
|
|
||||||
const onScroll = React.useCallback((event: Event) => {
|
|
||||||
const currentOffset = (event.target as HTMLElement)?.scrollTop;
|
|
||||||
if (currentOffset < 200) {
|
|
||||||
if (stickyRef.current) {
|
|
||||||
stickyRef.current = false;
|
|
||||||
setSticky(false);
|
|
||||||
lastStickyChangeTime.current = Date.now();
|
|
||||||
prevScroll.current = currentOffset;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (Date.now() - lastStickyChangeTime.current < 300) return;
|
|
||||||
if (currentOffset > prevScroll.current) {
|
|
||||||
if (
|
|
||||||
!scrollState.current.startingOffset ||
|
|
||||||
scrollState.current.isMovingUp
|
|
||||||
) {
|
|
||||||
scrollState.current.startingOffset = currentOffset;
|
|
||||||
}
|
|
||||||
scrollState.current.isMovingUp = false;
|
|
||||||
} else {
|
|
||||||
if (
|
|
||||||
!scrollState.current.startingOffset ||
|
|
||||||
!scrollState.current.isMovingUp
|
|
||||||
) {
|
|
||||||
scrollState.current.startingOffset = currentOffset;
|
|
||||||
}
|
|
||||||
scrollState.current.isMovingUp = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (scrollState.current.isMovingUp) {
|
|
||||||
if (currentOffset < scrollState.current.startingOffset - 50) {
|
|
||||||
if (!stickyRef.current) {
|
|
||||||
stickyRef.current = true;
|
|
||||||
setSticky(true);
|
|
||||||
}
|
|
||||||
scrollState.current.startingOffset = 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (currentOffset > scrollState.current.startingOffset + 50) {
|
|
||||||
if (stickyRef.current) {
|
|
||||||
stickyRef.current = false;
|
|
||||||
setSticky(false);
|
|
||||||
}
|
|
||||||
scrollState.current.startingOffset = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lastStickyChangeTime.current = Date.now();
|
|
||||||
prevScroll.current = currentOffset;
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
currentWords.current = words;
|
currentWords.current = words;
|
||||||
}, [words]);
|
}, [words]);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const node = container.current;
|
|
||||||
node?.addEventListener("scroll", onScroll);
|
|
||||||
return () => {
|
|
||||||
node?.removeEventListener("scroll", onScroll);
|
|
||||||
};
|
|
||||||
}, [onScroll, container]);
|
|
||||||
|
|
||||||
const paragraphStyle: React.CSSProperties = {
|
const paragraphStyle: React.CSSProperties = {
|
||||||
marginTop: 0,
|
marginTop: 0,
|
||||||
marginBottom: 0,
|
marginBottom: 0,
|
||||||
fontSize: "12px",
|
fontSize: 12,
|
||||||
color: "var(--nn_secondary_paragraph)",
|
color: "var(--nn_secondary_paragraph)",
|
||||||
marginRight: 8,
|
|
||||||
paddingBottom: 0,
|
paddingBottom: 0,
|
||||||
userSelect: "none",
|
userSelect: "none"
|
||||||
pointerEvents: "none"
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<p
|
||||||
style={{
|
onMouseDown={(e) => {
|
||||||
flexDirection: "row",
|
setShowChars(!showChars);
|
||||||
display: loading ? "none" : "flex",
|
|
||||||
paddingRight: 12,
|
|
||||||
paddingLeft: 12,
|
|
||||||
position: sticky ? "sticky" : "relative",
|
|
||||||
top: -3,
|
|
||||||
backgroundColor: "var(--nn_primary_background)",
|
|
||||||
zIndex: 10,
|
|
||||||
justifyContent: sticky ? "center" : "flex-start",
|
|
||||||
paddingTop: 4,
|
|
||||||
paddingBottom: 2
|
|
||||||
}}
|
}}
|
||||||
id="statusbar"
|
style={paragraphStyle}
|
||||||
>
|
>
|
||||||
<p style={paragraphStyle}>{words}</p>
|
{showChars ? strings.characters(chars) : words}
|
||||||
<p style={paragraphStyle}>{status.date}</p>
|
</p>
|
||||||
<p style={paragraphStyle}>{status.saved}</p>
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -50,14 +50,15 @@
|
|||||||
z-index: 999;
|
z-index: 999;
|
||||||
list-style: none;
|
list-style: none;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
padding: 0px;
|
|
||||||
font-family: sans-serif;
|
font-family: sans-serif;
|
||||||
font-size: 0.95em;
|
font-size: 0.95em;
|
||||||
border: 1px solid var(--nn_primary_border);
|
border: 1px solid var(--nn_primary_border);
|
||||||
box-shadow: 1px 1px 20px 1px rgba(0, 0, 0, 0.1);
|
box-shadow: 1px 1px 20px 1px rgba(0, 0, 0, 0.1);
|
||||||
border-radius: 6px;
|
border-radius: 8px;
|
||||||
background-color: var(--nn_secondary_background);
|
background-color: var(--nn_secondary_background);
|
||||||
min-width: 12rem;
|
min-width: 13rem;
|
||||||
|
padding: 0 !important;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.menuOpening {
|
.menuOpening {
|
||||||
@@ -73,10 +74,11 @@
|
|||||||
.menuItem {
|
.menuItem {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
padding: 1rem 0.6rem !important;
|
padding: 0.5rem 0.6rem !important;
|
||||||
color: var(--nn_primary_paragraph);
|
color: var(--nn_primary_paragraph);
|
||||||
font-family: "Inter";
|
font-family: "Inter";
|
||||||
padding: 12px 6px;
|
font-size: 0.9em;
|
||||||
|
flex-wrap: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.menuItemHover {
|
.menuItemHover {
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ import { Settings } from "../utils";
|
|||||||
import { EditorEvents } from "../utils/editor-events";
|
import { EditorEvents } from "../utils/editor-events";
|
||||||
import styles from "./styles.module.css";
|
import styles from "./styles.module.css";
|
||||||
import { useTabContext } from "../hooks/useTabStore";
|
import { useTabContext } from "../hooks/useTabStore";
|
||||||
import { strings } from "@notesnook/intl";
|
|
||||||
|
|
||||||
function Tags(props: { settings: Settings; loading?: boolean }): JSX.Element {
|
function Tags(props: { settings: Settings; loading?: boolean }): JSX.Element {
|
||||||
const [tags, setTags] = useState<
|
const [tags, setTags] = useState<
|
||||||
@@ -54,80 +53,32 @@ function Tags(props: { settings: Settings; loading?: boolean }): JSX.Element {
|
|||||||
<div
|
<div
|
||||||
className={styles.container}
|
className={styles.container}
|
||||||
style={{
|
style={{
|
||||||
padding: "0px 12px",
|
|
||||||
display: "flex",
|
display: "flex",
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
overflowX: "scroll",
|
overflowX: "scroll",
|
||||||
minHeight: "40px",
|
minHeight: "40px",
|
||||||
opacity: props.loading ? 0 : 1
|
opacity: props.loading ? 0 : 1,
|
||||||
|
gap: 6
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<button
|
|
||||||
className={styles.btn}
|
|
||||||
onClick={(e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
openManageTagsSheet();
|
|
||||||
}}
|
|
||||||
style={{
|
|
||||||
border: `1px solid var(--nn_primary_border)`,
|
|
||||||
backgroundColor: "var(--nn_secondary_background)",
|
|
||||||
marginRight: 5,
|
|
||||||
borderRadius: 100,
|
|
||||||
padding: "0px 10px",
|
|
||||||
fontFamily: "Inter",
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
height: "30px",
|
|
||||||
userSelect: "none",
|
|
||||||
WebkitUserSelect: "none"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{tags.length === 0 ? (
|
|
||||||
<p
|
|
||||||
style={{
|
|
||||||
marginRight: 4,
|
|
||||||
fontSize: 13,
|
|
||||||
color: "var(--nn_primary_icon)",
|
|
||||||
userSelect: "none"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{strings.addATag()}
|
|
||||||
</p>
|
|
||||||
) : null}
|
|
||||||
<svg
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
version="1.1"
|
|
||||||
width={20 * fontScale}
|
|
||||||
height={20 * fontScale}
|
|
||||||
viewBox={`0 0 24 24`}
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
fill="var(--nn_primary_accent)"
|
|
||||||
d="M19,13H13V19H11V13H5V11H11V5H13V11H19V13Z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
{tags.map((tag) => (
|
{tags.map((tag) => (
|
||||||
<button
|
<button
|
||||||
key={tag.title}
|
key={tag.title}
|
||||||
className={styles.btn}
|
|
||||||
style={{
|
style={{
|
||||||
border: "1px solid var(--nn_primary_border)",
|
border: "1px solid var(--nn_primary_border)",
|
||||||
backgroundColor: "var(--nn_secondary_background)",
|
backgroundColor: "var(--nn_secondary_background)",
|
||||||
marginRight: 5,
|
borderRadius: 6,
|
||||||
borderRadius: 100,
|
padding: "0px 4px",
|
||||||
padding: "0px 10px",
|
height: "24px",
|
||||||
height: "30px",
|
|
||||||
fontFamily: "Inter",
|
fontFamily: "Inter",
|
||||||
fontSize: 13,
|
fontSize: 12,
|
||||||
color: "var(--nn_primary_icon)",
|
color: "var(--nn_primary_icon)",
|
||||||
userSelect: "none",
|
userSelect: "none",
|
||||||
WebkitUserSelect: "none"
|
WebkitUserSelect: "none"
|
||||||
}}
|
}}
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
post(EditorEvents.tag, tag, tab.id, tab.session?.noteId);
|
openManageTagsSheet();
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
#{tag.alias}
|
#{tag.alias}
|
||||||
|
|||||||
@@ -49,9 +49,9 @@ function Title({
|
|||||||
if (!titleSizeDiv.current || !titleRef.current) return;
|
if (!titleSizeDiv.current || !titleRef.current) return;
|
||||||
titleSizeDiv.current.innerText = titleRef.current.value;
|
titleSizeDiv.current.innerText = titleRef.current.value;
|
||||||
titleRef.current.style.height = `${titleSizeDiv.current.clientHeight}px`;
|
titleRef.current.style.height = `${titleSizeDiv.current.clientHeight}px`;
|
||||||
|
titleRef.current.style.minHeight = `${titleSizeDiv.current.clientHeight}px`;
|
||||||
titleSizeDiv.current.style.width = `${titleRef.current.clientWidth}px`;
|
titleSizeDiv.current.style.width = `${titleRef.current.clientWidth}px`;
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (titleRef.current) {
|
if (titleRef.current) {
|
||||||
titleRef.current.value = title;
|
titleRef.current.value = title;
|
||||||
@@ -88,8 +88,8 @@ function Title({
|
|||||||
maxWidth: "100%",
|
maxWidth: "100%",
|
||||||
minHeight: 40,
|
minHeight: 40,
|
||||||
opacity: 0,
|
opacity: 0,
|
||||||
paddingRight: 10,
|
paddingRight: 16,
|
||||||
paddingLeft: 10,
|
paddingLeft: 16,
|
||||||
fontWeight: 600,
|
fontWeight: 600,
|
||||||
fontFamily: getFontById(fontFamily)?.font || "Inter",
|
fontFamily: getFontById(fontFamily)?.font || "Inter",
|
||||||
boxSizing: "border-box",
|
boxSizing: "border-box",
|
||||||
@@ -119,8 +119,8 @@ function Title({
|
|||||||
boxSizing: "border-box",
|
boxSizing: "border-box",
|
||||||
border: 0,
|
border: 0,
|
||||||
opacity: 1,
|
opacity: 1,
|
||||||
paddingRight: 10,
|
paddingRight: 16,
|
||||||
paddingLeft: 10,
|
paddingLeft: 16,
|
||||||
fontWeight: 600,
|
fontWeight: 600,
|
||||||
fontFamily: getFontById(fontFamily)?.font || "Inter",
|
fontFamily: getFontById(fontFamily)?.font || "Inter",
|
||||||
backgroundColor: "transparent",
|
backgroundColor: "transparent",
|
||||||
|
|||||||
@@ -491,6 +491,10 @@ msgstr "{count, plural, one {Unpublish item} other {Unpublish # items}}"
|
|||||||
msgid "{count, plural, one {Unpublish note} other {Unpublish # notes}}"
|
msgid "{count, plural, one {Unpublish note} other {Unpublish # notes}}"
|
||||||
msgstr "{count, plural, one {Unpublish note} other {Unpublish # notes}}"
|
msgstr "{count, plural, one {Unpublish note} other {Unpublish # notes}}"
|
||||||
|
|
||||||
|
#: src/strings.ts:2492
|
||||||
|
msgid "{count} characters"
|
||||||
|
msgstr "{count} characters"
|
||||||
|
|
||||||
#: src/strings.ts:1563
|
#: src/strings.ts:1563
|
||||||
msgid "{days, plural, one {1 day} other {# days}}"
|
msgid "{days, plural, one {1 day} other {# days}}"
|
||||||
msgstr "{days, plural, one {1 day} other {# days}}"
|
msgstr "{days, plural, one {1 day} other {# days}}"
|
||||||
|
|||||||
@@ -491,6 +491,10 @@ msgstr ""
|
|||||||
msgid "{count, plural, one {Unpublish note} other {Unpublish # notes}}"
|
msgid "{count, plural, one {Unpublish note} other {Unpublish # notes}}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/strings.ts:2492
|
||||||
|
msgid "{count} characters"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/strings.ts:1563
|
#: src/strings.ts:1563
|
||||||
msgid "{days, plural, one {1 day} other {# days}}"
|
msgid "{days, plural, one {1 day} other {# days}}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|||||||
@@ -2488,5 +2488,6 @@ Use this if changes from other devices are not appearing on this device. This wi
|
|||||||
t`Select a notebook to move this notebook into, or unselect to move it to the root level.`,
|
t`Select a notebook to move this notebook into, or unselect to move it to the root level.`,
|
||||||
noNotebooksSelectedToMove: () => t`No notebooks selected to move`,
|
noNotebooksSelectedToMove: () => t`No notebooks selected to move`,
|
||||||
scrollToTop: () => t`Scroll to top`,
|
scrollToTop: () => t`Scroll to top`,
|
||||||
scrollToBottom: () => t`Scroll to bottom`
|
scrollToBottom: () => t`Scroll to bottom`,
|
||||||
|
characters: (count: number) => t`${count} characters`
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user