mirror of
https://github.com/streetwriters/notesnook.git
synced 2026-09-01 19:49:54 +02:00
mobile: fix bugs
This commit is contained in:
@@ -51,19 +51,11 @@ export const Header = React.memo(
|
||||
{announcements.length !== 0 && !noAnnouncement ? (
|
||||
<Announcement color={color || colors.primary.accent} />
|
||||
) : (screen as any) === "Search" ? null : !shouldShow ? (
|
||||
<View
|
||||
style={{
|
||||
marginBottom: 5,
|
||||
padding: 0,
|
||||
width: "100%",
|
||||
justifyContent: "center",
|
||||
alignItems: "center"
|
||||
}}
|
||||
>
|
||||
<>
|
||||
{messageCard ? (
|
||||
<Card color={color || colors.primary.accent} />
|
||||
) : null}
|
||||
</View>
|
||||
</>
|
||||
) : null}
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -405,7 +405,7 @@ const NoteItem = ({
|
||||
</>
|
||||
) : null}
|
||||
|
||||
{selectionMode ? (
|
||||
{selectionMode === "note" || selectionMode === "trash" ? (
|
||||
<>
|
||||
<AppIcon
|
||||
name={selected ? "checkbox-outline" : "checkbox-blank-outline"}
|
||||
|
||||
@@ -31,6 +31,9 @@ import { IconButton } from "../../ui/icon-button";
|
||||
import Heading from "../../ui/typography/heading";
|
||||
import Paragraph from "../../ui/typography/paragraph";
|
||||
import { strings } from "@notesnook/intl";
|
||||
import { useSelectionStore } from "../../../stores/use-selection-store";
|
||||
import useIsSelected from "../../../hooks/use-selected";
|
||||
import AppIcon from "../../ui/AppIcon";
|
||||
|
||||
type NotebookItemProps = {
|
||||
item: Notebook | BaseTrashItem<Notebook>;
|
||||
@@ -50,6 +53,8 @@ export const NotebookItem = ({
|
||||
const compactMode = useIsCompactModeEnabled(
|
||||
(item as TrashItem).itemType || item.type
|
||||
);
|
||||
const selectionMode = useSelectionStore((state) => state.selectionMode);
|
||||
const [selected] = useIsSelected(item);
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -185,21 +190,30 @@ export const NotebookItem = ({
|
||||
</Paragraph>
|
||||
</>
|
||||
) : null}
|
||||
|
||||
<IconButton
|
||||
color={colors.primary.heading}
|
||||
name="dots-horizontal"
|
||||
testID={notesnook.ids.notebook.menu}
|
||||
size={AppFontSize.xl}
|
||||
onPress={() => Properties.present(item)}
|
||||
style={{
|
||||
justifyContent: "center",
|
||||
height: 35,
|
||||
width: 35,
|
||||
borderRadius: 100,
|
||||
alignItems: "center"
|
||||
}}
|
||||
/>
|
||||
{selectionMode === "notebook" || selectionMode === "trash" ? (
|
||||
<>
|
||||
<AppIcon
|
||||
name={selected ? "checkbox-outline" : "checkbox-blank-outline"}
|
||||
color={selected ? colors.selected.icon : colors.primary.icon}
|
||||
size={AppFontSize.lg}
|
||||
/>
|
||||
</>
|
||||
) : (
|
||||
<IconButton
|
||||
color={colors.primary.heading}
|
||||
name="dots-horizontal"
|
||||
testID={notesnook.ids.notebook.menu}
|
||||
size={AppFontSize.xl}
|
||||
onPress={() => Properties.present(item)}
|
||||
style={{
|
||||
justifyContent: "center",
|
||||
height: 35,
|
||||
width: 35,
|
||||
borderRadius: 100,
|
||||
alignItems: "center"
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</View>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -31,6 +31,9 @@ import Heading from "../../ui/typography/heading";
|
||||
import Paragraph from "../../ui/typography/paragraph";
|
||||
import SelectionWrapper, { selectItem } from "../selection-wrapper";
|
||||
import { strings } from "@notesnook/intl";
|
||||
import { useSelectionStore } from "../../../stores/use-selection-store";
|
||||
import useIsSelected from "../../../hooks/use-selected";
|
||||
import AppIcon from "../../ui/AppIcon";
|
||||
|
||||
const ReminderItem = React.memo(
|
||||
({
|
||||
@@ -48,6 +51,8 @@ const ReminderItem = React.memo(
|
||||
|
||||
ReminderSheet.present(item, undefined, isSheet);
|
||||
};
|
||||
const selectionMode = useSelectionStore((state) => state.selectionMode);
|
||||
const [selected] = useIsSelected(item);
|
||||
return (
|
||||
<SelectionWrapper onPress={openReminder} item={item} isSheet={isSheet}>
|
||||
<View
|
||||
@@ -156,20 +161,31 @@ const ReminderItem = React.memo(
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
<IconButton
|
||||
testID={notesnook.listitem.menu}
|
||||
color={colors.primary.paragraph}
|
||||
name="dots-horizontal"
|
||||
size={AppFontSize.xl}
|
||||
onPress={() => Properties.present(item, isSheet)}
|
||||
style={{
|
||||
justifyContent: "center",
|
||||
height: 35,
|
||||
width: 35,
|
||||
borderRadius: 100,
|
||||
alignItems: "center"
|
||||
}}
|
||||
/>
|
||||
|
||||
{selectionMode === "note" || selectionMode === "trash" ? (
|
||||
<>
|
||||
<AppIcon
|
||||
name={selected ? "checkbox-outline" : "checkbox-blank-outline"}
|
||||
color={selected ? colors.selected.icon : colors.primary.icon}
|
||||
size={AppFontSize.lg}
|
||||
/>
|
||||
</>
|
||||
) : (
|
||||
<IconButton
|
||||
testID={notesnook.listitem.menu}
|
||||
color={colors.primary.paragraph}
|
||||
name="dots-horizontal"
|
||||
size={AppFontSize.xl}
|
||||
onPress={() => Properties.present(item, isSheet)}
|
||||
style={{
|
||||
justifyContent: "center",
|
||||
height: 35,
|
||||
width: 35,
|
||||
borderRadius: 100,
|
||||
alignItems: "center"
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</SelectionWrapper>
|
||||
);
|
||||
},
|
||||
|
||||
@@ -26,7 +26,7 @@ import {
|
||||
NativeSyntheticEvent,
|
||||
RefreshControl
|
||||
} from "react-native";
|
||||
import Animated, { FadeInDown } from "react-native-reanimated";
|
||||
import Animated, { FadeIn } from "react-native-reanimated";
|
||||
import { notesnook } from "../../../e2e/test.ids";
|
||||
import { useGroupOptions } from "../../hooks/use-group-options";
|
||||
import { eSendEvent } from "../../services/event-manager";
|
||||
@@ -149,7 +149,7 @@ export default function List(props: ListProps) {
|
||||
style={{
|
||||
flex: 1
|
||||
}}
|
||||
entering={props.renderedInRoute === "Search" ? undefined : FadeInDown}
|
||||
entering={props.renderedInRoute === "Search" ? undefined : FadeIn}
|
||||
>
|
||||
<ListView
|
||||
style={styles}
|
||||
|
||||
@@ -29,11 +29,11 @@ import {
|
||||
} from "react-native";
|
||||
import { Menu } from "react-native-material-menu";
|
||||
import { db } from "../../common/database";
|
||||
import useGlobalSafeAreaInsets from "../../hooks/use-global-safe-area-insets";
|
||||
import { ToastManager } from "../../services/event-manager";
|
||||
import Navigation from "../../services/navigation";
|
||||
import useNavigationStore from "../../stores/use-navigation-store";
|
||||
import { useSelectionStore } from "../../stores/use-selection-store";
|
||||
import { useTrashStore } from "../../stores/use-trash-store";
|
||||
import { deleteItems } from "../../utils/functions";
|
||||
import { fluidTabsRef } from "../../utils/global-refs";
|
||||
import { updateNotebook } from "../../utils/notebooks";
|
||||
@@ -60,14 +60,12 @@ export const SelectionHeader = React.memo(
|
||||
renderedInRoute?: string;
|
||||
}) => {
|
||||
const menuRef = useRef<Menu>(null);
|
||||
const { colors: contextMenuColors } = useThemeColors("contextMenu");
|
||||
const { colors } = useThemeColors();
|
||||
const selectionMode = useSelectionStore((state) => state.selectionMode);
|
||||
const selectedItemsList = useSelectionStore(
|
||||
(state) => state.selectedItemsList
|
||||
);
|
||||
const clearSelection = useSelectionStore((state) => state.clearSelection);
|
||||
const insets = useGlobalSafeAreaInsets();
|
||||
const allSelected =
|
||||
items?.placeholders?.length === selectedItemsList.length;
|
||||
const focusedRouteId = useNavigationStore((state) => state.focusedRouteId);
|
||||
@@ -102,8 +100,11 @@ export const SelectionHeader = React.memo(
|
||||
const deleteItem = async () => {
|
||||
if (!type) return;
|
||||
presentDialog({
|
||||
title: strings.doActions.delete.unknown(type, selectedItemsList.length),
|
||||
paragraph: strings.actionConfirmations.delete.unknown(
|
||||
title: strings.doActions.permanentlyDelete.unknown(
|
||||
type,
|
||||
selectedItemsList.length
|
||||
),
|
||||
paragraph: strings.actionConfirmations.permanentlyDelete.unknown(
|
||||
type,
|
||||
selectedItemsList.length
|
||||
),
|
||||
@@ -112,7 +113,7 @@ export const SelectionHeader = React.memo(
|
||||
positivePress: async () => {
|
||||
if (!selectedItemsList.length) return;
|
||||
await db.trash.delete(...selectedItemsList);
|
||||
Navigation.queueRoutesForUpdate();
|
||||
useTrashStore.getState().refresh();
|
||||
clearSelection();
|
||||
},
|
||||
positiveType: "errorShade"
|
||||
|
||||
@@ -29,14 +29,12 @@ import { hideAllTooltips } from "../hooks/use-tooltip";
|
||||
import Favorites from "../screens/favorites";
|
||||
import Home from "../screens/home";
|
||||
import NotebookScreen from "../screens/notebook";
|
||||
import Notebooks from "../screens/notebooks";
|
||||
import { ColoredNotes } from "../screens/notes/colored";
|
||||
import { Monographs } from "../screens/notes/monographs";
|
||||
import { TaggedNotes } from "../screens/notes/tagged";
|
||||
import Reminders from "../screens/reminders";
|
||||
import { Search } from "../screens/search";
|
||||
import Settings from "../screens/settings";
|
||||
import Tags from "../screens/tags";
|
||||
import Trash from "../screens/trash";
|
||||
import SettingsService from "../services/settings";
|
||||
import useNavigationStore, {
|
||||
@@ -72,10 +70,8 @@ const AppNavigation = React.memo(
|
||||
}}
|
||||
>
|
||||
<AppStack.Screen name="Notes" component={Home as any} />
|
||||
<AppStack.Screen name="Notebooks" component={Notebooks as any} />
|
||||
<AppStack.Screen name="Favorites" component={Favorites as any} />
|
||||
<AppStack.Screen name="Trash" component={Trash as any} />
|
||||
<AppStack.Screen name="Tags" component={Tags as any} />
|
||||
<AppStack.Screen name="TaggedNotes" component={TaggedNotes as any} />
|
||||
<AppStack.Screen name="ColoredNotes" component={ColoredNotes as any} />
|
||||
<AppStack.Screen name="Reminders" component={Reminders as any} />
|
||||
|
||||
@@ -1,119 +0,0 @@
|
||||
/*
|
||||
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 React, { useEffect } from "react";
|
||||
import { Config } from "react-native-config";
|
||||
import { FloatingButton } from "../../components/container/floating-button";
|
||||
import DelayLayout from "../../components/delay-layout";
|
||||
import { Header } from "../../components/header";
|
||||
import List from "../../components/list";
|
||||
import SelectionHeader from "../../components/selection-header";
|
||||
import { AddNotebookSheet } from "../../components/sheets/add-notebook";
|
||||
import { Walkthrough } from "../../components/walkthroughs";
|
||||
import { useNavigationFocus } from "../../hooks/use-navigation-focus";
|
||||
import Navigation, { NavigationProps } from "../../services/navigation";
|
||||
import SettingsService from "../../services/settings";
|
||||
import useNavigationStore from "../../stores/use-navigation-store";
|
||||
import { useNotebooks } from "../../stores/use-notebook-store";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
const onButtonPress = () => {
|
||||
AddNotebookSheet.present();
|
||||
};
|
||||
|
||||
export const Notebooks = ({
|
||||
navigation,
|
||||
route
|
||||
}: NavigationProps<"Notebooks">) => {
|
||||
const [notebooks, loading] = useNotebooks();
|
||||
|
||||
const isFocused = useNavigationFocus(navigation, {
|
||||
onFocus: (prev) => {
|
||||
Navigation.routeNeedsUpdate(
|
||||
route.name,
|
||||
Navigation.routeUpdateFunctions[route.name]
|
||||
);
|
||||
useNavigationStore.getState().setFocusedRouteId(route.name);
|
||||
return false;
|
||||
},
|
||||
onBlur: () => false,
|
||||
delay: SettingsService.get().homepage === route.name ? 1 : -1
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (notebooks?.placeholders) {
|
||||
if (notebooks?.placeholders?.length === 0 && !Config.isTesting) {
|
||||
Walkthrough.present("notebooks");
|
||||
} else {
|
||||
Walkthrough.update("notebooks");
|
||||
}
|
||||
}
|
||||
}, [notebooks]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<SelectionHeader
|
||||
id={route.name}
|
||||
items={notebooks}
|
||||
renderedInRoute={route.name}
|
||||
type="notebook"
|
||||
/>
|
||||
<Header
|
||||
renderedInRoute={route.name}
|
||||
title={strings.routes[route.name]()}
|
||||
canGoBack={route.params?.canGoBack}
|
||||
hasSearch={true}
|
||||
id={route.name}
|
||||
onSearch={() => {
|
||||
Navigation.push("Search", {
|
||||
placeholder: strings.searchInRoute(route.name),
|
||||
type: "notebook",
|
||||
title: route.name,
|
||||
route: route.name
|
||||
});
|
||||
}}
|
||||
onPressDefaultRightButton={onButtonPress}
|
||||
/>
|
||||
<DelayLayout wait={loading}>
|
||||
<List
|
||||
data={notebooks}
|
||||
dataType="notebook"
|
||||
renderedInRoute="Notebooks"
|
||||
loading={loading}
|
||||
placeholder={{
|
||||
title: strings.yourNotebooks(),
|
||||
paragraph: strings.notebooksEmpty(),
|
||||
button: strings.addFirstNotebook(),
|
||||
action: onButtonPress,
|
||||
loading: strings.loadingNotebooks()
|
||||
}}
|
||||
headerTitle={strings.routes[route.name]()}
|
||||
/>
|
||||
|
||||
{!notebooks ||
|
||||
notebooks.placeholders.length === 0 ||
|
||||
!isFocused ? null : (
|
||||
<FloatingButton onPress={onButtonPress} />
|
||||
)}
|
||||
</DelayLayout>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default Notebooks;
|
||||
@@ -1,88 +0,0 @@
|
||||
/*
|
||||
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 React from "react";
|
||||
import DelayLayout from "../../components/delay-layout";
|
||||
import { Header } from "../../components/header";
|
||||
import List from "../../components/list";
|
||||
import SelectionHeader from "../../components/selection-header";
|
||||
import { useNavigationFocus } from "../../hooks/use-navigation-focus";
|
||||
import Navigation, { NavigationProps } from "../../services/navigation";
|
||||
import SettingsService from "../../services/settings";
|
||||
import useNavigationStore from "../../stores/use-navigation-store";
|
||||
import { useTags } from "../../stores/use-tag-store";
|
||||
import { strings } from "@notesnook/intl";
|
||||
|
||||
export const Tags = ({ navigation, route }: NavigationProps<"Tags">) => {
|
||||
const [tags, loading] = useTags();
|
||||
const isFocused = useNavigationFocus(navigation, {
|
||||
onFocus: (prev) => {
|
||||
Navigation.routeNeedsUpdate(
|
||||
route.name,
|
||||
Navigation.routeUpdateFunctions[route.name]
|
||||
);
|
||||
useNavigationStore.getState().setFocusedRouteId(route.name);
|
||||
return !prev?.current;
|
||||
},
|
||||
onBlur: () => false,
|
||||
delay: SettingsService.get().homepage === route.name ? 1 : -1
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
<SelectionHeader
|
||||
id={route.name}
|
||||
items={tags}
|
||||
type="tag"
|
||||
renderedInRoute={route.name}
|
||||
/>
|
||||
<Header
|
||||
renderedInRoute={route.name}
|
||||
id={route.name}
|
||||
title={route.name}
|
||||
canGoBack={false}
|
||||
hasSearch={true}
|
||||
onSearch={() => {
|
||||
Navigation.push("Search", {
|
||||
placeholder: strings.searchInRoute(route.name),
|
||||
type: "tag",
|
||||
title: route.name,
|
||||
route: route.name
|
||||
});
|
||||
}}
|
||||
/>
|
||||
<DelayLayout wait={loading}>
|
||||
<List
|
||||
data={tags}
|
||||
dataType="tag"
|
||||
headerTitle="Tags"
|
||||
loading={!isFocused}
|
||||
renderedInRoute="Tags"
|
||||
placeholder={{
|
||||
title: strings.yourTags(),
|
||||
paragraph: strings.tagsEmpty(),
|
||||
loading: strings.loadingTags()
|
||||
}}
|
||||
/>
|
||||
</DelayLayout>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default Tags;
|
||||
Reference in New Issue
Block a user