mirror of
https://github.com/bulwarkmail/native.git
synced 2026-11-01 16:05:39 +00:00
fix: clear the new event slot marker when the editor closes or the tab is left
This commit is contained in:
@@ -89,6 +89,8 @@ interface TimeGridScrollViewProps {
|
||||
onSelectDate?: (date: Date) => void;
|
||||
onSelectEvent?: (event: CalendarEvent) => void;
|
||||
onCreateAtTime?: (date: Date) => void;
|
||||
/** A change takes the "New event" block away (the editor closed, the tab was left). */
|
||||
draftResetKey?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -119,6 +121,7 @@ function TimeGridScrollViewInner({
|
||||
onSelectDate,
|
||||
onSelectEvent,
|
||||
onCreateAtTime,
|
||||
draftResetKey = 0,
|
||||
}: TimeGridScrollViewProps) {
|
||||
const c = useColors();
|
||||
// "Light event colors" (webmail calendarTintedEvents).
|
||||
@@ -314,6 +317,9 @@ function TimeGridScrollViewInner({
|
||||
// A tap on an empty slot marks it with a "New event" block; tapping that
|
||||
// block creates the event. Two taps, so a stray tap never opens the editor.
|
||||
const [draft, setDraft] = React.useState<{ key: string; hour: number } | null>(null);
|
||||
React.useEffect(() => {
|
||||
setDraft(null);
|
||||
}, [draftResetKey]);
|
||||
const handleTapAt = React.useCallback((day: Date, hour: number) => {
|
||||
const key = dayKey(day);
|
||||
setDraft((cur) => (cur && cur.key === key && cur.hour === hour ? null : { key, hour }));
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
|
||||
// Checked on the source: the suite has no React Native renderer.
|
||||
const grid = fs.readFileSync(path.resolve(__dirname, '../TimeGridScrollView.tsx'), 'utf8');
|
||||
const screen = fs.readFileSync(path.resolve(__dirname, '../../../screens/CalendarScreen.tsx'), 'utf8');
|
||||
|
||||
describe('the "New event" block a tap on an empty slot leaves', () => {
|
||||
it('goes when the grid is told to drop it', () => {
|
||||
expect(grid).toMatch(/React\.useEffect\(\(\) => \{\s*setDraft\(null\);\s*\}, \[draftResetKey\]\);/);
|
||||
});
|
||||
|
||||
it('is dropped when the editor opens or closes and when the user leaves the tab', () => {
|
||||
const grids = screen.slice(screen.indexOf('<TimeGridScrollView'), screen.indexOf('/>', screen.indexOf('<TimeGridScrollView')));
|
||||
expect(grids).toMatch(/draftResetKey=\{slotDraftReset\}/);
|
||||
expect(screen).toMatch(/React\.useEffect\(\(\) => \{\s*setSlotDraftReset\(\(n\) => n \+ 1\);\s*\}, \[modalVisible\]\);/);
|
||||
// The focus effect's cleanup runs on blur.
|
||||
expect(screen).toMatch(/useFocusEffect\(\s*React\.useCallback\(\(\) => \(\) => setSlotDraftReset\(\(n\) => n \+ 1\), \[\]\),?\s*\)/);
|
||||
});
|
||||
});
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
useWindowDimensions,
|
||||
} from 'react-native';
|
||||
import { SafeAreaView } from 'react-native-safe-area-context';
|
||||
import { useFocusEffect } from '@react-navigation/native';
|
||||
import { TASK_CHIP_ID_PREFIX, multiDayCount } from '../lib/calendar-time-grid';
|
||||
import {
|
||||
Calendar as CalendarIcon,
|
||||
@@ -239,6 +240,15 @@ export default function CalendarScreen() {
|
||||
const [modalEvent, setModalEvent] = React.useState<CalendarEvent | null>(null);
|
||||
const [modalDate, setModalDate] = React.useState<Date | undefined>(undefined);
|
||||
const [modalVisible, setModalVisible] = React.useState(false);
|
||||
// The "New event" block a tap on an empty slot leaves: gone once the
|
||||
// editor opens or closes, or the user leaves the tab.
|
||||
const [slotDraftReset, setSlotDraftReset] = React.useState(0);
|
||||
React.useEffect(() => {
|
||||
setSlotDraftReset((n) => n + 1);
|
||||
}, [modalVisible]);
|
||||
useFocusEffect(
|
||||
React.useCallback(() => () => setSlotDraftReset((n) => n + 1), []),
|
||||
);
|
||||
const [pendingAction, setPendingAction] = React.useState<PendingAction>(null);
|
||||
const [sidebarVisible, setSidebarVisible] = React.useState(false);
|
||||
const [tasksVisible, setTasksVisible] = React.useState(false);
|
||||
@@ -1177,6 +1187,7 @@ export default function CalendarScreen() {
|
||||
onSelectDate={viewMode === 'day' ? handleSelectDate : openDay}
|
||||
onSelectEvent={handleSelectEvent}
|
||||
onCreateAtTime={openCreate}
|
||||
draftResetKey={slotDraftReset}
|
||||
/>
|
||||
)}
|
||||
{viewMode === 'week' && !freeScroll && (
|
||||
|
||||
Reference in New Issue
Block a user