mirror of
https://github.com/streetwriters/notesnook.git
synced 2026-09-01 11:39:21 +02:00
mobile: fix note item ui
This commit is contained in:
@@ -25,7 +25,7 @@ import {
|
||||
TrashItem
|
||||
} from "@notesnook/core";
|
||||
import { useThemeColors } from "@notesnook/theme";
|
||||
import { EntityLevel, decode } from "entities";
|
||||
import { decode, EntityLevel } from "entities";
|
||||
import React from "react";
|
||||
import { View } from "react-native";
|
||||
import { useIsCompactModeEnabled } from "../../../hooks/use-is-compact-mode-enabled";
|
||||
@@ -41,23 +41,23 @@ import {
|
||||
TagsWithDateEdited
|
||||
} from "@notesnook/common";
|
||||
import { strings } from "@notesnook/intl";
|
||||
import dayjs from "dayjs";
|
||||
import { create } from "zustand";
|
||||
import { notesnook } from "../../../../e2e/test.ids";
|
||||
import { FontFamily } from "../../../common/design/font";
|
||||
import { Radius, Spacing } from "../../../common/design/spacing";
|
||||
import useIsSelected from "../../../hooks/use-selected";
|
||||
import { useTabStore } from "../../../screens/editor/tiptap/use-tab-store";
|
||||
import { useSelectionStore } from "../../../stores/use-selection-store";
|
||||
import { DefaultAppStyles } from "../../../utils/styles";
|
||||
import { Properties } from "../../properties";
|
||||
import AppIcon from "../../ui/AppIcon";
|
||||
import { ExpiryDate } from "../../ui/expiry-date";
|
||||
import { IconButton } from "../../ui/icon-button";
|
||||
import { ReminderTime } from "../../ui/reminder-time";
|
||||
import { TimeSince } from "../../ui/time-since";
|
||||
import Heading from "../../ui/typography/heading";
|
||||
import Paragraph from "../../ui/typography/paragraph";
|
||||
import dayjs from "dayjs";
|
||||
import { ExpiryDate } from "../../ui/expiry-date";
|
||||
import { Radius, Spacing } from "../../../common/design/spacing";
|
||||
import { create } from "zustand";
|
||||
import { FontFamily } from "../../../common/design/font";
|
||||
|
||||
type NoteItemProps = {
|
||||
item: Note | BaseTrashItem<Note>;
|
||||
@@ -157,6 +157,16 @@ const NoteItem = ({
|
||||
}
|
||||
];
|
||||
|
||||
const activeStatusIcons = statusIcons.filter(
|
||||
(statusIcon) => statusIcon.condition
|
||||
);
|
||||
|
||||
const canShowTopStatusBar =
|
||||
attachmentsCount > 0 &&
|
||||
activeStatusIcons.length > 0 &&
|
||||
notebooks?.items?.length &&
|
||||
tags?.items.length;
|
||||
|
||||
return (
|
||||
<>
|
||||
<View
|
||||
@@ -166,7 +176,7 @@ const NoteItem = ({
|
||||
gap: compactMode ? undefined : Spacing.LEVEL_1
|
||||
}}
|
||||
>
|
||||
{compactMode ? null : (
|
||||
{compactMode || !canShowTopStatusBar || isTrash ? null : (
|
||||
<View
|
||||
style={{
|
||||
flexDirection: "row",
|
||||
@@ -178,177 +188,140 @@ const NoteItem = ({
|
||||
flexWrap: "wrap"
|
||||
}}
|
||||
>
|
||||
{!isTrash ? (
|
||||
<>
|
||||
{statusIcons
|
||||
.filter((statusIcon) => statusIcon.condition)
|
||||
.map((statusIcon) => (
|
||||
<View
|
||||
key={statusIcon.testID || statusIcon.name}
|
||||
style={{
|
||||
borderRadius: Radius.XXS,
|
||||
paddingHorizontal: 3,
|
||||
paddingVertical: 3,
|
||||
// borderWidth: 1,
|
||||
// borderColor: primaryColors.border,
|
||||
flexDirection: "row",
|
||||
alignItems: "center"
|
||||
}}
|
||||
>
|
||||
<AppIcon
|
||||
testID={statusIcon.testID}
|
||||
name={statusIcon.name}
|
||||
size={12}
|
||||
iconFamily="notesnook"
|
||||
color={statusIcon.color}
|
||||
/>
|
||||
</View>
|
||||
))}
|
||||
{activeStatusIcons.map((statusIcon) => (
|
||||
<View
|
||||
key={statusIcon.testID || statusIcon.name}
|
||||
style={{
|
||||
borderRadius: Radius.XXS,
|
||||
paddingHorizontal: 3,
|
||||
paddingVertical: 3,
|
||||
// borderWidth: 1,
|
||||
// borderColor: primaryColors.border,
|
||||
flexDirection: "row",
|
||||
alignItems: "center"
|
||||
}}
|
||||
>
|
||||
<AppIcon
|
||||
testID={statusIcon.testID}
|
||||
name={statusIcon.name}
|
||||
size={12}
|
||||
iconFamily="notesnook"
|
||||
color={statusIcon.color}
|
||||
/>
|
||||
</View>
|
||||
))}
|
||||
|
||||
{attachmentsCount !== 0 ? (
|
||||
{attachmentsCount !== 0 ? (
|
||||
<View
|
||||
style={{
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
borderRadius: Radius.XXS,
|
||||
paddingHorizontal: 3,
|
||||
paddingVertical: 3,
|
||||
gap: Spacing.LEVEL_0
|
||||
}}
|
||||
>
|
||||
<AppIcon
|
||||
name="link"
|
||||
iconFamily="notesnook"
|
||||
size={12}
|
||||
color={colors.secondary.icon}
|
||||
/>
|
||||
<Paragraph color={colors.secondary.paragraph} fontSize="XS">
|
||||
{attachmentsCount}
|
||||
</Paragraph>
|
||||
</View>
|
||||
) : null}
|
||||
|
||||
{notebooks?.items
|
||||
?.filter(
|
||||
(item) =>
|
||||
renderedInRoute !== "Notebook" ||
|
||||
item.id !== useNavigationStore.getState().focusedRouteId
|
||||
)
|
||||
.filter((_, index) => showMore || index < 1)
|
||||
.map((item) => (
|
||||
<View
|
||||
key={item.id}
|
||||
style={{
|
||||
borderRadius: 100,
|
||||
paddingHorizontal: Spacing.LEVEL_1,
|
||||
paddingVertical: 2,
|
||||
backgroundColor: colors.secondary.background,
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
gap: Spacing.LEVEL_0
|
||||
}}
|
||||
>
|
||||
<AppIcon
|
||||
name="bookmark"
|
||||
iconFamily="notesnook"
|
||||
size={AppFontSize.xs}
|
||||
color={colors.secondary.icon}
|
||||
/>
|
||||
<Paragraph fontSize="XS" color={colors.secondary.paragraph}>
|
||||
{item.title}
|
||||
</Paragraph>
|
||||
</View>
|
||||
))}
|
||||
|
||||
{tags?.items
|
||||
?.filter((_, index) => showMore || index < 1)
|
||||
.map((item) =>
|
||||
item.id ? (
|
||||
<View
|
||||
key={item.id}
|
||||
style={{
|
||||
borderRadius: 100,
|
||||
paddingHorizontal: Spacing.LEVEL_1,
|
||||
paddingVertical: 2,
|
||||
backgroundColor: colors.secondary.background,
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
borderRadius: Radius.XXS,
|
||||
paddingHorizontal: 3,
|
||||
paddingVertical: 3,
|
||||
gap: Spacing.LEVEL_0
|
||||
}}
|
||||
>
|
||||
<AppIcon
|
||||
name="link"
|
||||
iconFamily="notesnook"
|
||||
size={12}
|
||||
color={colors.secondary.icon}
|
||||
/>
|
||||
<Paragraph color={colors.secondary.paragraph} fontSize="XS">
|
||||
{attachmentsCount}
|
||||
<Paragraph
|
||||
size={AppFontSize.xs}
|
||||
color={colors.secondary.paragraph}
|
||||
>
|
||||
{item.title}
|
||||
</Paragraph>
|
||||
</View>
|
||||
) : null}
|
||||
) : null
|
||||
)}
|
||||
|
||||
{notebooks?.items
|
||||
?.filter(
|
||||
(item) =>
|
||||
renderedInRoute !== "Notebook" ||
|
||||
item.id !== useNavigationStore.getState().focusedRouteId
|
||||
)
|
||||
.filter((_, index) => showMore || index < 1)
|
||||
.map((item) => (
|
||||
<View
|
||||
key={item.id}
|
||||
style={{
|
||||
borderRadius: 100,
|
||||
paddingHorizontal: Spacing.LEVEL_1,
|
||||
paddingVertical: 2,
|
||||
backgroundColor: colors.secondary.background,
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
gap: Spacing.LEVEL_0
|
||||
}}
|
||||
>
|
||||
<AppIcon
|
||||
name="bookmark"
|
||||
iconFamily="notesnook"
|
||||
size={AppFontSize.xs}
|
||||
color={colors.secondary.icon}
|
||||
/>
|
||||
<Paragraph
|
||||
fontSize="XS"
|
||||
color={colors.secondary.paragraph}
|
||||
>
|
||||
{item.title}
|
||||
</Paragraph>
|
||||
</View>
|
||||
))}
|
||||
|
||||
{tags?.items
|
||||
?.filter((_, index) => showMore || index < 1)
|
||||
.map((item) =>
|
||||
item.id ? (
|
||||
<View
|
||||
key={item.id}
|
||||
style={{
|
||||
borderRadius: 100,
|
||||
paddingHorizontal: Spacing.LEVEL_1,
|
||||
paddingVertical: 2,
|
||||
backgroundColor: colors.secondary.background,
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
gap: Spacing.LEVEL_0
|
||||
}}
|
||||
>
|
||||
<Paragraph
|
||||
size={AppFontSize.xs}
|
||||
color={colors.secondary.paragraph}
|
||||
>
|
||||
{item.title}
|
||||
</Paragraph>
|
||||
</View>
|
||||
) : null
|
||||
)}
|
||||
|
||||
{(() => {
|
||||
const filteredNotebooks = (notebooks?.items || []).filter(
|
||||
(nb) =>
|
||||
renderedInRoute !== "Notebook" ||
|
||||
nb.id !== useNavigationStore.getState().focusedRouteId
|
||||
);
|
||||
const filteredTags = (tags?.items || []).filter((t) => t.id);
|
||||
const totalNotebooks = filteredNotebooks.length;
|
||||
const totalTags = filteredTags.length;
|
||||
const hasMore = totalNotebooks > 1 || totalTags > 1;
|
||||
if (!hasMore) return null;
|
||||
const hiddenCount =
|
||||
(totalNotebooks > 1 ? totalNotebooks - 1 : 0) +
|
||||
(totalTags > 1 ? totalTags - 1 : 0);
|
||||
return (
|
||||
<Heading
|
||||
size={AppFontSize.xs}
|
||||
color={colors.primary.accent}
|
||||
onPress={() => {
|
||||
if (showMore) {
|
||||
useShowMoreStore.getState().hide(item.id);
|
||||
} else {
|
||||
useShowMoreStore.getState().show(item.id);
|
||||
}
|
||||
}}
|
||||
>
|
||||
{showMore
|
||||
? "Show less"
|
||||
: `+${hiddenCount} ${strings.more()}`}
|
||||
</Heading>
|
||||
);
|
||||
})()}
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Paragraph
|
||||
color={colors.secondary.paragraph}
|
||||
size={AppFontSize.xxs}
|
||||
style={{
|
||||
marginRight: 6
|
||||
{(() => {
|
||||
const filteredNotebooks = (notebooks?.items || []).filter(
|
||||
(nb) =>
|
||||
renderedInRoute !== "Notebook" ||
|
||||
nb.id !== useNavigationStore.getState().focusedRouteId
|
||||
);
|
||||
const filteredTags = (tags?.items || []).filter((t) => t.id);
|
||||
const totalNotebooks = filteredNotebooks.length;
|
||||
const totalTags = filteredTags.length;
|
||||
const hasMore = totalNotebooks > 1 || totalTags > 1;
|
||||
if (!hasMore) return null;
|
||||
const hiddenCount =
|
||||
(totalNotebooks > 1 ? totalNotebooks - 1 : 0) +
|
||||
(totalTags > 1 ? totalTags - 1 : 0);
|
||||
return (
|
||||
<Heading
|
||||
size={AppFontSize.xs}
|
||||
color={colors.primary.accent}
|
||||
onPress={() => {
|
||||
if (showMore) {
|
||||
useShowMoreStore.getState().hide(item.id);
|
||||
} else {
|
||||
useShowMoreStore.getState().show(item.id);
|
||||
}
|
||||
}}
|
||||
>
|
||||
{item && item.dateDeleted
|
||||
? strings.deletedOn(
|
||||
new Date(item.dateDeleted).toISOString().slice(0, 10)
|
||||
)
|
||||
: null}
|
||||
</Paragraph>
|
||||
|
||||
<Paragraph
|
||||
color={primaryColors.accent}
|
||||
size={AppFontSize.xxs}
|
||||
style={{
|
||||
marginRight: 6
|
||||
}}
|
||||
>
|
||||
{strings.note()}
|
||||
</Paragraph>
|
||||
</>
|
||||
)}
|
||||
{showMore ? "Show less" : `+${hiddenCount} ${strings.more()}`}
|
||||
</Heading>
|
||||
);
|
||||
})()}
|
||||
</View>
|
||||
)}
|
||||
|
||||
@@ -490,6 +463,18 @@ const NoteItem = ({
|
||||
gap: Spacing.LEVEL_1
|
||||
}}
|
||||
>
|
||||
{isTrash ? (
|
||||
<Paragraph
|
||||
color={primaryColors.accent}
|
||||
fontSize="XXS"
|
||||
style={{
|
||||
marginRight: 6
|
||||
}}
|
||||
>
|
||||
{strings.note()}
|
||||
</Paragraph>
|
||||
) : null}
|
||||
|
||||
{compactMode ? null : (
|
||||
<View
|
||||
style={{
|
||||
@@ -512,12 +497,18 @@ const NoteItem = ({
|
||||
}}
|
||||
fontSize="XS"
|
||||
>
|
||||
{getFormattedDate(
|
||||
date,
|
||||
dayjs(date).isBefore(dayjs().subtract(1, "day").hour(23))
|
||||
? "date"
|
||||
: "time"
|
||||
)}
|
||||
{isTrash
|
||||
? strings.deletedOn(
|
||||
new Date((item as TrashItem).dateDeleted)
|
||||
.toISOString()
|
||||
.slice(0, 10)
|
||||
)
|
||||
: getFormattedDate(
|
||||
date,
|
||||
dayjs(date).isBefore(dayjs().subtract(1, "day").hour(23))
|
||||
? "date"
|
||||
: "time"
|
||||
)}
|
||||
</Paragraph>
|
||||
</View>
|
||||
)}
|
||||
|
||||
@@ -71,44 +71,53 @@ const SelectionWrapper = ({
|
||||
};
|
||||
|
||||
return (
|
||||
<View
|
||||
style={{
|
||||
backgroundColor: isEditingNote ? colors.selected.background : undefined
|
||||
}}
|
||||
>
|
||||
<Pressable
|
||||
customColor={isSheet ? colors.primary.hover : "transparent"}
|
||||
testID={testID}
|
||||
onLongPress={onLongPress}
|
||||
onPress={onPress}
|
||||
customSelectedColor={colors.primary.hover}
|
||||
noborder
|
||||
customAlpha={!isDark ? -0.02 : 0.02}
|
||||
customOpacity={1}
|
||||
style={{
|
||||
paddingHorizontal: Spacing.LEVEL_3
|
||||
}}
|
||||
>
|
||||
{hasGroupHeader ? null : (
|
||||
<>
|
||||
{hasGroupHeader ? null : (
|
||||
<View
|
||||
style={{
|
||||
paddingHorizontal: Spacing.LEVEL_3
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
marginVertical: Spacing.LEVEL_2,
|
||||
borderBottomWidth: 1,
|
||||
borderBottomColor: colors.primary.separator,
|
||||
width: "100%"
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<View
|
||||
</View>
|
||||
)}
|
||||
<View
|
||||
style={{
|
||||
backgroundColor: undefined
|
||||
}}
|
||||
>
|
||||
<Pressable
|
||||
customColor={isSheet ? colors.primary.hover : "transparent"}
|
||||
testID={testID}
|
||||
onLongPress={onLongPress}
|
||||
onPress={onPress}
|
||||
customSelectedColor={colors.primary.hover}
|
||||
noborder
|
||||
customAlpha={!isDark ? -0.02 : 0.02}
|
||||
customOpacity={1}
|
||||
style={{
|
||||
width: "100%",
|
||||
flexDirection: "row"
|
||||
paddingHorizontal: Spacing.LEVEL_3,
|
||||
paddingBottom: Spacing.LEVEL_2,
|
||||
paddingTop: hasGroupHeader ? 0 : Spacing.LEVEL_2
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</View>
|
||||
</Pressable>
|
||||
</View>
|
||||
<View
|
||||
style={{
|
||||
width: "100%",
|
||||
flexDirection: "row"
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</View>
|
||||
</Pressable>
|
||||
</View>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user