mobile: wrap add-reminder screen in keyboard avoiding view on ios

This commit is contained in:
Ammar Ahmed
2025-06-27 13:54:50 +05:00
parent b81cc178b5
commit 92c7e1a0c1

View File

@@ -21,7 +21,13 @@ import { strings } from "@notesnook/intl";
import { useThemeColors } from "@notesnook/theme";
import dayjs from "dayjs";
import React, { useRef, useState } from "react";
import { Platform, ScrollView, TextInput, View } from "react-native";
import {
KeyboardAvoidingView,
Platform,
ScrollView,
TextInput,
View
} from "react-native";
import DatePicker from "react-native-date-picker";
import DateTimePickerModal from "react-native-modal-datetime-picker";
import { SafeAreaView } from "react-native-safe-area-context";
@@ -199,6 +205,8 @@ export default function AddReminder(props: NavigationProps<"AddReminder">) {
}
}
const KeyboardViewIOS = Platform.OS === "ios" ? KeyboardAvoidingView : View;
return (
<SafeAreaView
style={{
@@ -206,374 +214,388 @@ export default function AddReminder(props: NavigationProps<"AddReminder">) {
flex: 1
}}
>
<Header
title={reminder ? strings.editReminder() : strings.newReminder()}
canGoBack
rightButton={{
name: "check",
onPress: saveReminder
}}
/>
<Dialog context="local" />
<ScrollView
bounces={false}
<KeyboardViewIOS
behavior="padding"
style={{
marginBottom: DDS.isTab ? 25 : undefined,
paddingHorizontal: DefaultAppStyles.GAP
flex: 1
}}
>
<Input
fwdRef={titleRef}
defaultValue={reminder?.title || referencedItem?.title}
placeholder={strings.remindeMeOf()}
onChangeText={(text) => (title.current = text)}
wrapperStyle={{
marginTop: DefaultAppStyles.GAP_VERTICAL
<Header
title={reminder ? strings.editReminder() : strings.newReminder()}
canGoBack
rightButton={{
name: "check",
onPress: saveReminder
}}
/>
<Input
defaultValue={
reminder ? reminder?.description : referencedItem?.headline
}
placeholder={strings.addShortNote()}
onChangeText={(text) => (details.current = text)}
containerStyle={{
maxHeight: 80
}}
multiline
textAlignVertical="top"
inputStyle={{
minHeight: 80,
paddingVertical: DefaultAppStyles.GAP_VERTICAL
}}
height={80}
wrapperStyle={{
marginBottom: DefaultAppStyles.GAP_VERTICAL
}}
/>
<Dialog context="local" />
<ScrollView
style={{
flexDirection: "row",
marginBottom: DefaultAppStyles.GAP_VERTICAL
marginBottom: DDS.isTab ? 25 : undefined,
paddingHorizontal: DefaultAppStyles.GAP
}}
horizontal
keyboardDismissMode="interactive"
keyboardShouldPersistTaps="handled"
>
{Object.keys(ReminderModes).map((mode) => (
<Button
key={mode}
title={strings.reminderModes(
ReminderModes[mode as keyof typeof ReminderModes] as string
)}
style={{
paddingVertical: DefaultAppStyles.GAP_VERTICAL_SMALL,
marginRight: DefaultAppStyles.GAP_SMALL
}}
proTag={mode === "Repeat"}
height={35}
type={
reminderMode ===
ReminderModes[mode as keyof typeof ReminderModes]
? "selected"
: "plain"
}
onPress={() => {
if (mode === "Repeat" && !PremiumService.get()) return;
setReminderMode(
ReminderModes[
mode as keyof typeof ReminderModes
] as Reminder["mode"]
);
if (mode === "Repeat") {
setSelectedDays((days) => {
if (days.length > 0) return days;
if (days.indexOf(date.getDay()) > -1) {
return days;
}
days.push(date.getDay());
return [...days];
});
}
}}
/>
))}
</ScrollView>
<Input
fwdRef={titleRef}
defaultValue={reminder?.title || referencedItem?.title}
placeholder={strings.remindeMeOf()}
onChangeText={(text) => (title.current = text)}
wrapperStyle={{
marginTop: DefaultAppStyles.GAP_VERTICAL
}}
/>
{reminderMode === ReminderModes.Repeat ? (
<View
style={{
backgroundColor: colors.secondary.background,
padding: DefaultAppStyles.GAP,
borderRadius: defaultBorderRadius,
<Input
defaultValue={
reminder ? reminder?.description : referencedItem?.headline
}
placeholder={strings.addShortNote()}
onChangeText={(text) => (details.current = text)}
containerStyle={{
maxHeight: 80
}}
multiline
textAlignVertical="top"
inputStyle={{
minHeight: 80,
paddingVertical: DefaultAppStyles.GAP_VERTICAL
}}
height={80}
wrapperStyle={{
marginBottom: DefaultAppStyles.GAP_VERTICAL
}}
>
<View
style={{
flexDirection: "row",
marginBottom:
recurringMode === "day" || recurringMode === "year" ? 0 : 12,
alignItems: "center"
}}
>
{Object.keys(RecurringModes).map((mode) => (
<Button
key={mode}
title={strings.recurringModes(
RecurringModes[mode as keyof typeof RecurringModes]
)}
style={{
marginRight: 6,
borderRadius: 100,
paddingVertical: DefaultAppStyles.GAP_VERTICAL_SMALL
}}
type={
recurringMode ===
RecurringModes[mode as keyof typeof RecurringModes]
? "selected"
: "plain"
}
onPress={() => {
setRecurringMode(
RecurringModes[
mode as keyof typeof RecurringModes
] as Reminder["recurringMode"]
);
setSelectedDays([]);
setRepeatFrequency(1);
}}
/>
))}
</View>
/>
<ScrollView showsHorizontalScrollIndicator={false} horizontal>
{recurringMode === RecurringModes.Daily ||
recurringMode === RecurringModes.Year
? null
: recurringMode === RecurringModes.Week
? WeekDays.map((item, index) => (
<Button
key={strings.weekDayNamesShort[
index as keyof typeof strings.weekDayNamesShort
]()}
title={strings.weekDayNamesShort[
index as keyof typeof strings.weekDayNamesShort
]()}
type={
selectedDays.indexOf(index) > -1 ? "selected" : "plain"
}
fontSize={AppFontSize.xs}
style={{
height: 40,
borderRadius: 100,
marginRight: 10
}}
onPress={() => {
setSelectedDays((days) => {
if (days.indexOf(index) > -1) {
days.splice(days.indexOf(index), 1);
return [...days];
}
days.push(index);
return [...days];
});
}}
/>
))
: MonthDays.map((item, index) => (
<Button
key={index + "monthday"}
title={index + 1 + ""}
type={
selectedDays.indexOf(index + 1) > -1
? "selected"
: "plain"
}
fontSize={AppFontSize.xs}
style={{
height: 40,
borderRadius: 100,
marginRight: 10
}}
onPress={() => {
setSelectedDays((days) => {
if (days.indexOf(index + 1) > -1) {
days.splice(days.indexOf(index + 1), 1);
return [...days];
}
days.push(index + 1);
return [...days];
});
}}
/>
))}
</ScrollView>
</View>
) : null}
{reminderMode === ReminderModes.Permanent ? null : (
<View
style={{
width: "100%",
flexDirection: "column",
justifyContent: "center",
marginBottom: DefaultAppStyles.GAP_VERTICAL,
alignItems: "center"
}}
>
<DateTimePickerModal
isVisible={isDatePickerVisible}
mode="date"
onConfirm={handleConfirm}
onCancel={hideDatePicker}
is24Hour={db.settings.getTimeFormat() === "24-hour"}
date={date || new Date(Date.now())}
/>
<DatePicker
date={date}
maximumDate={dayjs(date).add(3, "months").toDate()}
onDateChange={handleConfirm}
textColor={isDark ? colors.static.white : colors.static.black}
fadeToColor={colors.primary.background}
theme={isDark ? "dark" : "light"}
androidVariant="nativeAndroid"
is24hourSource="locale"
locale={
db.settings?.getTimeFormat() === "24-hour" ? "en_GB" : "en_US"
}
mode={
reminderMode === ReminderModes.Repeat &&
recurringMode !== "year"
? "time"
: "datetime"
}
/>
{reminderMode === ReminderModes.Repeat ? null : (
<Button
style={{
width: "100%"
}}
title={date ? date.toLocaleDateString() : strings.selectDate()}
type={date ? "secondaryAccented" : "secondary"}
icon="calendar"
fontSize={AppFontSize.sm}
onPress={() => {
showDatePicker();
}}
/>
)}
</View>
)}
{reminderMode === ReminderModes.Once ||
reminderMode === ReminderModes.Permanent ? null : (
<View
style={{
borderRadius: defaultBorderRadius,
flexDirection: "row",
paddingVertical: DefaultAppStyles.GAP_VERTICAL_SMALL,
alignItems: "center",
justifyContent: "flex-start",
marginBottom: DefaultAppStyles.GAP_VERTICAL
}}
>
<>
<Paragraph
size={AppFontSize.xxs}
color={colors.secondary.paragraph}
>
{recurringMode === RecurringModes.Daily
? strings.reminderRepeatStrings.day(
dayjs(date).format("hh:mm A")
)
: recurringMode === RecurringModes.Year
? strings.reminderRepeatStrings.year(
dayjs(date).format("dddd, MMMM D, h:mm A")
)
: selectedDays.length === 7 &&
recurringMode === RecurringModes.Week
? strings.reminderRepeatStrings.week.daily(
dayjs(date).format("hh:mm A")
)
: selectedDays.length === 0
? strings.reminderRepeatStrings[
recurringMode as "week" | "month"
].selectDays()
: strings.reminderRepeatStrings.repeats(
repeatFrequency,
recurringMode as string,
getSelectedDaysText(selectedDays),
dayjs(date).format("hh:mm A")
)}
</Paragraph>
</>
</View>
)}
<ReminderTime
reminder={reminder}
style={{
width: "100%",
justifyContent: "flex-start",
borderWidth: 0,
paddingVertical: DefaultAppStyles.GAP_VERTICAL_SMALL,
alignSelf: "flex-start"
}}
/>
{reminderMode === ReminderModes.Permanent ? null : (
<ScrollView
style={{
flexDirection: "row",
marginTop: DefaultAppStyles.GAP_VERTICAL,
height: 50
marginBottom: DefaultAppStyles.GAP_VERTICAL
}}
horizontal
>
{Object.keys(ReminderNotificationModes).map((mode) => (
{Object.keys(ReminderModes).map((mode) => (
<Button
key={mode}
title={strings.reminderNotificationModes(
mode as keyof typeof ReminderNotificationModes
title={strings.reminderModes(
ReminderModes[mode as keyof typeof ReminderModes] as string
)}
style={{
marginRight: 12,
paddingVertical: DefaultAppStyles.GAP_VERTICAL_SMALL
paddingVertical: DefaultAppStyles.GAP_VERTICAL_SMALL,
marginRight: DefaultAppStyles.GAP_SMALL
}}
icon={
mode === "Silent"
? "minus-circle"
: mode === "Vibrate"
? "vibrate"
: "volume-high"
}
fontSize={AppFontSize.xs}
proTag={mode === "Repeat"}
height={35}
type={
reminderNotificationMode ===
ReminderNotificationModes[
mode as keyof typeof ReminderNotificationModes
]
reminderMode ===
ReminderModes[mode as keyof typeof ReminderModes]
? "selected"
: "plain"
}
onPress={() => {
const _mode = ReminderNotificationModes[
mode as keyof typeof ReminderNotificationModes
] as Reminder["priority"];
SettingsService.set({
reminderNotificationMode: _mode
});
setReminderNotificatioMode(_mode);
if (mode === "Repeat" && !PremiumService.get()) return;
setReminderMode(
ReminderModes[
mode as keyof typeof ReminderModes
] as Reminder["mode"]
);
if (mode === "Repeat") {
setSelectedDays((days) => {
if (days.length > 0) return days;
if (days.indexOf(date.getDay()) > -1) {
return days;
}
days.push(date.getDay());
return [...days];
});
}
}}
/>
))}
</ScrollView>
)}
</ScrollView>
{reminderMode === ReminderModes.Repeat ? (
<View
style={{
backgroundColor: colors.secondary.background,
padding: DefaultAppStyles.GAP,
borderRadius: defaultBorderRadius,
marginBottom: DefaultAppStyles.GAP_VERTICAL
}}
>
<View
style={{
flexDirection: "row",
marginBottom:
recurringMode === "day" || recurringMode === "year"
? 0
: 12,
alignItems: "center"
}}
>
{Object.keys(RecurringModes).map((mode) => (
<Button
key={mode}
title={strings.recurringModes(
RecurringModes[mode as keyof typeof RecurringModes]
)}
style={{
marginRight: 6,
borderRadius: 100,
paddingVertical: DefaultAppStyles.GAP_VERTICAL_SMALL
}}
type={
recurringMode ===
RecurringModes[mode as keyof typeof RecurringModes]
? "selected"
: "plain"
}
onPress={() => {
setRecurringMode(
RecurringModes[
mode as keyof typeof RecurringModes
] as Reminder["recurringMode"]
);
setSelectedDays([]);
setRepeatFrequency(1);
}}
/>
))}
</View>
<ScrollView showsHorizontalScrollIndicator={false} horizontal>
{recurringMode === RecurringModes.Daily ||
recurringMode === RecurringModes.Year
? null
: recurringMode === RecurringModes.Week
? WeekDays.map((item, index) => (
<Button
key={strings.weekDayNamesShort[
index as keyof typeof strings.weekDayNamesShort
]()}
title={strings.weekDayNamesShort[
index as keyof typeof strings.weekDayNamesShort
]()}
type={
selectedDays.indexOf(index) > -1
? "selected"
: "plain"
}
fontSize={AppFontSize.xs}
style={{
height: 40,
borderRadius: 100,
marginRight: 10
}}
onPress={() => {
setSelectedDays((days) => {
if (days.indexOf(index) > -1) {
days.splice(days.indexOf(index), 1);
return [...days];
}
days.push(index);
return [...days];
});
}}
/>
))
: MonthDays.map((item, index) => (
<Button
key={index + "monthday"}
title={index + 1 + ""}
type={
selectedDays.indexOf(index + 1) > -1
? "selected"
: "plain"
}
fontSize={AppFontSize.xs}
style={{
height: 40,
borderRadius: 100,
marginRight: 10
}}
onPress={() => {
setSelectedDays((days) => {
if (days.indexOf(index + 1) > -1) {
days.splice(days.indexOf(index + 1), 1);
return [...days];
}
days.push(index + 1);
return [...days];
});
}}
/>
))}
</ScrollView>
</View>
) : null}
{reminderMode === ReminderModes.Permanent ? null : (
<View
style={{
width: "100%",
flexDirection: "column",
justifyContent: "center",
marginBottom: DefaultAppStyles.GAP_VERTICAL,
alignItems: "center"
}}
>
<DateTimePickerModal
isVisible={isDatePickerVisible}
mode="date"
onConfirm={handleConfirm}
onCancel={hideDatePicker}
is24Hour={db.settings.getTimeFormat() === "24-hour"}
date={date || new Date(Date.now())}
/>
<DatePicker
date={date}
maximumDate={dayjs(date).add(3, "months").toDate()}
onDateChange={handleConfirm}
textColor={isDark ? colors.static.white : colors.static.black}
fadeToColor={colors.primary.background}
theme={isDark ? "dark" : "light"}
androidVariant="nativeAndroid"
is24hourSource="locale"
locale={
db.settings?.getTimeFormat() === "24-hour" ? "en_GB" : "en_US"
}
mode={
reminderMode === ReminderModes.Repeat &&
recurringMode !== "year"
? "time"
: "datetime"
}
/>
{reminderMode === ReminderModes.Repeat ? null : (
<Button
style={{
width: "100%"
}}
title={
date ? date.toLocaleDateString() : strings.selectDate()
}
type={date ? "secondaryAccented" : "secondary"}
icon="calendar"
fontSize={AppFontSize.sm}
onPress={() => {
showDatePicker();
}}
/>
)}
</View>
)}
{reminderMode === ReminderModes.Once ||
reminderMode === ReminderModes.Permanent ? null : (
<View
style={{
borderRadius: defaultBorderRadius,
flexDirection: "row",
paddingVertical: DefaultAppStyles.GAP_VERTICAL_SMALL,
alignItems: "center",
justifyContent: "flex-start",
marginBottom: DefaultAppStyles.GAP_VERTICAL
}}
>
<>
<Paragraph
size={AppFontSize.xxs}
color={colors.secondary.paragraph}
>
{recurringMode === RecurringModes.Daily
? strings.reminderRepeatStrings.day(
dayjs(date).format("hh:mm A")
)
: recurringMode === RecurringModes.Year
? strings.reminderRepeatStrings.year(
dayjs(date).format("dddd, MMMM D, h:mm A")
)
: selectedDays.length === 7 &&
recurringMode === RecurringModes.Week
? strings.reminderRepeatStrings.week.daily(
dayjs(date).format("hh:mm A")
)
: selectedDays.length === 0
? strings.reminderRepeatStrings[
recurringMode as "week" | "month"
].selectDays()
: strings.reminderRepeatStrings.repeats(
repeatFrequency,
recurringMode as string,
getSelectedDaysText(selectedDays),
dayjs(date).format("hh:mm A")
)}
</Paragraph>
</>
</View>
)}
<ReminderTime
reminder={reminder}
style={{
width: "100%",
justifyContent: "flex-start",
borderWidth: 0,
paddingVertical: DefaultAppStyles.GAP_VERTICAL_SMALL,
alignSelf: "flex-start"
}}
/>
{reminderMode === ReminderModes.Permanent ? null : (
<ScrollView
style={{
flexDirection: "row",
marginTop: DefaultAppStyles.GAP_VERTICAL,
height: 50
}}
horizontal
>
{Object.keys(ReminderNotificationModes).map((mode) => (
<Button
key={mode}
title={strings.reminderNotificationModes(
mode as keyof typeof ReminderNotificationModes
)}
style={{
marginRight: 12,
paddingVertical: DefaultAppStyles.GAP_VERTICAL_SMALL
}}
icon={
mode === "Silent"
? "minus-circle"
: mode === "Vibrate"
? "vibrate"
: "volume-high"
}
fontSize={AppFontSize.xs}
height={35}
type={
reminderNotificationMode ===
ReminderNotificationModes[
mode as keyof typeof ReminderNotificationModes
]
? "selected"
: "plain"
}
onPress={() => {
const _mode = ReminderNotificationModes[
mode as keyof typeof ReminderNotificationModes
] as Reminder["priority"];
SettingsService.set({
reminderNotificationMode: _mode
});
setReminderNotificatioMode(_mode);
}}
/>
))}
</ScrollView>
)}
</ScrollView>
</KeyboardViewIOS>
</SafeAreaView>
);
}