mobile: push ui updates

This commit is contained in:
Ammar Ahmed
2026-06-29 11:27:03 +05:00
parent beb28d027c
commit 836bb1ea0a
47 changed files with 3818 additions and 3260 deletions

View File

@@ -17,7 +17,7 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import { KeyboardTypeOptions, TextInput } from "react-native";
import { KeyboardTypeOptions, TextInput, TextInputProps } from "react-native";
import { eSendEvent } from "../../services/event-manager";
import { eCloseSimpleDialog, eOpenSimpleDialog } from "../../utils/events";
import { ButtonProps } from "../ui/button";
@@ -58,6 +58,7 @@ export type DialogInfo = {
validators: FieldValidator[];
defaultValue?: string;
ref: RefObject<TextInput | null>;
inputProps?: TextInputProps;
}[];
onFormSubmit?: (form: FormRef) => Promise<boolean>;
};

View File

@@ -39,7 +39,7 @@ import { defaultBorderRadius } from "../../utils/size";
import { DefaultAppStyles } from "../../utils/styles";
import { sleep } from "../../utils/time";
import { Toast } from "../toast";
import { Button } from "../ui/button";
import { Checkbox } from "../ui/checkbox";
import Input from "../ui/input";
import { FormInput, type FormRef } from "../ui/input/form-input";
import { Notice } from "../ui/notice";
@@ -233,6 +233,7 @@ export const Dialog = ({ context = "global" }: { context?: string }) => {
>
{dialogInfo.form.items.map((item, index) => (
<FormInput
{...item.inputProps}
key={item.name}
fwdRef={item.ref}
name={item.name}
@@ -289,29 +290,16 @@ export const Dialog = ({ context = "global" }: { context?: string }) => {
) : null}
{dialogInfo.check ? (
<>
<Button
onPress={() => {
setChecked(!checked);
}}
icon={
checked
? "check-circle-outline"
: "checkbox-blank-circle-outline"
}
iconColor={
checked ? colors.secondary.icon : colors.primary.icon
}
style={{
justifyContent: "flex-start"
}}
height={35}
iconSize={20}
width="100%"
title={dialogInfo.check.info}
type={checked ? dialogInfo.check.type || "plain" : "plain"}
/>
</>
<Checkbox
checked={checked}
onPress={() => {
setChecked(!checked);
}}
title={dialogInfo.check.info}
style={{
marginTop: -Spacing.LEVEL_1
}}
/>
) : null}
</View>
<DialogButtons

View File

@@ -107,7 +107,6 @@ export const Header = ({
<View
style={{
paddingHorizontal: DefaultAppStyles.GAP,
marginBottom: Spacing.LEVEL_3,
marginTop: Platform.OS === "android" ? 5 : 0
}}
>

View File

@@ -71,6 +71,7 @@ export const SearchResult = (props: SearchResultProps) => {
}}
onLongPress={async () => {
const note = await db.notes.note(props.item.id);
if (!note) return;
Properties.present(note);
}}
onPress={async () => openNote()}
@@ -151,6 +152,7 @@ export const SearchResult = (props: SearchResultProps) => {
}}
onLongPress={async () => {
const note = await db.notes.note(props.item.id);
if (!note) return;
Properties.present(note);
}}
onPress={() => {

View File

@@ -24,7 +24,6 @@ import { AppFontSize } from "../../utils/size";
import Paragraph from "../ui/typography/paragraph";
import { getFormattedDate } from "@notesnook/common";
import { strings } from "@notesnook/intl";
import { DefaultAppStyles } from "../../utils/styles";
import DateTimePickerModal from "react-native-modal-datetime-picker";
import { db } from "../../common/database";
import { Item, Note } from "@notesnook/core";
@@ -60,7 +59,11 @@ export const DateMeta = ({ item }: { item: Item }) => {
alignItems: "center"
}}
>
<View>
<View
style={{
gap: Spacing.LEVEL_0
}}
>
<Paragraph size={AppFontSize.xs} color={colors.secondary.paragraph}>
{strings.dateDescFromKey(
key as
@@ -73,7 +76,7 @@ export const DateMeta = ({ item }: { item: Item }) => {
</Paragraph>
<Paragraph
size={AppFontSize.xs}
color={colors.primary.paragraph}
color={colors.primary.heading}
fontFamily="MEDIUM"
onPress={
item.type !== "note"
@@ -127,9 +130,6 @@ export const DateMeta = ({ item }: { item: Item }) => {
<View
style={{
borderTopWidth: 1,
borderColor: colors.primary.border,
paddingVertical: Spacing.LEVEL_2,
flexDirection: "row",
gap: Spacing.LEVEL_2
}}

View File

@@ -20,7 +20,7 @@ import { strings } from "@notesnook/intl";
import { useThemeColors } from "@notesnook/theme";
import React, { useEffect, useState } from "react";
import { View } from "react-native";
import { FlatList } from "react-native-actions-sheet";
import { ScrollView } from "react-native-actions-sheet";
import { db } from "../../common/database";
import { DDS } from "../../services/device-detection";
import {
@@ -54,17 +54,53 @@ import Navigation from "../../services/navigation";
import { useIsFeatureAvailable } from "@notesnook/common";
import PaywallSheet from "../sheets/paywall";
import { useSettingStore } from "../../stores/use-setting-store";
import { Action, useActions } from "../../hooks/use-actions";
import {
Color,
Note,
Notebook,
Reminder,
Tag,
TrashItem
} from "@notesnook/core";
export const Properties = ({ close = () => {}, item, buttons = [] }) => {
export type PropertiesItem =
| Note
| Notebook
| Tag
| Color
| Reminder
| TrashItem;
export const Properties = ({
close,
item,
buttons = []
}: {
close?: (ctx?: string | undefined) => void;
item: PropertiesItem;
buttons: Action[];
}) => {
const { colors } = useThemeColors();
const colorFeature = useIsFeatureAvailable("colors");
const [noteNotebooks, setNoteNotebooks] = useState([]);
const [tags, setTags] = useState([]);
const [noteNotebooks, setNoteNotebooks] = useState<Notebook[]>([]);
const [tags, setTags] = useState<Tag[]>([]);
const [visible, setVisible] = useState(false);
const colorNotes = useMenuStore((state) => state.colorNotes);
const actions = useActions({
item,
close: () => {
close?.();
}
});
const editAction = actions.find(
(action) => action.id === "edit-notebook" || action.id === "rename-tag"
);
useEffect(() => {
async function getNotebooks() {
let filteredNotebooks = await db.relations.to(item, "notebook").resolve();
const filteredNotebooks = await db.relations
.to(item, "notebook")
.resolve();
return filteredNotebooks || [];
}
if (item.type === "note") {
@@ -87,7 +123,7 @@ export const Properties = ({ close = () => {}, item, buttons = [] }) => {
}
return (
<FlatList
<ScrollView
keyboardShouldPersistTaps="always"
keyboardDismissMode="none"
style={{
@@ -95,39 +131,39 @@ export const Properties = ({ close = () => {}, item, buttons = [] }) => {
borderBottomRightRadius: DDS.isLargeTablet() ? 10 : 1,
borderBottomLeftRadius: DDS.isLargeTablet() ? 10 : 1,
maxHeight: "100%",
paddingTop: Spacing.LEVEL_3
paddingTop: Spacing.LEVEL_2
}}
nestedScrollEnabled
bounces={false}
data={[0]}
keyExtractor={() => "properties-scroll-item"}
renderItem={() => (
>
<View>
{item.type === "note" ? (
<ColorPicker
visible={visible}
setVisible={setVisible}
onColorAdded={async (color) => {
await db.relations.to(item, "color").unlink();
await db.relations.add(color, item);
useRelationStore.getState().update();
useMenuStore.getState().setColorNotes();
Navigation.queueRoutesForUpdate();
sendItemUpdateEvent(color.id, "color");
eSendEvent(refreshNotesPage);
}}
/>
) : null}
<View
style={{
gap: Spacing.LEVEL_1
paddingHorizontal: Spacing.LEVEL_3
}}
>
{item.type === "note" ? (
<ColorPicker
visible={visible}
setVisible={setVisible}
onColorAdded={async (color) => {
await db.relations.to(item, "color").unlink();
await db.relations.add(color, item);
useRelationStore.getState().update();
useMenuStore.getState().setColorNotes();
Navigation.queueRoutesForUpdate();
sendItemUpdateEvent(color.id, "color");
eSendEvent(refreshNotesPage);
}}
/>
) : null}
<View
style={{
paddingHorizontal: Spacing.LEVEL_3
gap: Spacing.LEVEL_1,
paddingBottom: Spacing.LEVEL_3
}}
>
<View>
{item.type === "note" && (noteNotebooks.length || tags.length) ? (
<View
style={{
flexDirection: "row",
@@ -183,95 +219,101 @@ export const Properties = ({ close = () => {}, item, buttons = [] }) => {
) : null
)}
</View>
) : null}
<View
style={{
flexDirection: "row",
justifyContent: "space-between"
}}
>
<View
style={{
flexDirection: "row",
justifyContent: "space-between"
alignItems: "center",
flexShrink: 1,
gap: Spacing.LEVEL_1
}}
>
<View
style={{
flexDirection: "row",
alignItems: "center",
flexShrink: 1,
gap: Spacing.LEVEL_1
}}
>
{item.type === "color" ? (
<Pressable
type="accent"
accentColor={item.colorCode}
accentText={colors.static.white}
style={{
width: 8,
height: 8,
borderRadius: 100
}}
/>
) : item.type === "tag" ? (
<AppIcon
name="shopping-mode"
iconFamily="evilicons"
size={AppFontSize.lg}
color={colors.primary.icon}
/>
) : null}
{item.type === "color" ? (
<Pressable
type="accent"
accentColor={item.colorCode}
accentText={colors.static.white}
style={{
width: 8,
height: 8,
borderRadius: 100
}}
/>
) : null}
<Heading size={AppFontSize.xl}>{item.title}</Heading>
</View>
<Heading size={AppFontSize.xl}>{item.title}</Heading>
{item.type === "note" ? (
{editAction ? (
<IconButton
name="square-out"
name="edit-pencil"
iconFamily="notesnook"
type="plain"
color={colors.primary.icon}
size={AppFontSize.lg}
style={{
alignSelf: "flex-start"
}}
onPress={() => {
close();
eSendEvent(eOnLoadNote, {
item: item,
newTab: true
});
if (!DDS.isTab) {
fluidTabsRef.current?.goToPage("editor");
}
}}
size={AppFontSize.md}
onPress={editAction.onPress}
/>
) : null}
</View>
{(item.type === "notebook" || item.type === "reminder") &&
item.description ? (
<Paragraph>{item.description}</Paragraph>
) : null}
{item.type === "reminder" ? (
<ReminderTime
reminder={item}
{item.type === "note" ? (
<IconButton
name="square-out"
iconFamily="notesnook"
type="plain"
color={colors.primary.icon}
size={AppFontSize.lg}
style={{
justifyContent: "flex-start",
borderWidth: 0,
alignSelf: "flex-start",
backgroundColor: "transparent",
paddingHorizontal: 0,
paddingVertical: DefaultAppStyles.GAP_VERTICAL_SMALL
alignSelf: "flex-start"
}}
onPress={() => {
close?.();
eSendEvent(eOnLoadNote, {
item: item,
newTab: true
});
if (!DDS.isTab) {
fluidTabsRef.current?.goToPage("editor");
}
}}
fontSize={AppFontSize.xs}
/>
) : null}
</View>
<DateMeta item={item} />
{item.type === "note" && colorNotes.length > 0 ? (
<Tags close={close} item={item} />
{(item.type === "notebook" || item.type === "reminder") &&
item.description ? (
<Paragraph>{item.description}</Paragraph>
) : null}
{item.type === "reminder" ? (
<ReminderTime
reminder={item}
style={{
justifyContent: "flex-start",
borderWidth: 0,
alignSelf: "flex-start",
backgroundColor: "transparent",
paddingHorizontal: 0,
paddingVertical: DefaultAppStyles.GAP_VERTICAL_SMALL
}}
fontSize={AppFontSize.xs}
/>
) : null}
</View>
<DateMeta item={item} />
{item.type === "note" && colorNotes.length > 0 ? (
<Tags close={close} item={item} />
) : null}
{item.type === "note" ? (
<View
style={{
flexDirection: "row",
@@ -286,7 +328,7 @@ export const Properties = ({ close = () => {}, item, buttons = [] }) => {
<Button
onPress={async () => {
ManageTags.present([item.id]);
close();
close?.();
}}
buttonType={{
text: colors.primary.paragraph
@@ -333,37 +375,54 @@ export const Properties = ({ close = () => {}, item, buttons = [] }) => {
/>
)}
</View>
</View>
) : null}
</View>
{/* {item.type === "note" ? (
<Notebooks note={item} close={close} />
) : null} */}
<Items
item={item}
buttons={buttons}
close={() => {
close();
<View
style={{
paddingHorizontal: Spacing.LEVEL_3
}}
>
<View
style={{
marginVertical: Spacing.LEVEL_3,
width: "100%",
borderBottomWidth: 1,
borderColor: colors.primary.separator
}}
/>
{DDS.isTab ? (
<View
style={{
height: 20
}}
/>
) : null}
<SheetProvider context="properties" />
<Dialog context="properties" />
</View>
)}
/>
<Items
item={item}
buttons={buttons}
actions={actions}
close={() => {
close?.();
}}
/>
{DDS.isTab ? (
<View
style={{
height: 20
}}
/>
) : null}
<SheetProvider context="properties" />
<Dialog context="properties" />
</View>
</ScrollView>
);
};
Properties.present = async (item, isSheet, buttons = []) => {
Properties.present = async (
item: PropertiesItem,
isSheet: boolean = false,
buttons: Action[] = []
) => {
if (!item) return;
let type = item?.type;
const type = item?.type;
let dbItem;
switch (type) {
case "trash":
@@ -387,15 +446,12 @@ Properties.present = async (item, isSheet, buttons = []) => {
}
}
if (!dbItem) return;
presentSheet({
context: isSheet ? "local" : undefined,
component: (ref, close) => (
<Properties
close={close}
actionSheetRef={ref}
item={dbItem}
buttons={buttons}
/>
<Properties close={close} item={dbItem} buttons={buttons} />
)
});
};

View File

@@ -18,19 +18,18 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import { Item } from "@notesnook/core";
import { strings } from "@notesnook/intl";
import { useThemeColors } from "@notesnook/theme";
import React from "react";
import { Dimensions, View } from "react-native";
import SwiperFlatList from "react-native-swiper-flatlist";
import Icon from "react-native-vector-icons/MaterialCommunityIcons";
import { Action, ActionId, useActions } from "../../hooks/use-actions";
import { Action, ActionId } from "../../hooks/use-actions";
import { useStoredRef } from "../../hooks/use-stored-ref";
import { DDS } from "../../services/device-detection";
import { useSettingStore } from "../../stores/use-setting-store";
import { AppFontSize } from "../../utils/size";
import { DefaultAppStyles } from "../../utils/styles";
import AppIcon from "../ui/AppIcon";
import { Button } from "../ui/button";
import { Pressable } from "../ui/pressable";
import Paragraph from "../ui/typography/paragraph";
import { Radius, Spacing } from "../../common/design/spacing";
@@ -64,10 +63,18 @@ const BOTTOM_BAR_ITEMS: ActionId[] = [
"trash"
];
const PREFERENCE_ITEMS: ActionId[] = [
"add-shortcut",
"pin",
"default-notebook",
"default-tag",
"default-homepage"
];
const COLUMN_BAR_ITEMS: ActionId[] = [
"select",
"add-notebook",
"edit-notebook",
// "edit-notebook",
"move-notes",
"move-notebook",
"edit-reminder",
@@ -79,7 +86,7 @@ const COLUMN_BAR_ITEMS: ActionId[] = [
"add-shortcut",
"reorder",
"rename-color",
"rename-tag",
// "rename-tag",
"launcher-shortcut",
"copy-id",
"copy-link",
@@ -91,11 +98,13 @@ const COLUMN_BAR_ITEMS: ActionId[] = [
export const Items = ({
item,
close,
buttons
buttons,
actions
}: {
item: Item;
close: () => void;
buttons: Action[];
actions: Action[];
}) => {
const { colors } = useThemeColors();
const topBarSorting = useStoredRef<{ [name: string]: number }>(
@@ -103,14 +112,12 @@ export const Items = ({
{}
);
const dimensions = useSettingStore((state) => state.dimensions);
const actions = useActions({ item, close });
const selectedActions = actions.filter((i) => !i.hidden);
const deviceMode = useSettingStore((state) => state.deviceMode);
const width = Math.min(dimensions.width, 600);
const shouldShrink =
Dimensions.get("window").fontScale > 1 &&
Dimensions.get("window").width < 450;
Dimensions.get("window").fontScale > 1 && dimensions.width < 450;
const columnItemsCount = deviceMode === "tablet" ? 7 : shouldShrink ? 4 : 5;
@@ -136,16 +143,23 @@ export const Items = ({
BOTTOM_BAR_ITEMS.indexOf(a.id) > BOTTOM_BAR_ITEMS.indexOf(b.id) ? 1 : -1
);
const preferenceItems = selectedActions
.filter((item) => PREFERENCE_ITEMS.indexOf(item.id) > -1)
.sort((a, b) =>
PREFERENCE_ITEMS.indexOf(a.id) > PREFERENCE_ITEMS.indexOf(b.id) ? 1 : -1
);
const columnItems = selectedActions
.filter((item) => COLUMN_BAR_ITEMS.indexOf(item.id) > -1)
.filter(
(item) =>
COLUMN_BAR_ITEMS.indexOf(item.id) > -1 &&
PREFERENCE_ITEMS.indexOf(item.id) === -1
)
.sort((a, b) =>
COLUMN_BAR_ITEMS.indexOf(a.id) > COLUMN_BAR_ITEMS.indexOf(b.id) ? 1 : -1
);
const topBarItemHeight = Math.min(
(width - (topBarItems.length * 10 + 14)) / topBarItems.length,
60
);
const actionItems = [...buttons, ...columnItems];
const renderRowItem = React.useCallback(
({ item }: { item: Action }) => (
@@ -170,9 +184,10 @@ export const Items = ({
marginBottom: 6
}}
>
<Icon
<AppIcon
allowFontScaling
name={item.icon}
iconFamily="notesnook"
size={
DDS.isTab
? AppFontSize.xxl
@@ -208,33 +223,79 @@ export const Items = ({
]
);
const renderColumnItem = React.useCallback(
const renderPreferenceItem = React.useCallback(
(item: Action) => (
<Button
<Pressable
key={item.id}
buttonType={{
text: item.checked
? item.activeColor || colors.primary.accent
: item.id === "delete" || item.id === "trash"
? colors.error.paragraph
: colors.primary.paragraph
}}
testID={"icon-" + item.id}
onPress={item.onPress}
title={item.title}
icon={item.icon}
type={item.checked ? "inverted" : "plain"}
fontSize={AppFontSize.sm}
type={item.checked ? "shade" : "transparent"}
testID={"icon-" + item.id}
style={{
borderRadius: 0,
justifyContent: "flex-start",
alignSelf: "flex-start",
width: "100%",
opacity: item.locked ? 0.5 : 1
width: "48.5%",
flexDirection: "row",
alignItems: "center",
justifyContent: "space-between",
gap: Spacing.LEVEL_1,
paddingVertical: Spacing.LEVEL_2,
paddingHorizontal: Spacing.LEVEL_2,
borderRadius: Radius.XS,
borderWidth: item.checked ? 0 : 1,
borderColor: colors.primary.border,
opacity: item.locked ? 0.7 : 1
}}
/>
>
<View
style={{
flexDirection: "row",
alignItems: "center",
gap: Spacing.LEVEL_1,
flexShrink: 1
}}
>
<AppIcon
name={item.icon}
iconFamily="notesnook"
allowFontScaling
size={AppFontSize.md}
color={item.checked ? colors.primary.icon : colors.secondary.icon}
/>
<Paragraph
numberOfLines={1}
fontSize="XS"
fontFamily="MEDIUM"
color={
item.checked
? colors.primary.paragraph
: colors.secondary.paragraph
}
style={{ flexShrink: 1 }}
>
{item.title}
</Paragraph>
</View>
<AppIcon
name={item.checked ? "toggle-on" : "toggle-off"}
iconFamily="notesnook"
size={16}
color={
item.checked
? [colors.primary.accent, colors.primary.background]
: [colors.disabled.icon, colors.primary.background]
}
/>
</Pressable>
),
[colors.error.paragraph, colors.primary.accent, colors.primary.paragraph]
[
colors.disabled.icon,
colors.primary.accent,
colors.primary.background,
colors.primary.border,
colors.primary.icon,
colors.primary.paragraph,
colors.secondary.icon,
colors.secondary.paragraph
]
);
const renderTopBarItem = React.useCallback(
@@ -274,8 +335,9 @@ export const Items = ({
paddingHorizontal: Spacing.LEVEL_2
}}
>
<Icon
<AppIcon
name={item.icon}
iconFamily="notesnook"
allowFontScaling
size={16}
color={
@@ -351,11 +413,7 @@ export const Items = ({
};
return (
<View
style={{
gap: DefaultAppStyles.GAP
}}
>
<View>
{item.type === "note" ? (
<>
<View>
@@ -416,9 +474,61 @@ export const Items = ({
</View>
</>
) : (
<View>
{buttons.map(renderColumnItem)}
{columnItems.map(renderColumnItem)}
<View
style={{
paddingHorizontal: DefaultAppStyles.GAP
}}
>
{preferenceItems.length > 0 ? (
<View style={{ gap: Spacing.LEVEL_2 }}>
<Paragraph
fontFamily="MEDIUM"
fontSize="SM"
color={colors.secondary.paragraph}
>
{strings.preferences()}
</Paragraph>
<View
style={{
flexDirection: "row",
flexWrap: "wrap",
gap: Spacing.LEVEL_1
}}
>
{preferenceItems.map(renderPreferenceItem)}
</View>
</View>
) : null}
<View
style={{
marginVertical: Spacing.LEVEL_3,
width: "100%",
borderBottomWidth: 1,
borderColor: colors.primary.separator
}}
/>
{actionItems.length > 0 ? (
<View style={{ gap: Spacing.LEVEL_2 }}>
<Paragraph
fontFamily="MEDIUM"
fontSize="SM"
color={colors.secondary.paragraph}
>
{strings.actionsHeading()}
</Paragraph>
<View
style={{
flexDirection: "row",
flexWrap: "wrap",
gap: Spacing.LEVEL_1
}}
>
{actionItems.map((item) => renderRowItem({ item }))}
</View>
</View>
) : null}
</View>
)}
</View>

View File

@@ -31,7 +31,7 @@ import { Properties } from "../properties";
import { useSideBarDraggingStore } from "./dragging-store";
import { MenuItem } from "./menu-item";
import { Default_Drag_Action } from "../../hooks/use-actions";
import { Spacing } from "../../common/design/spacing";
export const ColorSection = React.memo(
function ColorSection() {

View File

@@ -49,6 +49,7 @@ import { isFeatureAvailable } from "@notesnook/common";
import PaywallSheet from "../sheets/paywall";
import useGlobalSafeAreaInsets from "../../hooks/use-global-safe-area-insets";
import { Spacing } from "../../common/design/spacing";
import { createFormRef, validators } from "../ui/input/form-input";
/**
* Simple Tab View Implementation for the Side bar
@@ -428,25 +429,34 @@ const TabBar = (props: SimpleTabBarProps) => {
}
presentDialog({
title: strings.addTag(),
inputLabel: "Enter title",
inputPlaceholder: "eg. journal",
input: true,
positiveText: "Add",
positivePress: async (tag) => {
if (tag) {
await db.tags.add({
title: tag
});
useTagStore.getState().refresh();
return true;
form: {
formRef: createFormRef({
title: ""
}),
items: [
{
label: strings.enterTitle(),
name: "title",
placeholder: "eg. journal",
ref: React.createRef(),
validators: [validators.required(strings.allFieldsRequired())]
}
],
onFormSubmit: async (form) => {
try {
if (!form.validate()) return false;
await db.tags.add({
title: form.getValue("title").trim()
});
useTagStore.getState().refresh();
return true;
} catch (e) {
form.setError("title", (e as Error).message);
return false;
}
}
ToastManager.show({
context: "local",
type: "error",
message: strings.allFieldsRequired()
});
return false;
}
},
positiveText: strings.add()
});
}
}}

View File

@@ -176,7 +176,7 @@ export function MenuItem({
item.icon === "crown"
? colors.static.yellow
: isFocused
? colors.primary.icon
? colors.selected.icon
: colors.secondary.icon
}
size={AppFontSize.md}
@@ -198,7 +198,7 @@ export function MenuItem({
<Paragraph
fontSize="XS"
color={
isFocused ? colors.primary.paragraph : colors.secondary.paragraph
isFocused ? colors.selected.paragraph : colors.secondary.paragraph
}
style={{
marginLeft: Spacing.LEVEL_1

View File

@@ -19,7 +19,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
import { useThemeColors } from "@notesnook/theme";
import React, { useEffect } from "react";
import { View } from "react-native";
import { View, ViewStyle } from "react-native";
import { StoreApi, UseBoundStore } from "zustand";
import { useTotalNotes } from "../../hooks/use-db-item";
import {
@@ -38,6 +38,7 @@ import { useRelationStore } from "../../stores/use-relation-store";
import { Radius, Spacing } from "../../common/design/spacing";
import Heading from "../ui/typography/heading";
import { AddNotebookSheet } from "../sheets/add-notebook";
import { strings } from "@notesnook/intl";
export const NotebookItem = ({
index,
@@ -53,7 +54,10 @@ export const NotebookItem = ({
onLongPress,
onAddNotebook,
canDisableSelectionMode,
disableExpand
disableExpand,
hideNoteCount,
style,
subNotebookButtonStyle
}: {
index: number;
item: TreeItem;
@@ -69,6 +73,9 @@ export const NotebookItem = ({
onAddNotebook?: () => void;
canDisableSelectionMode?: boolean;
disableExpand?: boolean;
hideNoteCount?: boolean;
style?: ViewStyle;
subNotebookButtonStyle?: ViewStyle;
}) => {
const notebook = item.notebook;
const isFocused = focused;
@@ -96,210 +103,222 @@ export const NotebookItem = ({
}, [item.notebook.id, notebook.id, onItemUpdate]);
const itemPadding =
item.depth === 0 ? undefined : item.depth < 6 ? 15 * item.depth : 15 * 5;
item.depth === 0
? undefined
: item.depth < 6
? Spacing.LEVEL_2 * item.depth
: Spacing.LEVEL_2 * 5;
return (
<View
style={{
paddingLeft: itemPadding,
width: "100%",
opacity: item.disabled ? 0.5 : 1,
paddingBottom: Spacing.LEVEL_0
opacity: item.disabled ? 0.5 : 1
}}
>
{item.depth > 0 ? (
<View
style={{
height: "100%",
width: 1,
backgroundColor: colors.primary.border,
top: 0,
bottom: 0,
position: "absolute",
left: itemPadding
}}
/>
) : null}
<Pressable
type={isFocused || selected ? "selected" : "transparent"}
onLongPress={onLongPress}
testID={`notebook-item-${item.depth}-${index}`}
onPress={async () => {
if (selectionEnabled) {
const state = selectionStore.getState();
if (selected) {
state.markAs(item.notebook, "deselected");
return;
}
if (!state.multiSelect) {
const keys = Object.keys(state.selection);
const nextState: any = {};
for (const key in keys) {
nextState[key] = !state.initialState[key]
? undefined
: "deselected";
}
state.setSelection({
[item.notebook.id]: "selected",
...nextState
});
} else {
state.markAs(item.notebook, "selected");
}
if (
selectionStore.getState().getSelectedItemIds().length === 0 &&
canDisableSelectionMode
) {
selectionStore.setState({
enabled: false
});
}
} else {
onPress?.();
}
}}
<View
style={{
justifyContent: "space-between",
width: "100%",
alignItems: "center",
flexDirection: "row",
borderRadius: Radius.XS,
paddingVertical: Spacing.LEVEL_1,
paddingHorizontal: Spacing.LEVEL_1,
marginBottom:
expanded && item.hasChildren ? Spacing.LEVEL_0 : undefined
flexDirection: "row"
}}
>
<View
style={{
flexDirection: "row",
alignItems: "center",
flexShrink: 1,
gap: Spacing.LEVEL_1
}}
>
{item.depth === 0 ? (
<AppIcon
size={AppFontSize.md}
color={
selected || isFocused
? colors.selected.icon
: colors.primary.icon
{item.depth > 0 ? (
<View
style={{
height: "100%",
width: 1,
backgroundColor: colors.primary.border,
marginRight: Spacing.LEVEL_1
}}
/>
) : null}
<Pressable
type={isFocused || selected ? "selected" : "transparent"}
onLongPress={onLongPress}
testID={`notebook-item-${item.depth}-${index}`}
onPress={async () => {
if (selectionEnabled) {
const state = selectionStore.getState();
if (selected) {
state.markAs(item.notebook, "deselected");
return;
}
testID={item.hasChildren ? `expand-notebook-${index}` : ""}
style={{
borderRadius: defaultBorderRadius
}}
iconFamily="notesnook"
name={"bookmark"}
/>
) : null}
<Paragraph
color={
isFocused ? colors.selected.paragraph : colors.secondary.heading
if (!state.multiSelect) {
const keys = Object.keys(state.selection);
const nextState: any = {};
for (const key in keys) {
nextState[key] = !state.initialState[key]
? undefined
: "deselected";
}
state.setSelection({
[item.notebook.id]: "selected",
...nextState
});
} else {
state.markAs(item.notebook, "selected");
}
if (
selectionStore.getState().getSelectedItemIds().length === 0 &&
canDisableSelectionMode
) {
selectionStore.setState({
enabled: false
});
}
} else {
onPress?.();
}
size={AppFontSize.sm}
style={{ flexShrink: 1 }}
>
{notebook?.title}
</Paragraph>
</View>
<View
}}
style={{
gap: Spacing.LEVEL_1,
flexDirection: "row",
justifyContent: "space-between",
flexShrink: 1,
alignItems: "center",
justifyContent: "center",
marginLeft: Spacing.LEVEL_1
flexDirection: "row",
borderRadius: Radius.XS,
paddingVertical: Spacing.LEVEL_1,
paddingHorizontal: Spacing.LEVEL_1,
marginBottom:
expanded && item.hasChildren ? Spacing.LEVEL_0 : undefined,
...style
}}
>
{selectionEnabled ? (
<View
style={{
justifyContent: "center",
alignItems: "center"
}}
>
<View
style={{
flexDirection: "row",
alignItems: "center",
gap: Spacing.LEVEL_1
}}
>
{item.depth === 0 ? (
<AppIcon
name={selected ? "checkbox" : "box-empty"}
iconFamily="notesnook"
size={AppFontSize.md}
color={
selected
? [colors.selected.accent, colors.selected.accentForeground]
selected || isFocused
? colors.selected.icon
: colors.primary.icon
}
testID={item.hasChildren ? `expand-notebook-${index}` : ""}
style={{
borderRadius: defaultBorderRadius
}}
iconFamily="notesnook"
name={"bookmark"}
/>
</View>
) : (
<>
<Paragraph fontSize="SM" color={colors.secondary.paragraph}>
{totalNotes?.(notebook?.id) || 0}
</Paragraph>
</>
)}
) : null}
{onAddNotebook ? (
<IconButton
name="plus"
size={AppFontSize.md}
testID={`add-notebook-${index}`}
color={colors.primary.icon}
top={0}
left={0}
bottom={0}
right={40}
style={{
width: 32,
height: 32,
borderRadius: defaultBorderRadius
}}
onPress={() => {
onAddNotebook();
}}
/>
) : null}
{item.hasChildren ? (
<IconButton
size={12}
<Paragraph
color={
selected || isFocused
? colors.selected.icon
: colors.primary.icon
isFocused ? colors.selected.paragraph : colors.primary.paragraph
}
testID={item.hasChildren ? `expand-notebook-${index}` : ""}
onPress={() => {
if (item.hasChildren && !disableExpand) {
onToggleExpanded?.();
size={AppFontSize.sm}
>
{notebook?.title}
</Paragraph>
</View>
<View
style={{
gap: Spacing.LEVEL_1,
flexDirection: "row",
alignItems: "center",
justifyContent: "center"
}}
>
{selectionEnabled ? (
<View
style={{
justifyContent: "center",
alignItems: "center"
}}
>
<AppIcon
name={selected ? "checkbox" : "box-empty"}
iconFamily="notesnook"
size={AppFontSize.md}
color={
selected
? [
colors.selected.accent,
colors.selected.accentForeground
]
: colors.primary.icon
}
/>
</View>
) : (
<>
{item.hasChildren || hideNoteCount ? null : (
<Paragraph fontSize="SM" color={colors.secondary.paragraph}>
{totalNotes?.(notebook?.id) || 0}
</Paragraph>
)}
</>
)}
{onAddNotebook ? (
<IconButton
name="plus"
iconFamily="notesnook"
size={AppFontSize.md}
testID={`add-notebook-${index}`}
color={colors.primary.icon}
top={0}
left={0}
bottom={0}
right={40}
style={{
width: undefined,
height: undefined,
borderRadius: defaultBorderRadius
}}
onPress={() => {
onAddNotebook();
}}
/>
) : null}
{item.hasChildren ? (
<IconButton
size={12}
color={
selected || isFocused
? colors.selected.icon
: colors.primary.icon
}
}}
top={0}
left={20}
bottom={0}
right={20}
style={{
borderRadius: defaultBorderRadius,
width: undefined,
height: undefined
}}
iconFamily="notesnook"
name={expanded ? "chevron-up" : "chevron-down"}
/>
) : null}
</View>
</Pressable>
testID={item.hasChildren ? `expand-notebook-${index}` : ""}
onPress={() => {
if (item.hasChildren && !disableExpand) {
onToggleExpanded?.();
}
}}
top={0}
bottom={0}
right={0}
left={0}
style={{
borderRadius: defaultBorderRadius,
width: undefined,
height: undefined
}}
iconFamily="notesnook"
name={expanded ? "chevron-up" : "chevron-down"}
/>
) : null}
</View>
</Pressable>
</View>
{expanded && item.hasChildren && !selectionEnabled ? (
<View
style={{
width: "100%",
paddingLeft: (item.depth + 1) * 15
flexDirection: "row",
paddingLeft: (item.depth + 1) * Spacing.LEVEL_2
}}
>
<View
@@ -307,22 +326,18 @@ export const NotebookItem = ({
height: "100%",
width: 1,
backgroundColor: colors.primary.border,
top: 0,
bottom: 0,
position: "absolute",
left: (item.depth + 1) * 15
marginRight: Spacing.LEVEL_1
}}
/>
<Pressable
style={{
// borderLeftWidth: 1,
// borderLeftColor: colors.primary.border,
flexDirection: "row",
gap: Spacing.LEVEL_1,
justifyContent: "flex-start",
paddingVertical: Spacing.LEVEL_1,
paddingHorizontal: Spacing.LEVEL_1,
alignItems: "center"
alignItems: "center",
...subNotebookButtonStyle
}}
onPress={() => {
AddNotebookSheet.present(undefined, item.notebook);
@@ -336,8 +351,8 @@ export const NotebookItem = ({
}}
iconFamily="notesnook"
/>
<Heading fontSize="SM">Create sub-notebook</Heading>
</Pressable>{" "}
<Heading fontSize="SM">{strings.createSubnotebook()}</Heading>
</Pressable>
</View>
) : null}
</View>

View File

@@ -105,7 +105,6 @@ export const SideMenuListEmpty = (props: SideMenuListEmptyProps) => {
<Button
title={props.placeholderButtonTitle}
onPress={props.onPressPlaceholderButton}
fontSize={AppFontSize.sm}
style={{
marginTop: Spacing.LEVEL_2,
paddingVertical: Spacing.LEVEL_3,

View File

@@ -29,7 +29,6 @@ import { TreeItem } from "../../stores/create-notebook-tree-stores";
import useNavigationStore from "../../stores/use-navigation-store";
import { useNotebooks } from "../../stores/use-notebook-store";
import { AppFontSize } from "../../utils/size";
import { DefaultAppStyles } from "../../utils/styles";
import { Properties } from "../properties";
import { NotebookItem } from "./notebook-item";
import { SideMenuHeader } from "./side-menu-header";
@@ -291,8 +290,8 @@ const NotebookItemWrapper = React.memo(
Properties.present(item.notebook, false, [
{
id: "select",
title: strings.select() + " " + strings.dataTypes["notebook"](),
icon: "checkbox-outline",
title: strings.select(),
icon: "check-square",
onPress: () => {
const store = useSideMenuNotebookSelectionStore;
store.setState({

View File

@@ -27,7 +27,6 @@ import { useDBItem, useTotalNotes } from "../../hooks/use-db-item";
import { TaggedNotes } from "../../screens/notes/tagged";
import { presentDialog } from "../dialog/functions";
import Navigation from "../../services/navigation";
import { ToastManager } from "../../services/event-manager";
import useNavigationStore from "../../stores/use-navigation-store";
import { useTags, useTagStore } from "../../stores/use-tag-store";
import { AppFontSize } from "../../utils/size";
@@ -42,6 +41,7 @@ import { useSideMenuTagsSelectionStore } from "./stores";
import { LegendList, LegendListRenderItemProps } from "@legendapp/list";
import { useRelationStore } from "../../stores/use-relation-store";
import { Radius, Spacing } from "../../common/design/spacing";
import { createFormRef, validators } from "../ui/input/form-input";
const TagItem = (props: {
tags: VirtualizedGrouping<Tag>;
@@ -81,8 +81,8 @@ const TagItem = (props: {
Properties.present(item, false, [
{
id: "select",
title: strings.select() + " " + strings.dataTypes["tag"](),
icon: "checkbox-outline",
title: strings.select(),
icon: "check-square",
onPress: () => {
const store = useSideMenuTagsSelectionStore;
store.setState({
@@ -237,26 +237,37 @@ export const SideMenuTags = () => {
const onPressAddTag = React.useCallback(() => {
presentDialog({
title: strings.addTag(),
// paragraph: strings.addTagDesc(),
input: true,
inputLabel: "Enter title",
inputPlaceholder: "eg. journal",
positiveText: strings.add(),
positivePress: async (tag) => {
if (tag) {
await db.tags.add({
title: tag
});
useTagStore.getState().refresh();
return true;
form: {
formRef: createFormRef({
title: ""
}),
items: [
{
label: strings.enterTitle(),
name: "title",
placeholder: "eg. journal",
ref: React.createRef(),
validators: [validators.required(strings.allFieldsRequired())],
inputProps: {
autoCapitalize: "none"
}
}
],
onFormSubmit: async (form) => {
try {
if (!form.validate()) return false;
await db.tags.add({
title: form.getValue("title").trim()
});
useTagStore.getState().refresh();
return true;
} catch (e) {
form.setError("title", (e as Error).message);
return false;
}
}
ToastManager.show({
context: "local",
type: "error",
message: strings.allFieldsRequired()
});
return false;
}
},
positiveText: strings.add()
});
}, []);

View File

@@ -80,13 +80,13 @@ export const TabBarButton = ({
backgroundColor: "transparent",
borderWidth: 0
}}
type={"plain"}
type={"plain"}
>
<Animated.View
style={[
{
backgroundColor: isActive ? colors.primary.shade : undefined,
borderRadius: Radius.XXS,
borderRadius: Radius.XS,
padding: Spacing.LEVEL_1
},
animatedIconStyle
@@ -95,7 +95,7 @@ export const TabBarButton = ({
<AppIcon
name={icon}
iconFamily="notesnook"
color={isActive ? colors.primary.icon : colors.secondary.icon}
color={isActive ? colors.selected.icon : colors.secondary.icon}
size={16}
/>
</Animated.View>

View File

@@ -0,0 +1,116 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import { useThemeColors } from "@notesnook/theme";
import React from "react";
import { ColorValue, DimensionValue, TextStyle, ViewStyle } from "react-native";
import { FontFamily } from "../../common/design/font";
import { Radius, Spacing } from "../../common/design/spacing";
import { AppFontSize } from "../../utils/size";
import AppIcon from "./AppIcon";
import { Pressable, PressableProps } from "./pressable";
import Paragraph from "./typography/paragraph";
export interface CheckboxProps extends Omit<PressableProps, "style"> {
checked?: boolean;
title?: string | null;
onPress?: () => void;
type?: PressableProps["type"];
style?: ViewStyle;
textStyle?: TextStyle;
fontSize?: number;
fontFamily?: keyof typeof FontFamily;
iconSize?: number;
iconColor?: ColorValue | ColorValue[];
width?: DimensionValue | null;
disabled?: boolean;
/**
* Hide the whole component when set to false.
*
* @default true
*/
visible?: boolean;
}
export const Checkbox = ({
checked,
title = null,
onPress,
type = "shade",
style,
textStyle,
fontSize = AppFontSize.xs,
fontFamily = "MEDIUM",
iconSize = 16,
iconColor,
width = "100%",
disabled,
visible = true,
...restProps
}: CheckboxProps) => {
const { colors } = useThemeColors();
if (!visible) return null;
return (
<Pressable
{...restProps}
onPress={onPress}
disabled={disabled}
type={type}
style={{
width: width || undefined,
flexDirection: "row",
alignItems: "center",
justifyContent: "flex-start",
flexShrink: 1,
gap: Spacing.LEVEL_1,
paddingHorizontal: Spacing.LEVEL_2,
paddingVertical: Spacing.LEVEL_2,
borderRadius: Radius.XS,
opacity: disabled ? 0.5 : 1,
...style
}}
>
<AppIcon
name={checked ? "checkbox" : "box-empty"}
iconFamily="notesnook"
size={iconSize}
color={
iconColor ||
(checked
? [colors.primary.accent, colors.primary.accentForeground]
: colors.primary.icon)
}
/>
{title ? (
<Paragraph
numberOfLines={1}
size={fontSize}
fontFamily={fontFamily}
color={colors.primary.paragraph}
style={[{ flexShrink: 1 }, textStyle]}
>
{title}
</Paragraph>
) : null}
</Pressable>
);
};

View File

@@ -0,0 +1,116 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import { useThemeColors } from "@notesnook/theme";
import React from "react";
import { ColorValue, DimensionValue, TextStyle, ViewStyle } from "react-native";
import { FontFamily } from "../../../common/design/font";
import { Radius, Spacing } from "../../../common/design/spacing";
import { AppFontSize } from "../../../utils/size";
import AppIcon from "../AppIcon";
import { Pressable, PressableProps } from "../pressable";
import Paragraph from "../typography/paragraph";
export interface CheckboxProps extends Omit<PressableProps, "style"> {
checked?: boolean;
title?: string | null;
onPress?: () => void;
type?: PressableProps["type"];
style?: ViewStyle;
textStyle?: TextStyle;
fontSize?: number;
fontFamily?: keyof typeof FontFamily;
iconSize?: number;
iconColor?: ColorValue | ColorValue[];
width?: DimensionValue | null;
disabled?: boolean;
/**
* Hide the whole component when set to false.
*
* @default true
*/
visible?: boolean;
}
export const Checkbox = ({
checked,
title = null,
onPress,
type = "shade",
style,
textStyle,
fontSize = AppFontSize.xs,
fontFamily = "MEDIUM",
iconSize = 16,
iconColor,
width = "100%",
disabled,
visible = true,
...restProps
}: CheckboxProps) => {
const { colors } = useThemeColors();
if (!visible) return null;
return (
<Pressable
{...restProps}
onPress={onPress}
disabled={disabled}
type={type}
style={{
width: width || undefined,
flexDirection: "row",
alignItems: "center",
justifyContent: "flex-start",
flexShrink: 1,
gap: Spacing.LEVEL_1,
paddingHorizontal: Spacing.LEVEL_2,
paddingVertical: Spacing.LEVEL_2,
borderRadius: Radius.XS,
opacity: disabled ? 0.5 : 1,
...style
}}
>
<AppIcon
name={checked ? "checkbox" : "box-empty"}
iconFamily="notesnook"
size={iconSize}
color={
iconColor ||
(checked
? [colors.primary.accent, colors.primary.accentForeground]
: colors.primary.icon)
}
/>
{title ? (
<Paragraph
numberOfLines={1}
size={fontSize}
fontFamily={fontFamily}
color={colors.primary.paragraph}
style={[{ flexShrink: 1 }, textStyle]}
>
{title}
</Paragraph>
) : null}
</Pressable>
);
};

View File

@@ -219,7 +219,6 @@ const Input = ({
justifyContent: "space-between",
alignItems: "center",
paddingHorizontal: Spacing.LEVEL_2,
paddingRight: Spacing.LEVEL_3,
...containerStyle
};
@@ -230,6 +229,7 @@ const Input = ({
onPress && loading ? colors.primary.accent : colors.primary.paragraph,
paddingTop: Spacing.LEVEL_3,
paddingBottom: Spacing.LEVEL_3,
lineHeight: fontSize + fontSize * 0.3,
flexGrow: 1,
flexShrink: 1,
fontFamily: "Inter-Regular",

View File

@@ -18,21 +18,39 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import React from "react";
import { View } from "react-native";
import { DimensionValue, View, ViewStyle } from "react-native";
import { useThemeColors } from "@notesnook/theme";
import { Spacing } from "../../../common/design/spacing";
const LineSeparator = ({ padding }: { padding: keyof typeof Spacing }) => {
const LineSeparator = ({
style,
paddingHorizontal,
paddingVertical,
stroke = 1
}: {
style?: ViewStyle;
paddingHorizontal?: DimensionValue;
paddingVertical?: DimensionValue;
stroke?: number;
}) => {
const { colors } = useThemeColors();
return (
<View
style={{
width: "100%",
height: 1,
backgroundColor: colors.primary.border
// marginVertical: Spacing[padding]
}}
/>
style={[
style,
{
paddingHorizontal,
paddingVertical
}
]}
>
<View
style={{
width: "100%",
height: stroke,
backgroundColor: colors.primary.separator
}}
/>
</View>
);
};

View File

@@ -488,7 +488,7 @@ export const useActions = ({
actions.push({
id: "rename-tag",
title: strings.rename(),
icon: "square-edit-outline",
icon: "mode-edit",
onPress: renameTag
});
}
@@ -497,7 +497,7 @@ export const useActions = ({
actions.push({
id: "rename-color",
title: strings.rename(),
icon: "square-edit-outline",
icon: "mode-edit",
onPress: renameColor
});
}
@@ -544,7 +544,7 @@ export const useActions = ({
{
id: "delete",
title: strings.delete(),
icon: "delete",
icon: "trash-alt",
onPress: deleteTrashItem
}
);
@@ -557,7 +557,7 @@ export const useActions = ({
title: isPinnedToMenu
? strings.removeShortcut()
: strings.addShortcut(),
icon: isPinnedToMenu ? "link-variant-remove" : "link-variant",
icon: "arrow-square-out",
onPress: createMenuShortcut,
isToggle: true,
checked: isPinnedToMenu,
@@ -570,7 +570,7 @@ export const useActions = ({
? strings.removeAsDefault()
: strings.setAsDefault(),
hidden: item.type !== "tag",
icon: "pound",
icon: "check",
onPress: async () => {
if (defaultTag === item.id) {
await db.settings.setDefaultTag(undefined);
@@ -605,7 +605,7 @@ export const useActions = ({
{
id: "add-notebook",
title: strings.addNotebook(),
icon: "plus",
icon: "bookmark",
onPress: async () => {
if (features && !features.notebooks.isAllowed) {
ToastManager.show({
@@ -626,16 +626,16 @@ export const useActions = ({
},
locked: !features?.notebooks.isAllowed
},
{
id: "edit-notebook",
title: strings.editNotebook(),
icon: "square-edit-outline",
onPress: async () => {
close();
await sleep(300);
AddNotebookSheet.present(item);
}
},
// {
// id: "edit-notebook",
// title: strings.editNotebook(),
// icon: "square-edit-outline",
// onPress: async () => {
// close();
// await sleep(300);
// AddNotebookSheet.present(item);
// }
// },
{
id: "default-notebook",
title:
@@ -643,7 +643,7 @@ export const useActions = ({
? strings.removeAsDefault()
: strings.setAsDefault(),
hidden: item.type !== "notebook",
icon: "notebook",
icon: "check",
onPress: async () => {
if (defaultNotebook === item.id) {
await db.settings.setDefaultNotebook(undefined);
@@ -678,7 +678,7 @@ export const useActions = ({
id: "move-notes",
title: strings.addNotes(),
hidden: item.type !== "notebook",
icon: "text",
icon: "file-text",
onPress: () => {
close();
Navigation.navigate("MoveNotes", {
@@ -689,7 +689,7 @@ export const useActions = ({
{
id: "move-notebook",
title: strings.moveNotebookFix(),
icon: "arrow-right-bold-box-outline",
icon: "drive-file-move",
onPress: () => {
close();
Navigation.navigate("MoveNotebook", {
@@ -704,7 +704,7 @@ export const useActions = ({
actions.push({
id: "pin",
title: item.pinned ? strings.unpin() : strings.pin(),
icon: item.pinned ? "pin-off-outline" : "pin-outline",
icon: "pin",
onPress: pinItem,
isToggle: true,
checked: item.pinned,
@@ -720,7 +720,7 @@ export const useActions = ({
actions.push({
id: "default-homepage",
title: isHomepage ? strings.unsetAsHomepage() : strings.setAsHomepage(),
icon: "home-outline",
icon: "house",
isToggle: true,
checked: isHomepage,
onPress: async () => {
@@ -1014,7 +1014,7 @@ export const useActions = ({
{
id: "favorite",
title: !item.favorite ? strings.favorite() : strings.unfavorite(),
icon: item.favorite ? "star-off" : "star-outline",
icon: "star",
onPress: addToFavorites,
isToggle: true,
checked: item.favorite,
@@ -1053,19 +1053,19 @@ export const useActions = ({
{
id: "attachments",
title: strings.attachedFiles(),
icon: "attachment",
icon: "paperclip",
onPress: showAttachments
},
{
id: "history",
title: strings.history(),
icon: "history",
icon: "clock-counter-clockwise",
onPress: openHistory
},
{
id: "reminders",
title: strings.dataTypesPluralCamelCase.reminder(),
icon: "clock-outline",
icon: "clock",
onPress: async () => {
close();
RelationsList.present({
@@ -1095,40 +1095,40 @@ export const useActions = ({
{
id: "copy",
title: strings.copy(),
icon: "content-copy",
icon: "copy",
onPress: copyContent
},
{
id: "share",
title: strings.share(),
icon: "share-variant",
icon: "share",
onPress: shareNote
},
{
id: "read-only",
title: strings.readOnly(),
icon: "pencil-lock",
icon: "pencil-simple-slash",
onPress: toggleReadyOnlyMode,
checked: item.readonly
},
{
id: "local-only",
title: strings.syncOff(),
icon: "sync-off",
icon: "sync-disabled",
onPress: toggleLocalOnly,
checked: item.localOnly
},
{
id: "duplicate",
title: strings.duplicate(),
icon: "content-duplicate",
icon: "duplicate",
onPress: duplicateNote
},
{
id: "add-reminder",
title: strings.remindMe(),
icon: "clock-plus-outline",
icon: "bell",
onPress: async () => {
close();
await sleep(100);
@@ -1138,7 +1138,7 @@ export const useActions = ({
{
id: "lock-unlock",
title: locked ? strings.unlock() : strings.lock(),
icon: locked ? "lock-open-outline" : "key-outline",
icon: "lock",
onPress: addToVault,
checked: locked
},
@@ -1163,16 +1163,16 @@ export const useActions = ({
icon: "book-outline",
onPress: addTo
},
{
id: "add-tag",
title: strings.addTags(),
icon: "pound",
onPress: addTo
},
// {
// id: "add-tag",
// title: strings.addTags(),
// icon: "pound",
// onPress: addTo
// },
{
id: "references",
title: strings.references(),
icon: "vector-link",
icon: "link-alt",
onPress: () => {
ReferencesList.present({
reference: item as ItemReference
@@ -1272,7 +1272,7 @@ export const useActions = ({
item.type !== "notebook" && item.type !== "note"
? strings.doActions.delete.unknown(item.type, 1)
: strings.moveToTrash(),
icon: "delete-outline",
icon: "trash-alt",
type: "error",
onPress: deleteItem,
locked: isPublished
@@ -1289,7 +1289,7 @@ export const useActions = ({
actions.push({
id: "launcher-shortcut",
title: strings.addToHome(),
icon: "cellphone-arrow-down",
icon: "home",
locked: !features?.androidLauncherShortcuts.isAllowed,
onPress: async () => {
if (features && !features?.androidLauncherShortcuts.isAllowed) {

View File

@@ -139,6 +139,7 @@ const showActionsheet = async () => {
.getNoteIdForTab(useTabStore.getState().currentTab!);
if (noteId) {
const note = await db.notes?.note(noteId);
if (!note) return;
Properties.present(note, false);
} else {
ToastManager.show({

View File

@@ -69,7 +69,7 @@ export const Home = ({ navigation, route }: NavigationProps<"Notes">) => {
onPressDefaultRightButton={openEditor}
/>
<LineSeparator padding="LEVEL_3" />
<LineSeparator />
<DelayLayout wait={loading}>
<List

View File

@@ -55,6 +55,8 @@ import { eSendEvent, ToastManager } from "../../services/event-manager";
import { eUpdateNotebookRoute } from "../../utils/events";
import { isFeatureAvailable } from "@notesnook/common";
import PaywallSheet from "../../components/sheets/paywall";
import { Radius, Spacing } from "../../common/design/spacing";
import LineSeparator from "../../components/ui/seperator/line-separator";
const {
useNotebookExpandedStore,
@@ -136,14 +138,14 @@ export const MoveNotebook = (props: NavigationProps<"MoveNotebook">) => {
excludedItems.push(notebook.id);
}
// Exclude and disable items as needed
const filtered = tree.filter(item => !excludedItems.includes(item.notebook.id)).map(
(treeItem) => {
const filtered = tree
.filter((item) => !excludedItems.includes(item.notebook.id))
.map((treeItem) => {
return {
...treeItem,
disabled: disabledItems.includes(treeItem.notebook.id)
}
}
);
};
});
return filtered;
}
filterNotebooks().then((filtered) => {
@@ -157,13 +159,14 @@ export const MoveNotebook = (props: NavigationProps<"MoveNotebook">) => {
<NotebookItemWrapper
index={index}
item={item}
hideNoteCount
onPress={async () => {
if (item.disabled) {
ToastManager.show({
type: "info",
"message": "You cannot move the selected notebook(s) here"
})
return;
if (item.disabled) {
ToastManager.show({
type: "info",
message: "You cannot move the selected notebook(s) here"
});
return;
}
const selectedNotebook = item.notebook;
presentDialog({
@@ -223,7 +226,6 @@ export const MoveNotebook = (props: NavigationProps<"MoveNotebook">) => {
return (
<SafeAreaView
style={{
gap: DefaultAppStyles.GAP_VERTICAL,
flex: 1,
backgroundColor: colors.primary.background
}}
@@ -233,6 +235,9 @@ export const MoveNotebook = (props: NavigationProps<"MoveNotebook">) => {
selectedNotebooks.length,
selectedNotebooks[0].title
)}
style={{
backgroundColor: "transparent"
}}
canGoBack
/>
@@ -244,7 +249,7 @@ export const MoveNotebook = (props: NavigationProps<"MoveNotebook">) => {
ListHeaderComponent={
<View
style={{
paddingHorizontal: DefaultAppStyles.GAP
paddingHorizontal: Spacing.LEVEL_3
}}
>
<Input
@@ -255,13 +260,17 @@ export const MoveNotebook = (props: NavigationProps<"MoveNotebook">) => {
updateNotebooks();
}, 300);
}}
containerStyle={{
backgroundColor: colors.secondary.background,
borderWidth: 0,
borderRadius: Radius.S
}}
testID="move-notebook-search"
button={{
icon: "plus",
onPress: async () => {
const notebooksFeature = await isFeatureAvailable(
"notebooks"
);
const notebooksFeature =
await isFeatureAvailable("notebooks");
if (!notebooksFeature.isAllowed) {
ToastManager.show({
message: notebooksFeature.error,
@@ -287,17 +296,19 @@ export const MoveNotebook = (props: NavigationProps<"MoveNotebook">) => {
color: colors.primary.icon
}}
/>
{moveToTopEnabled && tree.length > 0 ? (
<Button
title={strings.moveToTop()}
style={{
alignSelf: "flex-start",
width: "100%",
justifyContent: "space-between"
justifyContent: "space-between",
marginTop: Spacing.LEVEL_2
}}
icon="arrow-up-bold"
iconPosition="right"
type="secondaryAccented"
type="accent"
onPress={async () => {
for (const notebook of selectedNotebooks) {
if (
@@ -325,6 +336,13 @@ export const MoveNotebook = (props: NavigationProps<"MoveNotebook">) => {
}}
/>
) : null}
<LineSeparator
paddingVertical={Spacing.LEVEL_3}
style={{
paddingBottom: Spacing.LEVEL_0
}}
/>
</View>
}
ListEmptyComponent={
@@ -354,11 +372,13 @@ const NotebookItemWrapper = React.memo(
({
item,
index,
onPress
onPress,
hideNoteCount
}: {
item: TreeItem;
index: number;
onPress: () => void;
hideNoteCount?: boolean;
}) => {
const expanded = useNotebookExpandedStore(
(state) => state.expanded[item.notebook.id]
@@ -393,8 +413,7 @@ const NotebookItemWrapper = React.memo(
return (
<View
style={{
paddingHorizontal: DefaultAppStyles.GAP,
marginTop: index === 0 ? DefaultAppStyles.GAP : 0
paddingHorizontal: Spacing.LEVEL_3
}}
>
<NotebookItem
@@ -415,6 +434,13 @@ const NotebookItemWrapper = React.memo(
useNotebookTreeStore.getState().removeChildren(item.notebook.id);
}
}}
style={{
paddingVertical: Spacing.LEVEL_2
}}
subNotebookButtonStyle={{
paddingVertical: Spacing.LEVEL_2
}}
hideNoteCount={hideNoteCount}
disableExpand={disableExpand}
selected={selected}
selectionEnabled={selectionEnabled}

View File

@@ -166,6 +166,7 @@ const NotebookScreen = ({ route, navigation }: NavigationProps<"Notebook">) => {
rightButton={{
name: "dots-vertical",
onPress: () => {
if (!notebook) return;
Properties.present(notebook);
}
}}

View File

@@ -59,9 +59,14 @@ function confirmDeleteAllNotes(
) {
return new Promise<{ delete: boolean; deleteNotes: boolean }>((resolve) => {
presentDialog({
title: strings.doActions.delete.notebook(items.length),
title: strings.moveToTrash() + "?",
paragraph: `The selected notebook${items.length > 1 ? `s` : ``} will be moved to trash. You can restore them later.`,
positiveText: strings.delete(),
negativeText: strings.cancel(),
icon: "warning-circle",
iconType: "error",
iconFamily: "notesnook",
centered: true,
positivePress: async (_inputValue, value) => {
setTimeout(() => {
resolve({ delete: true, deleteNotes: value });

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24"><!-- Icon from Material Design Icons by Pictogrammers - https://github.com/Templarian/MaterialDesign/blob/master/LICENSE --><path fill="currentColor" d="M14.5 2.75c-1.8 0-3.25 1.45-3.25 3.25H10v1.29c-.69.21-1.33.52-1.92.91l9.71 9.71A6.9 6.9 0 0 0 19 14c0-3.17-2.11-5.85-5-6.71V6h-1.25a1.75 1.75 0 0 1 1.75-1.75A1.75 1.75 0 0 1 16.25 6a2.25 2.25 0 0 0 2.25 2.25c1.24 0 2.24-1.01 2.24-2.25v-.75h-1.49V6c0 .42-.34.75-.75.75c-.42 0-.75-.33-.75-.75c0-1.8-1.46-3.25-3.25-3.25M3.41 6.36L2 7.77l3.55 3.55C5.2 12.14 5 13.04 5 14c0 3.86 3.13 7 7 7c.92 0 1.83-.19 2.68-.55L18.23 24l1.41-1.41z"/></svg>

After

Width:  |  Height:  |  Size: 673 B

View File

@@ -0,0 +1,10 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_2311_26083)">
<path d="M15.5001 2C15.3675 2 15.2403 2.05268 15.1465 2.14645C15.0527 2.24021 15.0001 2.36739 15.0001 2.5C14.9877 2.87231 14.9123 3.23982 14.7769 3.58687C14.5238 4.20125 14.1063 4.5 13.5001 4.5C12.8088 4.5 12.3219 3.89 11.6569 2.95937C11.0001 2.04125 10.2576 1 9.00006 1C7.97568 1 7.18756 1.55562 6.78568 2.5625C6.66794 2.86435 6.58612 3.17902 6.54193 3.5H5.50006C5.23484 3.5 4.98049 3.60536 4.79295 3.79289C4.60542 3.98043 4.50006 4.23478 4.50006 4.5V5.09937C3.39902 5.66033 2.51897 6.57572 2.00177 7.69797C1.48456 8.82022 1.36035 10.0839 1.64915 11.2854C1.93795 12.4869 2.62293 13.5561 3.59368 14.3207C4.56442 15.0853 5.76436 15.5007 7.00006 15.5H7.09943C8.32673 15.4789 9.51169 15.0479 10.4657 14.2755C11.4197 13.5031 12.0879 12.4338 12.364 11.2378C12.64 10.0417 12.5081 8.78775 11.9891 7.67539C11.4701 6.56303 10.5939 5.65624 9.50006 5.09937V4.5C9.50006 4.23478 9.3947 3.98043 9.20717 3.79289C9.01963 3.60536 8.76528 3.5 8.50006 3.5H7.55506C7.59054 3.29947 7.64689 3.10319 7.72318 2.91438C7.97631 2.29875 8.39381 2 9.00006 2C9.69131 2 10.1782 2.61 10.8432 3.54063C11.5001 4.45875 12.2426 5.5 13.5001 5.5C14.5244 5.5 15.3126 4.94438 15.7144 3.9375C15.8913 3.47825 15.9879 2.992 16.0001 2.5C16.0001 2.36739 15.9474 2.24021 15.8536 2.14645C15.7598 2.05268 15.6327 2 15.5001 2ZM6.99318 13.0825C6.97366 13.1992 6.91341 13.3052 6.82312 13.3816C6.73283 13.458 6.61836 13.5 6.50006 13.5C6.47221 13.4999 6.44442 13.4976 6.41693 13.4931C5.69207 13.3645 5.02419 13.0164 4.50362 12.4958C3.98306 11.9752 3.63493 11.3074 3.50631 10.5825C3.49481 10.5175 3.49631 10.4508 3.51072 10.3863C3.52513 10.3219 3.55217 10.2609 3.59028 10.207C3.62839 10.153 3.67681 10.1071 3.73275 10.072C3.78868 10.0369 3.85102 10.0132 3.91617 10.0023C3.98131 9.99138 4.04797 9.9935 4.11229 10.0085C4.17662 10.0235 4.23733 10.0511 4.29092 10.0897C4.34451 10.1283 4.38993 10.1772 4.42454 10.2334C4.45915 10.2897 4.48226 10.3523 4.49256 10.4175C4.585 10.9378 4.83495 11.4172 5.20861 11.7908C5.58227 12.1645 6.06164 12.4144 6.58193 12.5069C6.64675 12.5176 6.7088 12.5411 6.76456 12.5758C6.82031 12.6106 6.86866 12.656 6.90685 12.7095C6.94505 12.7629 6.97233 12.8234 6.98714 12.8874C7.00196 12.9514 7.00401 13.0177 6.99318 13.0825Z" fill="#666666"/>
</g>
<defs>
<clipPath id="clip0_2311_26083">
<rect width="16" height="16" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@@ -0,0 +1,4 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M6 7.33329L8 9.33329L14.6667 2.66663" stroke="#181818" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M14 8V12.6667C14 13.0203 13.8595 13.3594 13.6095 13.6095C13.3594 13.8595 13.0203 14 12.6667 14H3.33333C2.97971 14 2.64057 13.8595 2.39052 13.6095C2.14048 13.3594 2 13.0203 2 12.6667V3.33333C2 2.97971 2.14048 2.64057 2.39052 2.39052C2.64057 2.14048 2.97971 2 3.33333 2H10.6667" stroke="#181818" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 608 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24"><!-- Icon from Material Design Icons by Pictogrammers - https://github.com/Templarian/MaterialDesign/blob/master/LICENSE --><path fill="currentColor" d="M14 14h2l-4-4l-4 4h2v4h4zM6 7h12v12c0 .5-.2 1-.61 1.39c-.39.41-.89.61-1.39.61H8c-.5 0-1-.2-1.39-.61C6.2 20 6 19.5 6 19zm13-3v2H5V4h3.5l1-1h5l1 1z"/></svg>

After

Width:  |  Height:  |  Size: 390 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 16 16"><!-- Icon from Qlementine Icons by Olivier Cléro - https://github.com/oclero/qlementine-icons/blob/master/LICENSE --><path fill="currentColor" d="M10.5 7a.5.5 0 0 1 .5.5V9h1.5a.5.5 0 0 1 0 1H11v1.5a.5.5 0 0 1-1 0V10H8.5a.5.5 0 0 1 0-1H10V7.5a.5.5 0 0 1 .5-.5"/><path fill="currentColor" fill-rule="evenodd" d="M13.5 3A2.5 2.5 0 0 1 16 5.5v8a2.5 2.5 0 0 1-2.5 2.5h-6A2.5 2.5 0 0 1 5 13.5v-8A2.5 2.5 0 0 1 7.5 3zm-6 1A1.5 1.5 0 0 0 6 5.5v8A1.5 1.5 0 0 0 7.5 15h6a1.5 1.5 0 0 0 1.5-1.5v-8A1.5 1.5 0 0 0 13.5 4z" clip-rule="evenodd"/><path fill="currentColor" d="M8.5 0c.979 0 1.83.563 2.24 1.38c.152.303-.103.618-.442.618c-.227 0-.423-.149-.55-.338a1.5 1.5 0 0 0-1.24-.662h-6a1.5 1.5 0 0 0-1.5 1.5v8a1.5 1.5 0 0 0 1.5 1.5h1a.5.5 0 0 1 0 1h-1a2.5 2.5 0 0 1-2.5-2.5v-8a2.5 2.5 0 0 1 2.5-2.5h6z"/></svg>

After

Width:  |  Height:  |  Size: 881 B

View File

@@ -0,0 +1,3 @@
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M10.2802 5.09437L6.53016 1.34437C6.38952 1.20383 6.19883 1.12488 6 1.12488C5.80118 1.12488 5.61049 1.20383 5.46985 1.34437L1.71985 5.09437C1.64987 5.16384 1.59439 5.24652 1.55665 5.33761C1.51891 5.42871 1.49965 5.5264 1.5 5.625V10.125C1.5 10.2245 1.53951 10.3198 1.60984 10.3902C1.68017 10.4605 1.77555 10.5 1.875 10.5H4.875C4.97446 10.5 5.06984 10.4605 5.14017 10.3902C5.2105 10.3198 5.25 10.2245 5.25 10.125V7.5H6.75V10.125C6.75 10.2245 6.78951 10.3198 6.85984 10.3902C6.93017 10.4605 7.02555 10.5 7.125 10.5H10.125C10.2245 10.5 10.3198 10.4605 10.3902 10.3902C10.4605 10.3198 10.5 10.2245 10.5 10.125V5.625C10.5004 5.5264 10.4811 5.42871 10.4434 5.33761C10.4056 5.24652 10.3501 5.16384 10.2802 5.09437ZM9.75 9.75H7.5V7.125C7.5 7.02554 7.4605 6.93016 7.39017 6.85983C7.31984 6.78951 7.22446 6.75 7.125 6.75H4.875C4.77555 6.75 4.68017 6.78951 4.60984 6.85983C4.53951 6.93016 4.5 7.02554 4.5 7.125V9.75H2.25V5.625L6 1.875L9.75 5.625V9.75Z" fill="#6F6F6F"/>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24"><!-- Icon from Material Design Icons by Pictogrammers - https://github.com/Templarian/MaterialDesign/blob/master/LICENSE --><path fill="currentColor" d="M10 7v2H9v6h1v2H6v-2h1V9H6V7zm6 0a2 2 0 0 1 2 2v6c0 1.11-.89 2-2 2h-4V7m4 2h-2v6h2z"/></svg>

After

Width:  |  Height:  |  Size: 328 B

View File

@@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M6.58569 4.90063C7.51769 4.90071 8.41185 5.2701 9.07104 5.92896V5.92993C9.40845 6.26828 9.67348 6.67158 9.85034 7.11548C10.0273 7.55953 10.1127 8.0351 10.1003 8.51294C10.0959 8.67187 10.0283 8.82257 9.91284 8.93188C9.79716 9.04123 9.64227 9.10042 9.48315 9.09595C9.32415 9.09145 9.17353 9.02399 9.06421 8.90845C8.95486 8.79277 8.89567 8.63788 8.90015 8.47876C8.91399 8.01493 8.78813 7.55764 8.53882 7.16626C8.28942 6.77479 7.92807 6.46691 7.50171 6.28345C7.07549 6.10005 6.60379 6.04904 6.14819 6.13696C5.74937 6.21401 5.3787 6.39502 5.073 6.65942L4.94604 6.77759L2.77808 8.94946C2.45461 9.27306 2.23357 9.68529 2.14429 10.134C2.05501 10.5828 2.10116 11.0482 2.27612 11.4709C2.45108 11.8936 2.74752 12.2547 3.12769 12.509C3.50798 12.7634 3.9553 12.8993 4.41284 12.8997C4.71773 12.9008 5.01979 12.8414 5.30151 12.7249C5.58326 12.6082 5.83955 12.4373 6.05444 12.2209L6.74878 11.5266L6.84058 11.4641C6.93785 11.4102 7.04934 11.3843 7.16187 11.3899C7.31156 11.3975 7.45301 11.461 7.55835 11.5676C7.66362 11.6743 7.72548 11.8163 7.7312 11.9661C7.73685 12.116 7.68572 12.2628 7.58862 12.3772L7.58374 12.3831L6.89624 13.0706C6.5705 13.398 6.18237 13.6575 5.75562 13.8342C5.38229 13.9888 4.9855 14.0771 4.58276 14.0959L4.40991 14.0999C3.71523 14.0991 3.03604 13.8925 2.45874 13.5061C1.88158 13.1197 1.43217 12.5708 1.16675 11.929C0.9013 11.287 0.831774 10.5809 0.967529 9.89966C1.10334 9.21834 1.4381 8.59197 1.92944 8.10083L4.10034 5.92896L4.22632 5.80884C4.87114 5.22528 5.71189 4.90063 6.58569 4.90063ZM11.5847 1.89966C12.0464 1.89969 12.5039 1.99051 12.9304 2.16724C13.3569 2.34396 13.7447 2.60251 14.071 2.92896V2.92993C14.409 3.26879 14.6744 3.67275 14.8513 4.11743C15.0282 4.5623 15.1133 5.03924 15.1003 5.51782C15.076 6.3577 14.7502 7.15866 14.1863 7.77661L14.071 7.89771L11.8992 10.0706C11.5735 10.398 11.1861 10.6575 10.7595 10.8342C10.3863 10.9888 9.98937 11.0771 9.58667 11.0959L9.41382 11.0999H9.41089C8.9413 11.0995 8.47618 11.0055 8.0437 10.8225C7.61125 10.6395 7.21957 10.3712 6.89233 10.0344C6.56526 9.69772 6.30884 9.29896 6.13843 8.86157C5.96798 8.4241 5.88703 7.95687 5.90015 7.48755C5.90462 7.32843 5.97197 7.17698 6.08765 7.06763C6.20331 6.95834 6.35826 6.90007 6.51733 6.90454C6.67632 6.90911 6.82701 6.97645 6.93628 7.09204C7.0455 7.20764 7.10474 7.36178 7.10034 7.52075C7.09161 7.82982 7.1444 8.1379 7.25659 8.42603C7.3688 8.71416 7.53819 8.9767 7.75366 9.19849C7.96912 9.42024 8.22672 9.59657 8.51147 9.71704C8.79625 9.83752 9.10265 9.89946 9.41187 9.89966C9.71567 9.9004 10.0169 9.8411 10.2976 9.72485C10.5782 9.60858 10.8333 9.43821 11.0476 9.2229L13.2185 7.05103C13.648 6.61607 13.8884 6.02853 13.8865 5.41724C13.8845 4.80607 13.6409 4.2205 13.2087 3.78833C12.7766 3.35616 12.191 3.1126 11.5798 3.1106C10.9685 3.10868 10.381 3.34902 9.94604 3.77856L9.94507 3.77759L9.25854 4.46509L9.25757 4.46704C9.14413 4.57481 8.99215 4.63408 8.83569 4.63208C8.67944 4.62996 8.5302 4.56678 8.41968 4.4563C8.30904 4.34566 8.2459 4.19576 8.2439 4.03931C8.24199 3.88298 8.30125 3.73176 8.40894 3.61841L9.09839 2.92896C9.42479 2.60253 9.81255 2.34393 10.239 2.16724C10.6656 1.9905 11.123 1.89966 11.5847 1.89966Z" fill="#666666" stroke="#666666" stroke-width="0.2"/>
</svg>

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24"><!-- Icon from Material Design Icons by Pictogrammers - https://github.com/Templarian/MaterialDesign/blob/master/LICENSE --><path fill="currentColor" d="M22 7v9c0 1.1-.9 2-2 2H6l-4 4V4c0-1.1.9-2 2-2h10.1c-.1.3-.1.7-.1 1s0 .7.1 1H4v12h16V7.9c.7-.1 1.4-.5 2-.9m-6-4c0 1.7 1.3 3 3 3s3-1.3 3-3s-1.3-3-3-3s-3 1.3-3 3"/></svg>

After

Width:  |  Height:  |  Size: 403 B

View File

@@ -0,0 +1,11 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_1258_18376)">
<path d="M2 13.9999H4.5L11.8733 6.62659L9.37333 4.12659L2 11.4999V13.9999ZM3.33333 12.0533L9.37333 6.01325L9.98667 6.62659L3.94667 12.6666H3.33333V12.0533Z" fill="#181818"/>
<path d="M12.2464 2.19329C11.9864 1.93329 11.5664 1.93329 11.3064 2.19329L10.0864 3.41329L12.5864 5.91329L13.8064 4.69329C14.0664 4.43329 14.0664 4.01329 13.8064 3.75329L12.2464 2.19329Z" fill="#181818"/>
</g>
<defs>
<clipPath id="clip0_1258_18376">
<rect width="16" height="16" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 630 B

View File

@@ -1,5 +1,3 @@
<svg preserveAspectRatio="none" width="100%" height="100%" overflow="visible" style="display: block;" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="Paperclip">
<path id="Vector" d="M13.1038 7.64625C13.1502 7.69269 13.1871 7.74783 13.2123 7.80853C13.2374 7.86923 13.2504 7.93429 13.2504 8C13.2504 8.06571 13.2374 8.13077 13.2123 8.19147C13.1871 8.25217 13.1502 8.30731 13.1038 8.35375L7.97563 13.4788C7.31913 14.1352 6.42877 14.5039 5.5004 14.5038C4.57204 14.5038 3.68172 14.1349 3.02531 13.4784C2.3689 12.8219 2.00017 11.9316 2.00023 11.0032C2.00028 10.0749 2.36913 9.18454 3.02562 8.52812L9.22937 2.23312C9.69806 1.76394 10.3339 1.50016 10.9971 1.49981C11.6603 1.49945 12.2964 1.76256 12.7656 2.23125C13.2348 2.69994 13.4986 3.33581 13.4989 3.99899C13.4993 4.66216 13.2362 5.29832 12.7675 5.7675L6.5625 12.0625C6.28071 12.3443 5.89851 12.5026 5.5 12.5026C5.10149 12.5026 4.71929 12.3443 4.4375 12.0625C4.15571 11.7807 3.9974 11.3985 3.9974 11C3.9974 10.6015 4.15571 10.2193 4.4375 9.9375L9.64375 4.64875C9.68936 4.6001 9.74423 4.56106 9.80515 4.53394C9.86607 4.50681 9.9318 4.49215 9.99847 4.4908C10.0651 4.48946 10.1314 4.50147 10.1934 4.52612C10.2553 4.55077 10.3117 4.58757 10.3593 4.63435C10.4068 4.68112 10.4445 4.73694 10.4701 4.7985C10.4958 4.86006 10.5088 4.92612 10.5085 4.99281C10.5083 5.05949 10.4946 5.12545 10.4685 5.18679C10.4423 5.24813 10.4042 5.30363 10.3563 5.35L5.14937 10.6444C5.10276 10.6906 5.0657 10.7456 5.04033 10.8062C5.01496 10.8667 5.00177 10.9317 5.00151 10.9974C5.00124 11.0631 5.01392 11.1281 5.03881 11.1889C5.0637 11.2497 5.10031 11.3049 5.14656 11.3516C5.19281 11.3982 5.24779 11.4352 5.30836 11.4606C5.36893 11.486 5.43391 11.4992 5.49957 11.4994C5.56524 11.4997 5.63032 11.487 5.69109 11.4621C5.75186 11.4372 5.80713 11.4006 5.85375 11.3544L12.0581 5.0625C12.3399 4.78129 12.4985 4.39965 12.4989 4.00155C12.4993 3.60344 12.3415 3.22148 12.0603 2.93969C11.7791 2.65789 11.3975 2.49936 10.9994 2.49894C10.6013 2.49853 10.2193 2.65629 9.9375 2.9375L3.735 9.23C3.50264 9.46199 3.31825 9.73747 3.19236 10.0407C3.06647 10.344 3.00154 10.669 3.00128 10.9974C3.00102 11.3257 3.06543 11.6509 3.19084 11.9544C3.31625 12.2578 3.5002 12.5336 3.73219 12.7659C3.96418 12.9983 4.23966 13.1827 4.54291 13.3086C4.84616 13.4345 5.17123 13.4994 5.49957 13.4997C5.82792 13.4999 6.15309 13.4355 6.45654 13.3101C6.75999 13.1847 7.03577 13.0007 7.26813 12.7688L12.3969 7.64375C12.491 7.55038 12.6183 7.4982 12.7508 7.49867C12.8834 7.49914 13.0103 7.55222 13.1038 7.64625Z" fill="var(--fill-0, #181818)"/>
</g>
</svg>
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M14.2934 7.36678L8.1667 13.4934C7.41613 14.244 6.39815 14.6657 5.3367 14.6657C4.27524 14.6657 3.25726 14.244 2.5067 13.4934C1.75613 12.7429 1.33447 11.7249 1.33447 10.6634C1.33447 9.60199 1.75613 8.584 2.5067 7.83344L8.63336 1.70678C9.13374 1.2064 9.81239 0.925293 10.52 0.925293C11.2277 0.925293 11.9063 1.2064 12.4067 1.70678C12.9071 2.20715 13.1882 2.8858 13.1882 3.59344C13.1882 4.30108 12.9071 4.97973 12.4067 5.48011L6.27336 11.6068C6.02318 11.857 5.68385 11.9975 5.33003 11.9975C4.97621 11.9975 4.63688 11.857 4.3867 11.6068C4.13651 11.3566 3.99596 11.0173 3.99596 10.6634C3.99596 10.3096 4.13651 9.9703 4.3867 9.72011L10.0467 4.06678" stroke="#666666" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 841 B

View File

@@ -0,0 +1,10 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_1422_6372)">
<path d="M2.15137 1.45605C2.2384 1.4608 2.32383 1.48265 2.40234 1.52051C2.48057 1.55827 2.55064 1.61092 2.6084 1.67578L13.8076 13.9902C13.8671 14.0541 13.9131 14.13 13.9434 14.2119C13.9736 14.2938 13.988 14.3806 13.9844 14.4678C13.9807 14.555 13.9598 14.6407 13.9229 14.7197C13.8859 14.7988 13.8332 14.87 13.7686 14.9287C13.7039 14.9874 13.6281 15.0323 13.5459 15.0615C13.4636 15.0908 13.3763 15.1033 13.2891 15.0986C13.2019 15.0939 13.1167 15.0721 13.0381 15.0342C12.9595 14.9963 12.889 14.9432 12.8311 14.8779V14.877L9.56445 11.2852L6.11035 14.7373C5.99744 14.851 5.86289 14.9416 5.71484 15.0029C5.60399 15.0488 5.48716 15.0783 5.36816 15.0898L5.24805 15.0947H2.12012C1.79679 15.0947 1.48656 14.9667 1.25781 14.7383C1.02902 14.5096 0.900391 14.1985 0.900391 13.875V10.748C0.899964 10.588 0.930956 10.4292 0.992188 10.2812C1.05347 10.1333 1.1433 9.99873 1.25684 9.88574L4.94141 6.2002L1.63184 2.56348V2.5625C1.57283 2.49884 1.52619 2.4242 1.49609 2.34277C1.46594 2.261 1.45242 2.174 1.45605 2.08691C1.4597 1.99969 1.48059 1.91404 1.51758 1.83496C1.55458 1.75587 1.60724 1.6847 1.67188 1.62598C1.73645 1.56737 1.81236 1.5224 1.89453 1.49316C1.97674 1.46395 2.06425 1.45137 2.15137 1.45605ZM2.21973 10.79V13.7754H5.20703L8.6748 10.3105L5.83008 7.18359L2.21973 10.79ZM10.752 0.900391C10.9121 0.900426 11.0708 0.931892 11.2188 0.993164C11.3665 1.05441 11.5011 1.14376 11.6143 1.25684L14.7422 4.38379C14.8554 4.49697 14.9455 4.63142 15.0068 4.7793C15.0681 4.92722 15.0996 5.08598 15.0996 5.24609C15.0996 5.40625 15.0681 5.56493 15.0068 5.71289C14.9455 5.86087 14.8555 5.99515 14.7422 6.1084L11.6406 9.21191C11.5166 9.33559 11.348 9.40453 11.1729 9.4043C10.9977 9.40405 10.8298 9.33396 10.7061 9.20996C10.5825 9.08598 10.5134 8.9182 10.5137 8.74316C10.5139 8.56807 10.583 8.40003 10.707 8.27637L11.2656 7.7168L8.2793 4.73145L7.90625 5.10645C7.78255 5.23018 7.61443 5.2997 7.43945 5.2998C7.26443 5.29988 7.09649 5.23011 6.97266 5.10645C6.84882 4.98275 6.77937 4.81467 6.7793 4.63965C6.77929 4.55319 6.79608 4.4676 6.8291 4.3877C6.86223 4.30764 6.91043 4.23414 6.97168 4.17285H6.97266L9.88867 1.25684C10.0019 1.1436 10.1372 1.05445 10.2852 0.993164C10.4331 0.931918 10.5918 0.900391 10.752 0.900391ZM9.21289 3.79883L12.1992 6.78418L13.7373 5.24609L10.751 2.25977L9.21289 3.79883Z" fill="#858585" stroke="#858585" stroke-width="0.2"/>
</g>
<defs>
<clipPath id="clip0_1422_6372">
<rect width="16" height="16" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@@ -0,0 +1,7 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12 5.33325C13.1046 5.33325 14 4.43782 14 3.33325C14 2.22868 13.1046 1.33325 12 1.33325C10.8954 1.33325 10 2.22868 10 3.33325C10 4.43782 10.8954 5.33325 12 5.33325Z" stroke="#666666" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M4 10C5.10457 10 6 9.10457 6 8C6 6.89543 5.10457 6 4 6C2.89543 6 2 6.89543 2 8C2 9.10457 2.89543 10 4 10Z" stroke="#666666" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M12 14.6667C13.1046 14.6667 14 13.7713 14 12.6667C14 11.5622 13.1046 10.6667 12 10.6667C10.8954 10.6667 10 11.5622 10 12.6667C10 13.7713 10.8954 14.6667 12 14.6667Z" stroke="#666666" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M5.72656 9.00659L10.2799 11.6599" stroke="#666666" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M10.2732 4.34009L5.72656 6.99342" stroke="#666666" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="33.34" height="32" viewBox="0 0 25 24"><!-- Icon from Lineicons by Lineicons - https://github.com/LineiconsHQ/Lineicons/blob/main/LICENSE.md --><path fill="currentColor" d="M9.25 4.5a.75.75 0 0 1 .686.445l6 13.5a.75.75 0 1 1-1.371.61l-1.728-3.888H5.663l-1.727 3.887a.75.75 0 0 1-1.371-.609l6-13.5A.75.75 0 0 1 9.25 4.5m0 2.597l-2.92 6.57h5.84zM22.28 5.78a.75.75 0 1 0-1.06-1.06L17.738 8.2l-1.41-1.411a.75.75 0 1 0-1.061 1.06l1.941 1.942a.75.75 0 0 0 1.06 0z"/></svg>

After

Width:  |  Height:  |  Size: 513 B

View File

@@ -0,0 +1,3 @@
<svg width="16" height="18" viewBox="0 0 16 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M13.9937 16L11.3632 13.3695C11.1396 13.4989 10.9072 13.6166 10.6662 13.7226C10.4247 13.8285 10.1686 13.9168 9.89786 13.9874V12.5044C9.96847 12.4809 10.0391 12.4545 10.1097 12.4253C10.1803 12.3957 10.2509 12.3632 10.3216 12.3279L4.67213 6.67844C4.54266 6.97268 4.43956 7.27586 4.36282 7.58799C4.28656 7.89965 4.24842 8.22026 4.24842 8.54981C4.24842 9.07944 4.34847 9.59425 4.54855 10.0942C4.74863 10.5947 5.06053 11.0567 5.48424 11.4805L5.66078 11.657V9.92686H7.07314V14.1639H2.83607V12.7516H4.77806L4.49559 12.5044C3.91887 11.9277 3.49799 11.3011 3.23294 10.6246C2.96836 9.94757 2.83607 9.25599 2.83607 8.54981C2.83607 8.02018 2.90362 7.51102 3.03874 7.02235C3.17433 6.53414 3.37158 6.0723 3.63052 5.63682L1 3.0063L2.00631 2L15 14.9937L13.9937 16ZM13.3758 11.3569L12.3165 10.2976C12.446 10.0151 12.546 9.72089 12.6166 9.41488C12.6873 9.10887 12.7226 8.79697 12.7226 8.47919C12.7226 7.94956 12.6225 7.43452 12.4224 6.93407C12.2224 6.4341 11.9105 5.97226 11.4868 5.54855L11.3102 5.372V7.10214H9.89786V2.86507H14.1349V4.27743H12.1929L12.4754 4.52459C13.0521 5.1013 13.473 5.72792 13.7381 6.40444C14.0026 7.08143 14.1349 7.77301 14.1349 8.47919C14.1349 9.00883 14.0671 9.51186 13.9316 9.9883C13.7964 10.4652 13.6112 10.9214 13.3758 11.3569ZM6.7024 4.68348L5.64313 3.62421C5.86675 3.49475 6.09626 3.38293 6.33165 3.28878C6.56704 3.19462 6.81421 3.11223 7.07314 3.04161V4.52459C7.01429 4.54813 6.95262 4.57167 6.88812 4.59521C6.82315 4.61875 6.76124 4.64817 6.7024 4.68348Z" fill="#858585"/>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M6.6665 1.33337L5.99984 2.00004H2.6665V3.33337H3.33317V13.3334C3.33317 13.6815 3.46072 14.0364 3.71208 14.2878C3.96343 14.5392 4.31836 14.6667 4.6665 14.6667H11.3332C11.6813 14.6667 12.0362 14.5392 12.2876 14.2878C12.539 14.0364 12.6665 13.6815 12.6665 13.3334V3.33337H13.3332V2.00004H9.99984L9.33317 1.33337H6.6665ZM4.6665 3.33337H11.3332V13.3334H4.6665V3.33337ZM5.99984 4.66671V12H7.33317V4.66671H5.99984ZM8.6665 4.66671V12H9.99984V4.66671H8.6665Z" fill="#FB2C36"/>
</svg>

After

Width:  |  Height:  |  Size: 580 B

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1132,6 +1132,8 @@ $day$: Current day (eg. Monday)`,
start: () => t`Start`,
customization: () => t`Customization`,
appearance: () => t`Appearance`,
preferences: () => t`Preferences`,
actionsHeading: () => t`Actions`,
appearanceDesc: () =>
t`Customize the appearance of the app with custom themes`,
themes: () => t`Themes`,
@@ -2513,10 +2515,10 @@ Use this if changes from other devices are not appearing on this device. This wi
addToNotebook: () => t`Add to notebook`,
notebookAdded: () => t`Notebook added`,
addNotes: () => t`Add notes`,
setAsHomepage: () => t`Set as homepage`,
setAsHomepage: () => t`Set as home`,
defaultSidebarTab: () => t`Default sidebar tab`,
defaultSidebarTabDesc: () => t`Select the default sidebar tab`,
unsetAsHomepage: () => t`Reset homepage`,
unsetAsHomepage: () => t`Reset home`,
archive: () => t`Archive`,
yourArchiveIsEmpty: () => t`Your archive is empty`,
unarchive: () => t`Unarchive`,
@@ -2953,5 +2955,6 @@ Continue without attachments?`,
downloadLogsFailedDesc: () =>
t`Something went wrong while preparing your debug logs. This can happen if no storage location was selected.`,
shareZip: () => t`Share ZIP`,
tryDownloadLogsAgain: () => t`Try again`
tryDownloadLogsAgain: () => t`Try again`,
createSubnotebook: () => t`Create sub-notebook`
};