mobile: add support for sorting topics in sheet

This commit is contained in:
ammarahm-ed
2023-03-30 01:42:39 +05:00
committed by Ammar Ahmed
parent 783460c685
commit 9605eafa00
4 changed files with 157 additions and 90 deletions

View File

@@ -32,6 +32,7 @@ import Seperator from "../../ui/seperator";
import Heading from "../../ui/typography/heading";
const Sort = ({ type, screen }) => {
const colors = useThemeStore((state) => state.colors);
const isTopicSheet = screen === "TopicSheet";
const [groupOptions, setGroupOptions] = useState(
db.settings.getGroupOptions(type)
);
@@ -41,7 +42,7 @@ const Sort = ({ type, screen }) => {
layoutmanager.withSpringAnimation(600);
setGroupOptions(_groupOptions);
setTimeout(() => {
Navigation.queueRoutesForUpdate(screen);
if (screen !== "TopicSheet") Navigation.queueRoutesForUpdate(screen);
eSendEvent("groupOptionsUpdate");
eSendEvent(refreshNotesPage);
}, 1);
@@ -52,6 +53,9 @@ const Sort = ({ type, screen }) => {
...groupOptions,
sortDirection: groupOptions.sortDirection === "asc" ? "desc" : "asc"
};
if (type === "topics") {
_groupOptions.groupBy = "none";
}
await updateGroupOptions(_groupOptions);
};
@@ -119,7 +123,7 @@ const Sort = ({ type, screen }) => {
flexDirection: "row",
justifyContent: "flex-start",
flexWrap: "wrap",
borderBottomWidth: 1,
borderBottomWidth: isTopicSheet ? 0 : 1,
borderBottomColor: colors.nav,
marginBottom: 12,
paddingHorizontal: 12,
@@ -166,6 +170,9 @@ const Sort = ({ type, screen }) => {
...groupOptions,
sortBy: type === "trash" ? "dateDeleted" : item
};
if (type === "topics") {
_groupOptions.groupBy = "none";
}
await updateGroupOptions(_groupOptions);
}}
iconSize={SIZE.md}
@@ -175,64 +182,70 @@ const Sort = ({ type, screen }) => {
)}
</View>
<Heading
style={{
marginLeft: 12
}}
size={SIZE.lg}
>
Group by
</Heading>
<Seperator />
<View
style={{
borderRadius: 0,
flexDirection: "row",
flexWrap: "wrap",
paddingHorizontal: 12
}}
>
{Object.keys(GROUP).map((item) => (
<Button
key={item}
testID={"btn-" + item}
type={groupOptions.groupBy === GROUP[item] ? "grayBg" : "gray"}
buttonType={{
text:
groupOptions.groupBy === GROUP[item]
? colors.accent
: colors.icon
}}
onPress={async () => {
let _groupOptions = {
...groupOptions,
groupBy: GROUP[item]
};
if (item === "abc") {
_groupOptions.sortBy = "title";
_groupOptions.sortDirection = "asc";
} else {
if (groupOptions.sortBy === "title") {
_groupOptions.sortBy = "dateEdited";
_groupOptions.sortDirection = "desc";
}
}
updateGroupOptions(_groupOptions);
}}
height={40}
icon={groupOptions.groupBy === GROUP[item] ? "check" : null}
title={item.slice(0, 1).toUpperCase() + item.slice(1, item.length)}
{isTopicSheet ? null : (
<>
<Heading
style={{
paddingHorizontal: 8,
marginBottom: 10,
marginRight: 10
marginLeft: 12
}}
/>
))}
</View>
size={SIZE.lg}
>
Group by
</Heading>
<Seperator />
<View
style={{
borderRadius: 0,
flexDirection: "row",
flexWrap: "wrap",
paddingHorizontal: 12
}}
>
{Object.keys(GROUP).map((item) => (
<Button
key={item}
testID={"btn-" + item}
type={groupOptions.groupBy === GROUP[item] ? "grayBg" : "gray"}
buttonType={{
text:
groupOptions.groupBy === GROUP[item]
? colors.accent
: colors.icon
}}
onPress={async () => {
let _groupOptions = {
...groupOptions,
groupBy: GROUP[item]
};
if (item === "abc") {
_groupOptions.sortBy = "title";
_groupOptions.sortDirection = "asc";
} else {
if (groupOptions.sortBy === "title") {
_groupOptions.sortBy = "dateEdited";
_groupOptions.sortDirection = "desc";
}
}
updateGroupOptions(_groupOptions);
}}
height={40}
icon={groupOptions.groupBy === GROUP[item] ? "check" : null}
title={
item.slice(0, 1).toUpperCase() + item.slice(1, item.length)
}
style={{
paddingHorizontal: 8,
marginBottom: 10,
marginRight: 10
}}
/>
))}
</View>
</>
)}
</View>
);
};

View File

@@ -19,6 +19,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
import qclone from "qclone";
import React, {
createContext,
useCallback,
useContext,
useEffect,
useRef,
@@ -37,7 +38,8 @@ import { TopicNotes } from "../../../screens/notes/topic-notes";
import {
eSendEvent,
eSubscribeEvent,
eUnSubscribeEvent
eUnSubscribeEvent,
presentSheet
} from "../../../services/event-manager";
import useNavigationStore, {
NotebookScreenParams
@@ -49,7 +51,7 @@ import {
eOpenAddTopicDialog
} from "../../../utils/events";
import { normalize, SIZE } from "../../../utils/size";
import { NotebookType, TopicType } from "../../../utils/types";
import { GroupHeader, NotebookType, TopicType } from "../../../utils/types";
import Icon from "react-native-vector-icons/MaterialCommunityIcons";
import { openEditor } from "../../../screens/notes/common";
@@ -59,6 +61,8 @@ import { deleteItems } from "../../../utils/functions";
import { presentDialog } from "../../dialog/functions";
import Config from "react-native-config";
import { notesnook } from "../../../../e2e/test.ids";
import Sort from "../sort";
import { groupArray } from "@notesnook/core/utils/grouping";
export const TopicsSheet = () => {
const currentScreen = useNavigationStore((state) => state.currentScreen);
@@ -75,12 +79,33 @@ export const TopicsSheet = () => {
const [enabled, setEnabled] = useState(false);
const colors = useThemeStore((state) => state.colors);
const ref = useRef<ActionSheetRef>(null);
const [topics, setTopics] = useState(notebook ? qclone(notebook.topics) : []);
const [topics, setTopics] = useState(
notebook
? qclone(
groupArray(notebook.topics, db.settings?.getGroupOptions("topics"))
)
: []
);
const [animations] = useState({
translate: new Animated.Value(0),
display: new Animated.Value(-5000),
opacity: new Animated.Value(0)
});
const [groupOptions, setGroupOptions] = useState(
db.settings?.getGroupOptions("topics")
);
const onUpdate = useCallback(() => {
setGroupOptions({ ...(db.settings?.getGroupOptions("topics") as any) });
}, []);
useEffect(() => {
eSubscribeEvent("groupOptionsUpdate", onUpdate);
return () => {
eUnSubscribeEvent("groupOptionsUpdate", onUpdate);
};
}, [onUpdate]);
const onRequestUpdate = React.useCallback(
(data?: NotebookScreenParams) => {
if (!canShow) return;
@@ -89,10 +114,11 @@ export const TopicsSheet = () => {
?.data as NotebookType;
if (_notebook) {
setNotebook(_notebook);
setTopics(qclone(_notebook.topics));
setTopics(qclone(groupArray(_notebook.topics, groupOptions)));
}
},
[notebook, canShow]
[canShow, notebook, groupOptions]
);
useEffect(() => {
@@ -117,9 +143,16 @@ export const TopicsSheet = () => {
loading: "Loading notebook topics"
};
const renderTopic = ({ item, index }: { item: TopicType; index: number }) => (
<TopicItem item={item} index={index} />
);
const renderTopic = ({
item,
index
}: {
item: TopicType | GroupHeader;
index: number;
}) =>
(item as GroupHeader).type === "header" ? null : (
<TopicItem item={item as TopicType} index={index} />
);
const selectionContext = {
selection: selection,
@@ -191,7 +224,7 @@ export const TopicsSheet = () => {
backgroundColor: colors.nav
}}
keyboardHandlerEnabled={false}
snapPoints={Config.isTesting === "true" ? [100] : [15, 100]}
snapPoints={Config.isTesting === "true" ? [100] : [25, 100]}
initialSnapIndex={0}
backgroundInteractionEnabled
onChange={(position, height) => {
@@ -304,17 +337,38 @@ export const TopicsSheet = () => {
size={22}
/>
) : (
<IconButton
name="plus"
onPress={PLACEHOLDER_DATA.action}
testID="add-topic-button"
color={colors.pri}
size={22}
customStyle={{
width: 40,
height: 40
}}
/>
<>
<IconButton
name={
groupOptions?.sortDirection === "asc"
? "sort-ascending"
: "sort-descending"
}
onPress={() => {
presentSheet({
component: <Sort screen="TopicSheet" type="topics" />
});
}}
testID="group-topic-button"
color={colors.pri}
size={22}
customStyle={{
width: 40,
height: 40
}}
/>
<IconButton
name="plus"
onPress={PLACEHOLDER_DATA.action}
testID="add-topic-button"
color={colors.pri}
size={22}
customStyle={{
width: 40,
height: 40
}}
/>
</>
)}
</View>
</View>
@@ -334,7 +388,7 @@ export const TopicsSheet = () => {
progressBackgroundColor={colors.bg}
/>
}
keyExtractor={(item) => item.id}
keyExtractor={(item) => (item as TopicType).id}
renderItem={renderTopic}
ListEmptyComponent={
<View

View File

@@ -15,7 +15,7 @@
"html-to-text": "8.1.0",
"phone": "^3.1.14",
"qclone": "^1.2.0",
"react-native-actions-sheet": "0.9.0-alpha.15",
"react-native-actions-sheet": "0.9.0-alpha.16",
"react-native-check-version": "https://github.com/flexible-agency/react-native-check-version",
"react-native-drax": "^0.10.2",
"react-native-image-zoom-viewer": "^3.0.1",

View File

@@ -1,12 +1,12 @@
{
"name": "@notesnook/mobile",
"version": "2.4.8",
"version": "2.4.9",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@notesnook/mobile",
"version": "2.4.8",
"version": "2.4.9",
"license": "GPL-3.0-or-later",
"workspaces": [
"native/",
@@ -42,7 +42,7 @@
"qclone": "^1.2.0",
"react": "18.0.0",
"react-native": "0.69.7",
"react-native-actions-sheet": "0.9.0-alpha.15",
"react-native-actions-sheet": "0.9.0-alpha.16",
"react-native-check-version": "https://github.com/flexible-agency/react-native-check-version",
"react-native-drax": "^0.10.2",
"react-native-image-zoom-viewer": "^3.0.1",
@@ -17957,9 +17957,9 @@
}
},
"node_modules/react-native-actions-sheet": {
"version": "0.9.0-alpha.15",
"resolved": "https://registry.npmjs.org/react-native-actions-sheet/-/react-native-actions-sheet-0.9.0-alpha.15.tgz",
"integrity": "sha512-lcwk7Z1yDZq3c3DITdDmrWEj9eTlBbFo+lvUR9qGbvW7V2VJCSobn0B984b6t8s0nihufmXpafrdNhkRwbBtNg==",
"version": "0.9.0-alpha.16",
"resolved": "https://registry.npmjs.org/react-native-actions-sheet/-/react-native-actions-sheet-0.9.0-alpha.16.tgz",
"integrity": "sha512-/aR+MsJR1IgeZIg7elD2Zu/6In7Ztsvt4fPeOt2sM++FmsAofprsJ4JHjwPFEO06E5djS8ky8VvpaeCrC8HoFg==",
"peerDependencies": {
"react-native": "*",
"react-native-gesture-handler": "*"
@@ -24312,7 +24312,7 @@
"qclone": "^1.2.0",
"react": "18.0.0",
"react-native": "0.69.7",
"react-native-actions-sheet": "0.9.0-alpha.15",
"react-native-actions-sheet": "0.9.0-alpha.16",
"react-native-check-version": "https://github.com/flexible-agency/react-native-check-version",
"react-native-drax": "^0.10.2",
"react-native-image-zoom-viewer": "^3.0.1",
@@ -34856,9 +34856,9 @@
}
},
"react-native-actions-sheet": {
"version": "0.9.0-alpha.15",
"resolved": "https://registry.npmjs.org/react-native-actions-sheet/-/react-native-actions-sheet-0.9.0-alpha.15.tgz",
"integrity": "sha512-lcwk7Z1yDZq3c3DITdDmrWEj9eTlBbFo+lvUR9qGbvW7V2VJCSobn0B984b6t8s0nihufmXpafrdNhkRwbBtNg=="
"version": "0.9.0-alpha.16",
"resolved": "https://registry.npmjs.org/react-native-actions-sheet/-/react-native-actions-sheet-0.9.0-alpha.16.tgz",
"integrity": "sha512-/aR+MsJR1IgeZIg7elD2Zu/6In7Ztsvt4fPeOt2sM++FmsAofprsJ4JHjwPFEO06E5djS8ky8VvpaeCrC8HoFg=="
},
"react-native-actions-shortcuts": {
"version": "1.0.1",