diff --git a/apps/mobile/app/components/list-items/note/index.tsx b/apps/mobile/app/components/list-items/note/index.tsx
index 91bd179cd..afbaae87e 100644
--- a/apps/mobile/app/components/list-items/note/index.tsx
+++ b/apps/mobile/app/components/list-items/note/index.tsx
@@ -252,14 +252,16 @@ const NoteItem = ({
{reminder ? (
) : null}
diff --git a/apps/mobile/app/components/ui/reminder-time/index.tsx b/apps/mobile/app/components/ui/reminder-time/index.tsx
index cc127be88..e1da6a88d 100644
--- a/apps/mobile/app/components/ui/reminder-time/index.tsx
+++ b/apps/mobile/app/components/ui/reminder-time/index.tsx
@@ -41,7 +41,9 @@ export const ReminderTime = ({
} & ButtonProps) => {
const { colors } = useThemeColors();
const reminder = props.reminder;
- const time = !reminder ? undefined : getFormattedReminderTime(reminder);
+ const time = !reminder
+ ? undefined
+ : getFormattedReminderTime(reminder, props.short || false);
const isTodayOrTomorrow =
(time?.includes("Today") || time?.includes("Tomorrow")) &&
!time?.includes("Last");
diff --git a/apps/mobile/app/screens/add-reminder/index.tsx b/apps/mobile/app/screens/add-reminder/index.tsx
index 6e8a757d9..1bd0a234a 100644
--- a/apps/mobile/app/screens/add-reminder/index.tsx
+++ b/apps/mobile/app/screens/add-reminder/index.tsx
@@ -39,7 +39,7 @@ import Input from "../../components/ui/input";
import { ReminderTime } from "../../components/ui/reminder-time";
import Paragraph from "../../components/ui/typography/paragraph";
import { DDS } from "../../services/device-detection";
-import { ToastManager } from "../../services/event-manager";
+import { eSendEvent, ToastManager } from "../../services/event-manager";
import Navigation, { NavigationProps } from "../../services/navigation";
import Notifications from "../../services/notifications";
import SettingsService from "../../services/settings";
@@ -47,9 +47,18 @@ import { useRelationStore } from "../../stores/use-relation-store";
import { useSettingStore } from "../../stores/use-setting-store";
import { AppFontSize, defaultBorderRadius } from "../../utils/size";
import { DefaultAppStyles } from "../../utils/styles";
-import { getFormattedDate, useIsFeatureAvailable } from "@notesnook/common";
+import {
+ getFormattedDate,
+ useIsFeatureAvailable,
+ usePromise
+} from "@notesnook/common";
import PaywallSheet from "../../components/sheets/paywall";
import { useNavigationFocus } from "../../hooks/use-navigation-focus";
+import { Pressable } from "../../components/ui/pressable";
+import { TimeSince } from "../../components/ui/time-since";
+import Heading from "../../components/ui/typography/heading";
+import { eOnLoadNote } from "../../utils/events";
+import { fluidTabsRef } from "../../utils/global-refs";
const ReminderModes =
Platform.OS === "ios"
@@ -114,6 +123,15 @@ export default function AddReminder(props: NavigationProps<"AddReminder">) {
const titleRef = useRef(null);
const descriptionRef = useRef(null);
const timer = useRef(undefined);
+ const referencedNotes = usePromise(
+ () =>
+ reminder?.id
+ ? db.relations
+ .to({ id: reminder.id, type: "reminder" }, "note")
+ .resolve()
+ : null,
+ [reminder?.id]
+ );
const showDatePicker = () => {
setDatePickerVisibility(true);
@@ -237,6 +255,9 @@ export default function AddReminder(props: NavigationProps<"AddReminder">) {
marginBottom: DDS.isTab ? 25 : undefined,
paddingHorizontal: DefaultAppStyles.GAP
}}
+ contentContainerStyle={{
+ gap: DefaultAppStyles.GAP_VERTICAL
+ }}
keyboardDismissMode="interactive"
keyboardShouldPersistTaps="handled"
>
@@ -271,15 +292,11 @@ export default function AddReminder(props: NavigationProps<"AddReminder">) {
paddingVertical: DefaultAppStyles.GAP_VERTICAL
}}
height={80}
- wrapperStyle={{
- marginBottom: DefaultAppStyles.GAP_VERTICAL
- }}
/>
@@ -335,8 +352,7 @@ export default function AddReminder(props: NavigationProps<"AddReminder">) {
style={{
backgroundColor: colors.secondary.background,
padding: DefaultAppStyles.GAP,
- borderRadius: defaultBorderRadius,
- marginBottom: DefaultAppStyles.GAP_VERTICAL
+ borderRadius: defaultBorderRadius
}}
>
) {
width: "100%",
flexDirection: "column",
justifyContent: "center",
- marginBottom: DefaultAppStyles.GAP_VERTICAL,
alignItems: "center"
}}
>
@@ -513,10 +528,8 @@ export default function AddReminder(props: NavigationProps<"AddReminder">) {
style={{
borderRadius: defaultBorderRadius,
flexDirection: "row",
- paddingVertical: DefaultAppStyles.GAP_VERTICAL_SMALL,
alignItems: "center",
- justifyContent: "flex-start",
- marginBottom: DefaultAppStyles.GAP_VERTICAL
+ justifyContent: "flex-start"
}}
>
<>
@@ -552,22 +565,10 @@ export default function AddReminder(props: NavigationProps<"AddReminder">) {
)}
-
-
{reminderMode === ReminderModes.Permanent ? null : (
) {
))}
)}
+
+
+
+ {referencedNotes &&
+ referencedNotes.status === "fulfilled" &&
+ referencedNotes.value !== null &&
+ referencedNotes.value?.length > 0 ? (
+
+ {strings.referencedIn()}
+ {referencedNotes.value.map((item) => (
+ {
+ Navigation.navigate("FluidPanelsView");
+ fluidTabsRef.current?.goToPage("editor");
+ eSendEvent(eOnLoadNote, {
+ item: item
+ });
+ }}
+ type="secondary"
+ >
+ {item.title}
+
+
+ ))}
+
+ ) : null}
diff --git a/apps/web/__e2e__/models/note-properties.model.ts b/apps/web/__e2e__/models/note-properties.model.ts
index accc00592..1796db50a 100644
--- a/apps/web/__e2e__/models/note-properties.model.ts
+++ b/apps/web/__e2e__/models/note-properties.model.ts
@@ -27,10 +27,12 @@ import {
fillColorDialog,
fillNotebookDialog,
fillPasswordDialog,
+ fillReminderDialog,
iterateList
} from "./utils";
import { SessionHistoryItemModel } from "./session-history-item-model";
import dayjs from "dayjs";
+import { Reminder } from "@notesnook/core";
abstract class BaseProperties {
protected readonly page: Page;
@@ -388,6 +390,12 @@ export class NoteContextMenuModel extends BaseProperties {
await confirmDialog(dialog);
}
+ async addReminder(reminder: Partial) {
+ await this.open();
+ await this.menu.clickOnItem("remind-me");
+ await fillReminderDialog(this.page, reminder);
+ }
+
async open() {
await this.menu.open(this.noteLocator);
}
diff --git a/apps/web/__e2e__/models/reminder-item.model.ts b/apps/web/__e2e__/models/reminder-item.model.ts
index 940c18b2d..a4714e0ce 100644
--- a/apps/web/__e2e__/models/reminder-item.model.ts
+++ b/apps/web/__e2e__/models/reminder-item.model.ts
@@ -62,4 +62,9 @@ export class ReminderItemModel extends BaseItemModel {
await this.contextMenu.open(this.locator);
await this.contextMenu.clickOnItem("toggle");
}
+
+ async open() {
+ await this.contextMenu.open(this.locator);
+ await this.contextMenu.clickOnItem("edit");
+ }
}
diff --git a/apps/web/__e2e__/reminders.test.ts b/apps/web/__e2e__/reminders.test.ts
index 269debcfa..552fb623e 100644
--- a/apps/web/__e2e__/reminders.test.ts
+++ b/apps/web/__e2e__/reminders.test.ts
@@ -20,6 +20,7 @@ along with this program. If not, see .
import { Reminder } from "@notesnook/core";
import { test, expect } from "@playwright/test";
import { AppModel } from "./models/app.model";
+import { getTestId } from "./utils";
const ONE_TIME_REMINDER: Partial = {
title: "Test reminder 1",
@@ -197,3 +198,26 @@ test("editing a weekly recurring reminder should not revert it to daily", async
expect(await reminder?.getRecurringMode()).toBe("Weekly");
expect(await reminder?.getDescription()).toBe("An edited reminder");
});
+
+test("adding a reminder via note context menu should show reference in edit dialog", async ({
+ page
+}) => {
+ const app = new AppModel(page);
+ await app.goto();
+ const notes = await app.goToNotes();
+ const note = await notes.createNote({
+ title: "Test note",
+ content: "I am a note"
+ });
+
+ await note?.contextMenu.addReminder(ONE_TIME_REMINDER);
+ const reminders = await app.goToReminders();
+ const reminder = await reminders.findReminder({
+ title: ONE_TIME_REMINDER.title
+ });
+ await reminder?.open();
+
+ const noteReferences = page.locator(getTestId("reminder-note-references"));
+ await noteReferences.waitFor({ state: "visible" });
+ expect(noteReferences.getByText("Test note")).toBeVisible();
+});
diff --git a/apps/web/src/dialogs/add-reminder-dialog.tsx b/apps/web/src/dialogs/add-reminder-dialog.tsx
index 075537977..dbfa1b271 100644
--- a/apps/web/src/dialogs/add-reminder-dialog.tsx
+++ b/apps/web/src/dialogs/add-reminder-dialog.tsx
@@ -17,6 +17,7 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
+import NoteItem from "../components/note";
import Dialog from "../components/dialog";
import Field from "../components/field";
import { Box, Button, Flex, Label, Radio, Text } from "@theme-ui/components";
@@ -32,13 +33,18 @@ import { usePersistentState } from "../hooks/use-persistent-state";
import { DayPicker } from "../components/day-picker";
import { PopupPresenter } from "@notesnook/ui";
import { useStore as useThemeStore } from "../stores/theme-store";
-import { getFormattedDate, useIsFeatureAvailable } from "@notesnook/common";
+import {
+ getFormattedDate,
+ useIsFeatureAvailable,
+ usePromise
+} from "@notesnook/common";
import { MONTHS_FULL, getTimeFormat } from "@notesnook/core";
import { Note, Reminder } from "@notesnook/core";
import { BaseDialogProps, DialogManager } from "../common/dialog-manager";
import { strings } from "@notesnook/intl";
import { checkFeature } from "../common";
import { setTimeOnly, setDateOnly } from "../utils/date-time";
+import Skeleton from "react-loading-skeleton";
dayjs.extend(customParseFormat);
@@ -148,6 +154,15 @@ export const AddReminderDialog = DialogManager.register(
const theme = useThemeStore((store) => store.colorScheme);
const dateInputRef = useRef(null);
const repeatModeAvailability = useIsFeatureAvailable("recurringReminders");
+ const referencedNotes = usePromise(
+ () =>
+ reminder?.id
+ ? db.relations
+ .to({ id: reminder.id, type: "reminder" }, "note")
+ .resolve()
+ : null,
+ [reminder?.id]
+ );
const repeatsDaily =
(selectedDays.length === 7 && recurringMode === RecurringModes.WEEK) ||
@@ -512,6 +527,32 @@ export const AddReminderDialog = DialogManager.register(
{strings.reminderStarts(date.format(db.settings.getDateFormat()), date.format(timeFormat()))}
)}
+
+ {reminder ? (
+ referencedNotes && referencedNotes.status === "fulfilled" ? (
+ referencedNotes.value !== null &&
+ referencedNotes.value.length > 0 && (
+
+
+ {strings.note()} {strings.references()}:
+
+ {referencedNotes.value.map((item) => (
+
+ ))}
+
+ )
+ ) : (
+
+ )
+ ) : null}
);
},
diff --git a/apps/web/src/dialogs/reminder-preview-dialog.tsx b/apps/web/src/dialogs/reminder-preview-dialog.tsx
index bbbe2a17c..42409e72e 100644
--- a/apps/web/src/dialogs/reminder-preview-dialog.tsx
+++ b/apps/web/src/dialogs/reminder-preview-dialog.tsx
@@ -96,7 +96,8 @@ export const ReminderPreviewDialog = DialogManager.register(
sx={{
alignItems: "center",
my: 1,
- gap: 1
+ gap: 1,
+ flexWrap: "wrap"
}}
>
{SNOOZE_TIMES.map((time) => (