@agent-native/core 0.180.0-nightly-20260915184036 → 0.180.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/corpus/README.md +1 -1
- package/corpus/templates/analytics/CHANGELOG.md +10 -0
- package/corpus/templates/calendar/CHANGELOG.md +39 -0
- package/corpus/templates/calendar/INTERACTION-MATRIX.md +19 -17
- package/corpus/templates/calendar/actions/update-calendar-visual-preferences.ts +21 -0
- package/corpus/templates/calendar/actions/view-screen.ts +10 -2
- package/corpus/templates/calendar/app/components/calendar/CreateEventDialog.tsx +11 -0
- package/corpus/templates/calendar/app/components/calendar/MonthView.tsx +174 -145
- package/corpus/templates/calendar/app/components/calendar/WeekView.tsx +20 -16
- package/corpus/templates/calendar/app/components/layout/Sidebar.tsx +1 -0
- package/corpus/templates/calendar/app/hooks/use-events.ts +16 -0
- package/corpus/templates/calendar/app/hooks/use-view-preferences.ts +126 -14
- package/corpus/templates/calendar/app/i18n-data.ts +90 -0
- package/corpus/templates/calendar/app/lib/calendar-navigation.ts +29 -9
- package/corpus/templates/calendar/app/lib/calendar-timezone.ts +2 -0
- package/corpus/templates/calendar/app/lib/event-time-range.ts +34 -0
- package/corpus/templates/calendar/app/pages/CalendarView.tsx +245 -35
- package/corpus/templates/calendar/changelog/2026-09-13-calendar-sidebar-overflow-is-easier-to-discover.md +6 -0
- package/corpus/templates/calendar/changelog/2026-09-15-calendar-mirrors-notion-calendar-s-customizable-day-ranges-a.md +6 -0
- package/corpus/templates/calendar/shared/calendar-view-preferences.ts +36 -0
- package/corpus/templates/calendar/shared/timezone.ts +9 -2
- package/corpus/templates/clips/.agents/skills/video-sharing/SKILL.md +2 -0
- package/corpus/templates/clips/CHANGELOG.md +19 -0
- package/corpus/templates/clips/actions/save-browser-diagnostics.ts +43 -4
- package/corpus/templates/clips/app/components/player/browser-diagnostics-panel.tsx +114 -1
- package/corpus/templates/clips/app/i18n/en-US.ts +7 -0
- package/corpus/templates/clips/app/lib/browser-diagnostics-capture.ts +108 -0
- package/corpus/templates/clips/app/routes/record.tsx +1 -0
- package/corpus/templates/clips/changelog/2026-09-15-recordings-include-a-structured-timeline-of-browser-interact.md +6 -0
- package/corpus/templates/clips/chrome-extension/public/manifest.json +7 -0
- package/corpus/templates/clips/chrome-extension/src/background.ts +235 -9
- package/corpus/templates/clips/chrome-extension/src/content-history-bridge.ts +80 -0
- package/corpus/templates/clips/chrome-extension/src/content-script.ts +166 -5
- package/corpus/templates/clips/chrome-extension/vite.config.ts +4 -0
- package/corpus/templates/clips/server/db/schema.ts +3 -0
- package/corpus/templates/clips/server/lib/public-agent-context.ts +40 -2
- package/corpus/templates/clips/server/plugins/db.ts +5 -0
- package/corpus/templates/clips/shared/browser-diagnostics.ts +171 -0
- package/corpus/templates/content/.agents/skills/content/SKILL.md +4 -2
- package/corpus/templates/content/.agents/skills/document-editing/SKILL.md +8 -1
- package/corpus/templates/content/AGENTS.md +5 -6
- package/corpus/templates/content/CHANGELOG.md +24 -0
- package/corpus/templates/content/actions/_content-database-row-migration.ts +67 -36
- package/corpus/templates/content/actions/_document-edit-mutation.ts +74 -23
- package/corpus/templates/content/actions/edit-document.ts +48 -8
- package/corpus/templates/content/actions/migrate-content-database-rows.ts +69 -28
- package/corpus/templates/content/server/plugins/agent-chat.ts +1 -1
- package/corpus/templates/design/CHANGELOG.md +22 -0
- package/corpus/templates/factory/CHANGELOG.md +11 -0
- package/corpus/templates/forms/CHANGELOG.md +6 -0
- package/corpus/templates/mail/.agents/skills/mail-interaction-parity/references/interaction-matrix.md +24 -4
- package/corpus/templates/mail/CHANGELOG.md +68 -0
- package/corpus/templates/mail/app/components/email/ComposeBubbleToolbar.tsx +8 -0
- package/corpus/templates/mail/app/components/email/ComposeModal.tsx +33 -13
- package/corpus/templates/mail/app/components/email/EmailListItem.tsx +23 -4
- package/corpus/templates/mail/app/components/email/EmailThread.tsx +56 -13
- package/corpus/templates/mail/app/components/email/InlineReplyComposer.tsx +23 -4
- package/corpus/templates/mail/app/components/email/RecipientInput.tsx +9 -0
- package/corpus/templates/mail/app/components/layout/AppLayout.tsx +8 -1
- package/corpus/templates/mail/app/i18n/en-US.ts +31 -0
- package/corpus/templates/mail/changelog/2026-09-15-mail-labels-recipient-and-account-controls-for-keyboard-and-.md +6 -0
- package/corpus/templates/slides/CHANGELOG.md +32 -0
- package/dist/client/CommandMenu.js +14 -2
- package/dist/client/settings/AccountSettingsCard.js +3 -2
- package/dist/client/settings/SettingsTabsPage.js +9 -1
- package/dist/client/settings/agent-settings-search.js +5 -1
- package/dist/client/sign-out.d.ts +1 -0
- package/dist/client/sign-out.js +8 -0
- package/dist/collab/routes.d.ts +1 -1
- package/dist/file-upload/actions/upload-image.d.ts +2 -2
- package/dist/observability/routes.d.ts +3 -3
- package/dist/org/handlers.d.ts +1 -1
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/secrets/routes.d.ts +3 -3
- package/dist/server/agent-engine-api-key-route.d.ts +2 -2
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/package.json +4 -4
|
@@ -150,6 +150,28 @@ export function shouldApplyPreferencePoll(
|
|
|
150
150
|
return requestedAtRevision === confirmedRevision;
|
|
151
151
|
}
|
|
152
152
|
|
|
153
|
+
export function mergePendingVisualPreferences(
|
|
154
|
+
remote: CalendarViewPreferences,
|
|
155
|
+
pending: Partial<CalendarViewPreferences>,
|
|
156
|
+
): CalendarViewPreferences {
|
|
157
|
+
return normalizeCalendarViewPreferences({ ...remote, ...pending });
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export function rollbackVisualPreferencePatch(
|
|
161
|
+
current: CalendarViewPreferences,
|
|
162
|
+
optimistic: Partial<CalendarViewPreferences>,
|
|
163
|
+
rollback: Partial<CalendarViewPreferences>,
|
|
164
|
+
activeKeys: readonly (keyof CalendarViewPreferences)[],
|
|
165
|
+
): CalendarViewPreferences {
|
|
166
|
+
const rollbackEntries = activeKeys.flatMap((key) =>
|
|
167
|
+
Object.is(current[key], optimistic[key]) ? [[key, rollback[key]]] : [],
|
|
168
|
+
);
|
|
169
|
+
return normalizeCalendarViewPreferences({
|
|
170
|
+
...current,
|
|
171
|
+
...Object.fromEntries(rollbackEntries),
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
|
|
153
175
|
export function enqueueSourcePreferenceMutation<T>(
|
|
154
176
|
chains: Record<string, Promise<unknown>>,
|
|
155
177
|
preferenceKey: string,
|
|
@@ -160,6 +182,17 @@ export function enqueueSourcePreferenceMutation<T>(
|
|
|
160
182
|
return request;
|
|
161
183
|
}
|
|
162
184
|
|
|
185
|
+
export function enqueueVisualPreferenceMutation<T>(
|
|
186
|
+
chains: Record<string, Promise<unknown>>,
|
|
187
|
+
run: () => Promise<T>,
|
|
188
|
+
): Promise<T> {
|
|
189
|
+
return enqueueSourcePreferenceMutation(
|
|
190
|
+
chains,
|
|
191
|
+
CALENDAR_VIEW_PREFERENCES_KEY,
|
|
192
|
+
run,
|
|
193
|
+
);
|
|
194
|
+
}
|
|
195
|
+
|
|
163
196
|
async function readAppStatePreferences(): Promise<CalendarViewPreferences | null> {
|
|
164
197
|
const controller = new AbortController();
|
|
165
198
|
const abortTimer = setTimeout(() => controller.abort(), REFRESH_ABORT_MS);
|
|
@@ -192,6 +225,13 @@ function useViewPreferencesState(): ViewPreferencesContextValue {
|
|
|
192
225
|
const visibilityMutationChains = useRef<Record<string, Promise<unknown>>>({});
|
|
193
226
|
const colorMutationChains = useRef<Record<string, Promise<unknown>>>({});
|
|
194
227
|
const accountMutationChains = useRef<Record<string, Promise<unknown>>>({});
|
|
228
|
+
const visualPreferenceRequestIds = useRef<
|
|
229
|
+
Partial<Record<keyof CalendarViewPreferences, number>>
|
|
230
|
+
>({});
|
|
231
|
+
const visualPreferenceMutationChains = useRef<
|
|
232
|
+
Record<string, Promise<unknown>>
|
|
233
|
+
>({});
|
|
234
|
+
const pendingVisualPreferences = useRef<Partial<CalendarViewPreferences>>({});
|
|
195
235
|
const confirmedServerRevision = useRef(0);
|
|
196
236
|
|
|
197
237
|
useEffect(() => {
|
|
@@ -237,14 +277,19 @@ function useViewPreferencesState(): ViewPreferencesContextValue {
|
|
|
237
277
|
...(pendingPreferences?.colors ?? {}),
|
|
238
278
|
...pendingAccountColors.current,
|
|
239
279
|
};
|
|
280
|
+
const remoteWithPendingVisualPreferences =
|
|
281
|
+
mergePendingVisualPreferences(
|
|
282
|
+
remote,
|
|
283
|
+
pendingVisualPreferences.current,
|
|
284
|
+
);
|
|
240
285
|
const next = normalizeCalendarViewPreferences({
|
|
241
|
-
...
|
|
286
|
+
...remoteWithPendingVisualPreferences,
|
|
242
287
|
googleCalendarVisibility: {
|
|
243
|
-
...
|
|
288
|
+
...remoteWithPendingVisualPreferences.googleCalendarVisibility,
|
|
244
289
|
...pendingVisibility.current,
|
|
245
290
|
},
|
|
246
291
|
googleCalendarColors: {
|
|
247
|
-
...
|
|
292
|
+
...remoteWithPendingVisualPreferences.googleCalendarColors,
|
|
248
293
|
...Object.fromEntries(
|
|
249
294
|
Object.entries(pendingGoogleColors.current).filter(
|
|
250
295
|
(entry): entry is [string, string] => entry[1] !== null,
|
|
@@ -254,7 +299,7 @@ function useViewPreferencesState(): ViewPreferencesContextValue {
|
|
|
254
299
|
...(Object.keys(pendingColors).length > 0
|
|
255
300
|
? {
|
|
256
301
|
accountColorModes: {
|
|
257
|
-
...
|
|
302
|
+
...remoteWithPendingVisualPreferences.accountColorModes,
|
|
258
303
|
...Object.fromEntries(
|
|
259
304
|
Object.keys(pendingColors).map((accountEmail) => [
|
|
260
305
|
accountEmail,
|
|
@@ -263,7 +308,7 @@ function useViewPreferencesState(): ViewPreferencesContextValue {
|
|
|
263
308
|
),
|
|
264
309
|
},
|
|
265
310
|
accountColors: {
|
|
266
|
-
...
|
|
311
|
+
...remoteWithPendingVisualPreferences.accountColors,
|
|
267
312
|
...pendingColors,
|
|
268
313
|
},
|
|
269
314
|
}
|
|
@@ -310,15 +355,82 @@ function useViewPreferencesState(): ViewPreferencesContextValue {
|
|
|
310
355
|
};
|
|
311
356
|
}, [demo]);
|
|
312
357
|
|
|
313
|
-
const update = useCallback(
|
|
314
|
-
|
|
315
|
-
const
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
return
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
358
|
+
const update = useCallback(
|
|
359
|
+
(patch: Partial<ViewPreferences>) => {
|
|
360
|
+
const preferenceKeys = Object.keys(
|
|
361
|
+
patch,
|
|
362
|
+
) as (keyof CalendarViewPreferences)[];
|
|
363
|
+
if (preferenceKeys.length === 0) return;
|
|
364
|
+
const requestIds = new Map<keyof CalendarViewPreferences, number>();
|
|
365
|
+
for (const key of preferenceKeys) {
|
|
366
|
+
const requestId = (visualPreferenceRequestIds.current[key] ?? 0) + 1;
|
|
367
|
+
visualPreferenceRequestIds.current[key] = requestId;
|
|
368
|
+
requestIds.set(key, requestId);
|
|
369
|
+
}
|
|
370
|
+
let rollbackValues: Partial<CalendarViewPreferences> = {};
|
|
371
|
+
let optimisticValues: Partial<CalendarViewPreferences> = {};
|
|
372
|
+
setPrefs((prev) => {
|
|
373
|
+
const next = normalizeCalendarViewPreferences({ ...prev, ...patch });
|
|
374
|
+
rollbackValues = Object.fromEntries(
|
|
375
|
+
preferenceKeys.map((key) => [key, prev[key]]),
|
|
376
|
+
) as Partial<CalendarViewPreferences>;
|
|
377
|
+
optimisticValues = Object.fromEntries(
|
|
378
|
+
preferenceKeys.map((key) => [key, next[key]]),
|
|
379
|
+
) as Partial<CalendarViewPreferences>;
|
|
380
|
+
for (const key of preferenceKeys) {
|
|
381
|
+
pendingVisualPreferences.current[key] = next[key] as never;
|
|
382
|
+
}
|
|
383
|
+
save(next);
|
|
384
|
+
window.dispatchEvent(new Event(CALENDAR_VIEW_PREFERENCES_CHANGE_EVENT));
|
|
385
|
+
return next;
|
|
386
|
+
});
|
|
387
|
+
|
|
388
|
+
enqueueVisualPreferenceMutation(
|
|
389
|
+
visualPreferenceMutationChains.current,
|
|
390
|
+
() => callAction("update-calendar-visual-preferences", patch),
|
|
391
|
+
)
|
|
392
|
+
.then(() => {
|
|
393
|
+
let confirmed = false;
|
|
394
|
+
for (const key of preferenceKeys) {
|
|
395
|
+
if (
|
|
396
|
+
visualPreferenceRequestIds.current[key] === requestIds.get(key)
|
|
397
|
+
) {
|
|
398
|
+
delete pendingVisualPreferences.current[key];
|
|
399
|
+
confirmed = true;
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
if (confirmed) confirmedServerRevision.current += 1;
|
|
403
|
+
})
|
|
404
|
+
.catch(() => {
|
|
405
|
+
const activeKeys = preferenceKeys.filter(
|
|
406
|
+
(key) =>
|
|
407
|
+
visualPreferenceRequestIds.current[key] === requestIds.get(key),
|
|
408
|
+
);
|
|
409
|
+
if (activeKeys.length === 0) return;
|
|
410
|
+
for (const key of activeKeys) {
|
|
411
|
+
delete pendingVisualPreferences.current[key];
|
|
412
|
+
}
|
|
413
|
+
setPrefs((current) => {
|
|
414
|
+
const next = rollbackVisualPreferencePatch(
|
|
415
|
+
current,
|
|
416
|
+
optimisticValues,
|
|
417
|
+
rollbackValues,
|
|
418
|
+
activeKeys,
|
|
419
|
+
);
|
|
420
|
+
if (calendarViewPreferencesEqual(current, next)) return current;
|
|
421
|
+
save(next);
|
|
422
|
+
window.dispatchEvent(
|
|
423
|
+
new Event(CALENDAR_VIEW_PREFERENCES_CHANGE_EVENT),
|
|
424
|
+
);
|
|
425
|
+
return next;
|
|
426
|
+
});
|
|
427
|
+
toast.error(
|
|
428
|
+
`${t("settings.saveFailed")}. ${t("common.tryAgain")}`, // i18n-key-ignore generated calendar catalog
|
|
429
|
+
);
|
|
430
|
+
});
|
|
431
|
+
},
|
|
432
|
+
[t],
|
|
433
|
+
);
|
|
322
434
|
|
|
323
435
|
const updateAccountColor = useCallback(
|
|
324
436
|
(accountEmail: string, accountColor: string) => {
|
|
@@ -665,6 +665,8 @@ const enUS = {
|
|
|
665
665
|
calendarSettingsLoading:
|
|
666
666
|
"Calendar settings are still loading. Try again in a moment.",
|
|
667
667
|
day: "Day",
|
|
668
|
+
daysCount: "{{count}} days",
|
|
669
|
+
declinedEvents: "Declined events",
|
|
668
670
|
display: "Display",
|
|
669
671
|
endTimeAfterStart: "End time must be after start time",
|
|
670
672
|
eventDeleted: "Event deleted",
|
|
@@ -675,6 +677,7 @@ const enUS = {
|
|
|
675
677
|
failedRestoreAttendance: "Failed to restore attendance",
|
|
676
678
|
failedMoveEvent: "Failed to move event",
|
|
677
679
|
failedUpdateEvent: "Failed to update event",
|
|
680
|
+
generalSettings: "General settings",
|
|
678
681
|
googleCalendarLinkUnavailable: "Google Calendar link unavailable",
|
|
679
682
|
hideWeekends: "Hide weekends",
|
|
680
683
|
loadingCalendars: "Loading calendars",
|
|
@@ -684,11 +687,17 @@ const enUS = {
|
|
|
684
687
|
notificationEmptyDescription:
|
|
685
688
|
"Calendar can pop browser alerts while this app is open. Clips desktop handles fuller meeting prompts with one-click notes.",
|
|
686
689
|
openNavigation: "Open navigation",
|
|
690
|
+
numberOfDays: "Number of days",
|
|
691
|
+
other: "Other…",
|
|
687
692
|
today: "Today",
|
|
688
693
|
undo: "Undo",
|
|
689
694
|
updatingEvent: "Updating event...",
|
|
690
695
|
updatingRecurringEvent: "Updating recurring event...",
|
|
691
696
|
week: "Week",
|
|
697
|
+
weekNumber: "Week {{number}}",
|
|
698
|
+
weekNumbers: "Week numbers",
|
|
699
|
+
weekends: "Weekends",
|
|
700
|
+
viewSettings: "View settings",
|
|
692
701
|
timezoneSwitchTitle: "Use your browser timezone?",
|
|
693
702
|
timezoneSwitchDescription:
|
|
694
703
|
"Calendar is pinned to {{savedTimezone}}, but your browser is in {{browserTimezone}}. Switch the calendar timezone?",
|
|
@@ -7894,6 +7903,8 @@ const translatedCalendarRawBurnDown = {
|
|
|
7894
7903
|
addTitleBeforeCreate: "创建事件前请添加标题",
|
|
7895
7904
|
calendarSettingsLoading: "日历设置仍在加载。请稍后再试。",
|
|
7896
7905
|
day: "日",
|
|
7906
|
+
daysCount: "{{count}} 天",
|
|
7907
|
+
declinedEvents: "已拒绝的事件",
|
|
7897
7908
|
display: "显示",
|
|
7898
7909
|
endTimeAfterStart: "结束时间必须晚于开始时间",
|
|
7899
7910
|
eventDeleted: "事件已删除",
|
|
@@ -7904,6 +7915,7 @@ const translatedCalendarRawBurnDown = {
|
|
|
7904
7915
|
failedRestoreAttendance: "恢复出席状态失败",
|
|
7905
7916
|
failedMoveEvent: "移动事件失败",
|
|
7906
7917
|
failedUpdateEvent: "更新事件失败",
|
|
7918
|
+
generalSettings: "常规设置",
|
|
7907
7919
|
googleCalendarLinkUnavailable: "Google Calendar 链接不可用",
|
|
7908
7920
|
hideWeekends: "隐藏周末",
|
|
7909
7921
|
loadingCalendars: "正在加载日历",
|
|
@@ -7913,11 +7925,17 @@ const translatedCalendarRawBurnDown = {
|
|
|
7913
7925
|
notificationEmptyDescription:
|
|
7914
7926
|
"此应用打开时,Calendar 可以显示浏览器提醒。Clips 桌面版会处理更完整的会议提示,并支持一键备注。",
|
|
7915
7927
|
openNavigation: "打开导航",
|
|
7928
|
+
numberOfDays: "天数",
|
|
7929
|
+
other: "其他…",
|
|
7916
7930
|
today: "今天",
|
|
7917
7931
|
undo: "撤销",
|
|
7918
7932
|
updatingEvent: "正在更新事件...",
|
|
7919
7933
|
updatingRecurringEvent: "正在更新重复事件...",
|
|
7920
7934
|
week: "周",
|
|
7935
|
+
weekNumber: "第 {{number}} 周",
|
|
7936
|
+
weekNumbers: "周数",
|
|
7937
|
+
weekends: "周末",
|
|
7938
|
+
viewSettings: "视图设置",
|
|
7921
7939
|
timezoneSwitchTitle: "使用浏览器时区?",
|
|
7922
7940
|
timezoneSwitchDescription:
|
|
7923
7941
|
"日历固定为 {{savedTimezone}},但浏览器使用 {{browserTimezone}}。要切换日历时区吗?",
|
|
@@ -8070,6 +8088,8 @@ const translatedCalendarRawBurnDown = {
|
|
|
8070
8088
|
calendarSettingsLoading:
|
|
8071
8089
|
"La configuración del calendario aún se está cargando. Inténtalo de nuevo en un momento.",
|
|
8072
8090
|
day: "Día",
|
|
8091
|
+
daysCount: "{{count}} días",
|
|
8092
|
+
declinedEvents: "Eventos rechazados",
|
|
8073
8093
|
display: "Mostrar",
|
|
8074
8094
|
endTimeAfterStart:
|
|
8075
8095
|
"La hora de finalización debe ser posterior a la de inicio",
|
|
@@ -8081,6 +8101,7 @@ const translatedCalendarRawBurnDown = {
|
|
|
8081
8101
|
failedRestoreAttendance: "No se pudo restaurar la asistencia",
|
|
8082
8102
|
failedMoveEvent: "No se pudo mover el evento",
|
|
8083
8103
|
failedUpdateEvent: "No se pudo actualizar el evento",
|
|
8104
|
+
generalSettings: "Configuración general",
|
|
8084
8105
|
googleCalendarLinkUnavailable:
|
|
8085
8106
|
"El enlace de Google Calendar no está disponible",
|
|
8086
8107
|
hideWeekends: "Ocultar fines de semana",
|
|
@@ -8091,11 +8112,17 @@ const translatedCalendarRawBurnDown = {
|
|
|
8091
8112
|
notificationEmptyDescription:
|
|
8092
8113
|
"Calendar puede mostrar alertas del navegador mientras esta app está abierta. Clips de escritorio gestiona avisos de reunión más completos con notas en un clic.",
|
|
8093
8114
|
openNavigation: "Abrir navegación",
|
|
8115
|
+
numberOfDays: "Número de días",
|
|
8116
|
+
other: "Otro…",
|
|
8094
8117
|
today: "Hoy",
|
|
8095
8118
|
undo: "Deshacer",
|
|
8096
8119
|
updatingEvent: "Actualizando evento...",
|
|
8097
8120
|
updatingRecurringEvent: "Actualizando evento recurrente...",
|
|
8098
8121
|
week: "Semana",
|
|
8122
|
+
weekNumber: "Semana {{number}}",
|
|
8123
|
+
weekNumbers: "Números de semana",
|
|
8124
|
+
weekends: "Fines de semana",
|
|
8125
|
+
viewSettings: "Configuración de vista",
|
|
8099
8126
|
timezoneSwitchTitle: "¿Usar la zona horaria del navegador?",
|
|
8100
8127
|
timezoneSwitchDescription:
|
|
8101
8128
|
"El calendario está fijado en {{savedTimezone}}, pero tu navegador usa {{browserTimezone}}. ¿Cambiar la zona horaria del calendario?",
|
|
@@ -8254,6 +8281,8 @@ const translatedCalendarRawBurnDown = {
|
|
|
8254
8281
|
calendarSettingsLoading:
|
|
8255
8282
|
"Les paramètres du calendrier sont encore en cours de chargement. Réessayez dans un instant.",
|
|
8256
8283
|
day: "Jour",
|
|
8284
|
+
daysCount: "{{count}} jours",
|
|
8285
|
+
declinedEvents: "Événements refusés",
|
|
8257
8286
|
display: "Affichage",
|
|
8258
8287
|
endTimeAfterStart: "L'heure de fin doit être après l'heure de début",
|
|
8259
8288
|
eventDeleted: "Événement supprimé",
|
|
@@ -8264,6 +8293,7 @@ const translatedCalendarRawBurnDown = {
|
|
|
8264
8293
|
failedRestoreAttendance: "Échec de la restauration de la participation",
|
|
8265
8294
|
failedMoveEvent: "Échec du déplacement de l'événement",
|
|
8266
8295
|
failedUpdateEvent: "Échec de la mise à jour de l'événement",
|
|
8296
|
+
generalSettings: "Paramètres généraux",
|
|
8267
8297
|
googleCalendarLinkUnavailable: "Lien Google Calendar indisponible",
|
|
8268
8298
|
hideWeekends: "Masquer les week-ends",
|
|
8269
8299
|
loadingCalendars: "Chargement des calendriers",
|
|
@@ -8273,11 +8303,17 @@ const translatedCalendarRawBurnDown = {
|
|
|
8273
8303
|
notificationEmptyDescription:
|
|
8274
8304
|
"Calendar peut afficher des alertes du navigateur tant que cette app est ouverte. Clips desktop gère des rappels de réunion plus complets avec des notes en un clic.",
|
|
8275
8305
|
openNavigation: "Ouvrir la navigation",
|
|
8306
|
+
numberOfDays: "Nombre de jours",
|
|
8307
|
+
other: "Autre…",
|
|
8276
8308
|
today: "Aujourd'hui",
|
|
8277
8309
|
undo: "Annuler",
|
|
8278
8310
|
updatingEvent: "Mise à jour de l'événement...",
|
|
8279
8311
|
updatingRecurringEvent: "Mise à jour de l'événement récurrent...",
|
|
8280
8312
|
week: "Semaine",
|
|
8313
|
+
weekNumber: "Semaine {{number}}",
|
|
8314
|
+
weekNumbers: "Numéros de semaine",
|
|
8315
|
+
weekends: "Week-ends",
|
|
8316
|
+
viewSettings: "Paramètres d'affichage",
|
|
8281
8317
|
timezoneSwitchTitle: "Utiliser le fuseau horaire du navigateur ?",
|
|
8282
8318
|
timezoneSwitchDescription:
|
|
8283
8319
|
"Le calendrier est fixé sur {{savedTimezone}}, mais votre navigateur utilise {{browserTimezone}}. Changer le fuseau horaire du calendrier ?",
|
|
@@ -8439,6 +8475,8 @@ const translatedCalendarRawBurnDown = {
|
|
|
8439
8475
|
calendarSettingsLoading:
|
|
8440
8476
|
"Die Kalendereinstellungen werden noch geladen. Versuchen Sie es gleich erneut.",
|
|
8441
8477
|
day: "Tag",
|
|
8478
|
+
daysCount: "{{count}} Tage",
|
|
8479
|
+
declinedEvents: "Abgelehnte Ereignisse",
|
|
8442
8480
|
display: "Anzeige",
|
|
8443
8481
|
endTimeAfterStart: "Die Endzeit muss nach der Startzeit liegen",
|
|
8444
8482
|
eventDeleted: "Ereignis gelöscht",
|
|
@@ -8450,6 +8488,7 @@ const translatedCalendarRawBurnDown = {
|
|
|
8450
8488
|
"Teilnahme konnte nicht wiederhergestellt werden",
|
|
8451
8489
|
failedMoveEvent: "Ereignis konnte nicht verschoben werden",
|
|
8452
8490
|
failedUpdateEvent: "Ereignis konnte nicht aktualisiert werden",
|
|
8491
|
+
generalSettings: "Allgemeine Einstellungen",
|
|
8453
8492
|
googleCalendarLinkUnavailable: "Google Calendar-Link nicht verfügbar",
|
|
8454
8493
|
hideWeekends: "Wochenenden ausblenden",
|
|
8455
8494
|
loadingCalendars: "Kalender werden geladen",
|
|
@@ -8459,11 +8498,17 @@ const translatedCalendarRawBurnDown = {
|
|
|
8459
8498
|
notificationEmptyDescription:
|
|
8460
8499
|
"Calendar kann Browserbenachrichtigungen anzeigen, während diese App geöffnet ist. Clips Desktop übernimmt umfassendere Meeting-Hinweise mit Notizen per Klick.",
|
|
8461
8500
|
openNavigation: "Navigation öffnen",
|
|
8501
|
+
numberOfDays: "Anzahl der Tage",
|
|
8502
|
+
other: "Andere…",
|
|
8462
8503
|
today: "Heute",
|
|
8463
8504
|
undo: "Rückgängig",
|
|
8464
8505
|
updatingEvent: "Ereignis wird aktualisiert...",
|
|
8465
8506
|
updatingRecurringEvent: "Wiederkehrendes Ereignis wird aktualisiert...",
|
|
8466
8507
|
week: "Woche",
|
|
8508
|
+
weekNumber: "Woche {{number}}",
|
|
8509
|
+
weekNumbers: "Kalenderwochen",
|
|
8510
|
+
weekends: "Wochenenden",
|
|
8511
|
+
viewSettings: "Ansichtseinstellungen",
|
|
8467
8512
|
timezoneSwitchTitle: "Browser-Zeitzone verwenden?",
|
|
8468
8513
|
timezoneSwitchDescription:
|
|
8469
8514
|
"Der Kalender ist auf {{savedTimezone}} festgelegt, aber Ihr Browser verwendet {{browserTimezone}}. Kalenderzeitzone wechseln?",
|
|
@@ -8623,6 +8668,8 @@ const translatedCalendarRawBurnDown = {
|
|
|
8623
8668
|
calendarSettingsLoading:
|
|
8624
8669
|
"カレンダー設定を読み込み中です。少し待ってからもう一度お試しください。",
|
|
8625
8670
|
day: "日",
|
|
8671
|
+
daysCount: "{{count}}日",
|
|
8672
|
+
declinedEvents: "辞退した予定",
|
|
8626
8673
|
display: "表示",
|
|
8627
8674
|
endTimeAfterStart: "終了時刻は開始時刻より後にしてください",
|
|
8628
8675
|
eventDeleted: "イベントを削除しました",
|
|
@@ -8633,6 +8680,7 @@ const translatedCalendarRawBurnDown = {
|
|
|
8633
8680
|
failedRestoreAttendance: "出席の復元に失敗しました",
|
|
8634
8681
|
failedMoveEvent: "イベントを移動できませんでした",
|
|
8635
8682
|
failedUpdateEvent: "イベントを更新できませんでした",
|
|
8683
|
+
generalSettings: "一般設定",
|
|
8636
8684
|
googleCalendarLinkUnavailable: "Google Calendar リンクを利用できません",
|
|
8637
8685
|
hideWeekends: "週末を非表示",
|
|
8638
8686
|
loadingCalendars: "カレンダーを読み込み中",
|
|
@@ -8642,11 +8690,17 @@ const translatedCalendarRawBurnDown = {
|
|
|
8642
8690
|
notificationEmptyDescription:
|
|
8643
8691
|
"このアプリを開いている間、Calendar はブラウザー通知を表示できます。Clips デスクトップでは、ワンクリックのメモ付きでより詳しい会議通知を扱えます。",
|
|
8644
8692
|
openNavigation: "ナビゲーションを開く",
|
|
8693
|
+
numberOfDays: "表示日数",
|
|
8694
|
+
other: "その他…",
|
|
8645
8695
|
today: "今日",
|
|
8646
8696
|
undo: "元に戻す",
|
|
8647
8697
|
updatingEvent: "イベントを更新中...",
|
|
8648
8698
|
updatingRecurringEvent: "繰り返しイベントを更新中...",
|
|
8649
8699
|
week: "週",
|
|
8700
|
+
weekNumber: "第{{number}}週",
|
|
8701
|
+
weekNumbers: "週番号",
|
|
8702
|
+
weekends: "週末",
|
|
8703
|
+
viewSettings: "表示設定",
|
|
8650
8704
|
timezoneSwitchTitle: "ブラウザのタイムゾーンを使用しますか?",
|
|
8651
8705
|
timezoneSwitchDescription:
|
|
8652
8706
|
"カレンダーは {{savedTimezone}} に固定されていますが、ブラウザは {{browserTimezone}} を使用しています。カレンダーのタイムゾーンを切り替えますか?",
|
|
@@ -8801,6 +8855,8 @@ const translatedCalendarRawBurnDown = {
|
|
|
8801
8855
|
calendarSettingsLoading:
|
|
8802
8856
|
"캘린더 설정을 아직 불러오는 중입니다. 잠시 후 다시 시도하세요.",
|
|
8803
8857
|
day: "일",
|
|
8858
|
+
daysCount: "{{count}}일",
|
|
8859
|
+
declinedEvents: "거절된 일정",
|
|
8804
8860
|
display: "표시",
|
|
8805
8861
|
endTimeAfterStart: "종료 시간은 시작 시간보다 늦어야 합니다",
|
|
8806
8862
|
eventDeleted: "이벤트가 삭제되었습니다",
|
|
@@ -8811,6 +8867,7 @@ const translatedCalendarRawBurnDown = {
|
|
|
8811
8867
|
failedRestoreAttendance: "참석 상태를 복원하지 못했습니다",
|
|
8812
8868
|
failedMoveEvent: "이벤트를 이동하지 못했습니다",
|
|
8813
8869
|
failedUpdateEvent: "이벤트를 업데이트하지 못했습니다",
|
|
8870
|
+
generalSettings: "일반 설정",
|
|
8814
8871
|
googleCalendarLinkUnavailable:
|
|
8815
8872
|
"Google Calendar 링크를 사용할 수 없습니다",
|
|
8816
8873
|
hideWeekends: "주말 숨기기",
|
|
@@ -8821,11 +8878,17 @@ const translatedCalendarRawBurnDown = {
|
|
|
8821
8878
|
notificationEmptyDescription:
|
|
8822
8879
|
"이 앱이 열려 있는 동안 Calendar가 브라우저 알림을 표시할 수 있습니다. Clips 데스크톱은 원클릭 메모가 포함된 더 자세한 회의 알림을 처리합니다.",
|
|
8823
8880
|
openNavigation: "탐색 열기",
|
|
8881
|
+
numberOfDays: "표시할 일수",
|
|
8882
|
+
other: "기타…",
|
|
8824
8883
|
today: "오늘",
|
|
8825
8884
|
undo: "실행 취소",
|
|
8826
8885
|
updatingEvent: "이벤트 업데이트 중...",
|
|
8827
8886
|
updatingRecurringEvent: "반복 이벤트 업데이트 중...",
|
|
8828
8887
|
week: "주",
|
|
8888
|
+
weekNumber: "{{number}}주",
|
|
8889
|
+
weekNumbers: "주 번호",
|
|
8890
|
+
weekends: "주말",
|
|
8891
|
+
viewSettings: "보기 설정",
|
|
8829
8892
|
timezoneSwitchTitle: "브라우저 시간대를 사용할까요?",
|
|
8830
8893
|
timezoneSwitchDescription:
|
|
8831
8894
|
"캘린더는 {{savedTimezone}}에 고정되어 있지만 브라우저는 {{browserTimezone}}을(를) 사용합니다. 캘린더 시간대를 전환할까요?",
|
|
@@ -8982,6 +9045,8 @@ const translatedCalendarRawBurnDown = {
|
|
|
8982
9045
|
calendarSettingsLoading:
|
|
8983
9046
|
"As configurações do calendário ainda estão carregando. Tente novamente em instantes.",
|
|
8984
9047
|
day: "Dia",
|
|
9048
|
+
daysCount: "{{count}} dias",
|
|
9049
|
+
declinedEvents: "Eventos recusados",
|
|
8985
9050
|
display: "Exibição",
|
|
8986
9051
|
endTimeAfterStart:
|
|
8987
9052
|
"O horário de término deve ser depois do horário de início",
|
|
@@ -8993,6 +9058,7 @@ const translatedCalendarRawBurnDown = {
|
|
|
8993
9058
|
failedRestoreAttendance: "Falha ao restaurar a participação",
|
|
8994
9059
|
failedMoveEvent: "Falha ao mover evento",
|
|
8995
9060
|
failedUpdateEvent: "Falha ao atualizar evento",
|
|
9061
|
+
generalSettings: "Configurações gerais",
|
|
8996
9062
|
googleCalendarLinkUnavailable: "Link do Google Calendar indisponível",
|
|
8997
9063
|
hideWeekends: "Ocultar fins de semana",
|
|
8998
9064
|
loadingCalendars: "Carregando calendários",
|
|
@@ -9002,11 +9068,17 @@ const translatedCalendarRawBurnDown = {
|
|
|
9002
9068
|
notificationEmptyDescription:
|
|
9003
9069
|
"Calendar pode exibir alertas do navegador enquanto este app estiver aberto. O Clips desktop cuida de lembretes de reunião mais completos com notas em um clique.",
|
|
9004
9070
|
openNavigation: "Abrir navegação",
|
|
9071
|
+
numberOfDays: "Número de dias",
|
|
9072
|
+
other: "Outro…",
|
|
9005
9073
|
today: "Hoje",
|
|
9006
9074
|
undo: "Desfazer",
|
|
9007
9075
|
updatingEvent: "Atualizando evento...",
|
|
9008
9076
|
updatingRecurringEvent: "Atualizando evento recorrente...",
|
|
9009
9077
|
week: "Semana",
|
|
9078
|
+
weekNumber: "Semana {{number}}",
|
|
9079
|
+
weekNumbers: "Números da semana",
|
|
9080
|
+
weekends: "Fins de semana",
|
|
9081
|
+
viewSettings: "Configurações de visualização",
|
|
9010
9082
|
timezoneSwitchTitle: "Usar o fuso horário do navegador?",
|
|
9011
9083
|
timezoneSwitchDescription:
|
|
9012
9084
|
"O calendário está fixado em {{savedTimezone}}, mas o navegador usa {{browserTimezone}}. Mudar o fuso horário do calendário?",
|
|
@@ -9163,6 +9235,8 @@ const translatedCalendarRawBurnDown = {
|
|
|
9163
9235
|
calendarSettingsLoading:
|
|
9164
9236
|
"कैलेंडर सेटिंग अभी लोड हो रही हैं। कृपया थोड़ी देर में फिर कोशिश करें।",
|
|
9165
9237
|
day: "दिन",
|
|
9238
|
+
daysCount: "{{count}} दिन",
|
|
9239
|
+
declinedEvents: "अस्वीकृत इवेंट",
|
|
9166
9240
|
display: "डिस्प्ले",
|
|
9167
9241
|
endTimeAfterStart: "समाप्ति समय प्रारंभ समय के बाद होना चाहिए",
|
|
9168
9242
|
eventDeleted: "इवेंट मिटा दिया गया",
|
|
@@ -9173,6 +9247,7 @@ const translatedCalendarRawBurnDown = {
|
|
|
9173
9247
|
failedRestoreAttendance: "उपस्थिति बहाल करने में विफल",
|
|
9174
9248
|
failedMoveEvent: "इवेंट स्थानांतरित करने में विफल",
|
|
9175
9249
|
failedUpdateEvent: "इवेंट अपडेट करने में विफल",
|
|
9250
|
+
generalSettings: "सामान्य सेटिंग",
|
|
9176
9251
|
googleCalendarLinkUnavailable: "Google Calendar लिंक उपलब्ध नहीं है",
|
|
9177
9252
|
hideWeekends: "सप्ताहांत छिपाएं",
|
|
9178
9253
|
loadingCalendars: "कैलेंडर लोड हो रहे हैं",
|
|
@@ -9182,11 +9257,17 @@ const translatedCalendarRawBurnDown = {
|
|
|
9182
9257
|
notificationEmptyDescription:
|
|
9183
9258
|
"यह ऐप खुला होने पर Calendar ब्राउज़र अलर्ट दिखा सकता है। Clips डेस्कटॉप एक-क्लिक नोट्स के साथ अधिक पूर्ण मीटिंग संकेत संभालता है।",
|
|
9184
9259
|
openNavigation: "नेविगेशन खोलें",
|
|
9260
|
+
numberOfDays: "दिनों की संख्या",
|
|
9261
|
+
other: "अन्य…",
|
|
9185
9262
|
today: "आज",
|
|
9186
9263
|
undo: "पहले जैसा करें",
|
|
9187
9264
|
updatingEvent: "इवेंट अपडेट हो रहा है...",
|
|
9188
9265
|
updatingRecurringEvent: "दोहराया जाने वाला इवेंट अपडेट हो रहा है...",
|
|
9189
9266
|
week: "सप्ताह",
|
|
9267
|
+
weekNumber: "सप्ताह {{number}}",
|
|
9268
|
+
weekNumbers: "सप्ताह संख्या",
|
|
9269
|
+
weekends: "सप्ताहांत",
|
|
9270
|
+
viewSettings: "दृश्य सेटिंग",
|
|
9190
9271
|
timezoneSwitchTitle: "ब्राउज़र का टाइमज़ोन इस्तेमाल करें?",
|
|
9191
9272
|
timezoneSwitchDescription:
|
|
9192
9273
|
"कैलेंडर {{savedTimezone}} पर पिन है, लेकिन आपका ब्राउज़र {{browserTimezone}} पर है। कैलेंडर टाइमज़ोन बदलें?",
|
|
@@ -9342,6 +9423,8 @@ const translatedCalendarRawBurnDown = {
|
|
|
9342
9423
|
calendarSettingsLoading:
|
|
9343
9424
|
"لا تزال إعدادات التقويم قيد التحميل. حاول مرة أخرى بعد قليل.",
|
|
9344
9425
|
day: "اليوم",
|
|
9426
|
+
daysCount: "{{count}} يوم",
|
|
9427
|
+
declinedEvents: "الأحداث المرفوضة",
|
|
9345
9428
|
display: "العرض",
|
|
9346
9429
|
endTimeAfterStart: "يجب أن يكون وقت الانتهاء بعد وقت البدء",
|
|
9347
9430
|
eventDeleted: "تم حذف الحدث",
|
|
@@ -9352,6 +9435,7 @@ const translatedCalendarRawBurnDown = {
|
|
|
9352
9435
|
failedRestoreAttendance: "فشل استعادة الحضور",
|
|
9353
9436
|
failedMoveEvent: "فشل نقل الحدث",
|
|
9354
9437
|
failedUpdateEvent: "فشل تحديث الحدث",
|
|
9438
|
+
generalSettings: "الإعدادات العامة",
|
|
9355
9439
|
googleCalendarLinkUnavailable: "رابط Google Calendar غير متاح",
|
|
9356
9440
|
hideWeekends: "إخفاء عطلات نهاية الأسبوع",
|
|
9357
9441
|
loadingCalendars: "جارٍ تحميل التقويمات",
|
|
@@ -9361,11 +9445,17 @@ const translatedCalendarRawBurnDown = {
|
|
|
9361
9445
|
notificationEmptyDescription:
|
|
9362
9446
|
"يمكن لـ Calendar عرض تنبيهات المتصفح أثناء فتح هذا التطبيق. يتولى Clips لسطح المكتب مطالبات اجتماع أكثر اكتمالًا مع ملاحظات بنقرة واحدة.",
|
|
9363
9447
|
openNavigation: "فتح التنقل",
|
|
9448
|
+
numberOfDays: "عدد الأيام",
|
|
9449
|
+
other: "أخرى…",
|
|
9364
9450
|
today: "اليوم",
|
|
9365
9451
|
undo: "تراجع",
|
|
9366
9452
|
updatingEvent: "جارٍ تحديث الحدث...",
|
|
9367
9453
|
updatingRecurringEvent: "جارٍ تحديث الحدث المتكرر...",
|
|
9368
9454
|
week: "الأسبوع",
|
|
9455
|
+
weekNumber: "الأسبوع {{number}}",
|
|
9456
|
+
weekNumbers: "أرقام الأسابيع",
|
|
9457
|
+
weekends: "عطلات نهاية الأسبوع",
|
|
9458
|
+
viewSettings: "إعدادات العرض",
|
|
9369
9459
|
timezoneSwitchTitle: "استخدام المنطقة الزمنية للمتصفح؟",
|
|
9370
9460
|
timezoneSwitchDescription:
|
|
9371
9461
|
"التقويم مثبت على {{savedTimezone}}، لكن متصفحك يستخدم {{browserTimezone}}. هل تريد تبديل المنطقة الزمنية للتقويم؟",
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
addDays,
|
|
3
3
|
addMonths,
|
|
4
|
-
|
|
4
|
+
eachDayOfInterval,
|
|
5
5
|
startOfWeek,
|
|
6
6
|
subDays,
|
|
7
7
|
subMonths,
|
|
8
|
-
subWeeks,
|
|
9
8
|
} from "date-fns";
|
|
10
9
|
|
|
11
10
|
import { dateKeyToDate, dateToCalendarDateKey } from "./calendar-timezone";
|
|
@@ -18,6 +17,7 @@ export function navigateCalendarDate(
|
|
|
18
17
|
selectedDate: Date,
|
|
19
18
|
direction: CalendarNavigationDirection,
|
|
20
19
|
weekStartsOn: 0 | 1,
|
|
20
|
+
numberOfDays = 7,
|
|
21
21
|
): Date {
|
|
22
22
|
switch (viewMode) {
|
|
23
23
|
case "month":
|
|
@@ -25,13 +25,20 @@ export function navigateCalendarDate(
|
|
|
25
25
|
? addMonths(selectedDate, 1)
|
|
26
26
|
: subMonths(selectedDate, 1);
|
|
27
27
|
case "week": {
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
28
|
+
const displayedDays = Number.isInteger(numberOfDays)
|
|
29
|
+
? Math.min(31, Math.max(1, numberOfDays))
|
|
30
|
+
: 7;
|
|
31
|
+
const periodStart =
|
|
32
|
+
displayedDays === 7
|
|
33
|
+
? dateKeyToDate(
|
|
34
|
+
dateToCalendarDateKey(
|
|
35
|
+
startOfWeek(selectedDate, { weekStartsOn }),
|
|
36
|
+
),
|
|
37
|
+
)
|
|
38
|
+
: selectedDate;
|
|
39
|
+
return direction === "next"
|
|
40
|
+
? addDays(periodStart, displayedDays)
|
|
41
|
+
: subDays(periodStart, displayedDays);
|
|
35
42
|
}
|
|
36
43
|
case "day":
|
|
37
44
|
return direction === "next"
|
|
@@ -39,3 +46,16 @@ export function navigateCalendarDate(
|
|
|
39
46
|
: subDays(selectedDate, 1);
|
|
40
47
|
}
|
|
41
48
|
}
|
|
49
|
+
|
|
50
|
+
export function getVisibleCalendarDays(
|
|
51
|
+
start: Date,
|
|
52
|
+
end: Date,
|
|
53
|
+
hideWeekends: boolean,
|
|
54
|
+
): Date[] {
|
|
55
|
+
const fullRange = eachDayOfInterval({ start, end });
|
|
56
|
+
if (!hideWeekends) return fullRange;
|
|
57
|
+
const weekdays = fullRange.filter(
|
|
58
|
+
(day) => day.getDay() !== 0 && day.getDay() !== 6,
|
|
59
|
+
);
|
|
60
|
+
return weekdays.length > 0 ? weekdays : fullRange;
|
|
61
|
+
}
|
|
@@ -167,12 +167,14 @@ export function getViewDateRange(
|
|
|
167
167
|
selectedDate: Date,
|
|
168
168
|
timezone: string,
|
|
169
169
|
weekStartsOn: 0 | 1 = 0,
|
|
170
|
+
numberOfDays = 7,
|
|
170
171
|
): { from: string; to: string } {
|
|
171
172
|
return getCalendarViewDateRange(
|
|
172
173
|
viewMode,
|
|
173
174
|
dateToCalendarDateKey(selectedDate),
|
|
174
175
|
normalizeTimezone(timezone),
|
|
175
176
|
weekStartsOn,
|
|
177
|
+
numberOfDays,
|
|
176
178
|
);
|
|
177
179
|
}
|
|
178
180
|
|
|
@@ -165,6 +165,40 @@ export function shiftEndForStartChange(
|
|
|
165
165
|
return { ...next, endDate: repaired.date, endTime: repaired.time };
|
|
166
166
|
}
|
|
167
167
|
|
|
168
|
+
/**
|
|
169
|
+
* Move a timed event's start date without changing its visible duration. The
|
|
170
|
+
* end date is shifted by the same number of calendar days; this keeps a
|
|
171
|
+
* multi-day event intact when its start date changes in the composer.
|
|
172
|
+
*/
|
|
173
|
+
export function shiftEndForDateChange(
|
|
174
|
+
range: EventTimeRange,
|
|
175
|
+
nextDate: string,
|
|
176
|
+
): EventTimeRange {
|
|
177
|
+
const next = { ...range, date: nextDate };
|
|
178
|
+
const currentStart = rangeToAbsoluteMinutes(range.date, range.startTime);
|
|
179
|
+
const nextStart = rangeToAbsoluteMinutes(nextDate, range.startTime);
|
|
180
|
+
if (currentStart === null || nextStart === null) return next;
|
|
181
|
+
|
|
182
|
+
const shifted = addMinutesToTimeValue(
|
|
183
|
+
range.endDate,
|
|
184
|
+
range.endTime,
|
|
185
|
+
nextStart - currentStart,
|
|
186
|
+
);
|
|
187
|
+
if (!shifted) return next;
|
|
188
|
+
const shiftedEnd = rangeToAbsoluteMinutes(shifted.date, shifted.time);
|
|
189
|
+
if (shiftedEnd !== null && shiftedEnd > nextStart) {
|
|
190
|
+
return { ...next, endDate: shifted.date, endTime: shifted.time };
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
const repaired = addMinutesToTimeValue(
|
|
194
|
+
nextDate,
|
|
195
|
+
range.startTime,
|
|
196
|
+
TIME_SLOT_MINUTES,
|
|
197
|
+
);
|
|
198
|
+
if (!repaired) return next;
|
|
199
|
+
return { ...next, endDate: repaired.date, endTime: repaired.time };
|
|
200
|
+
}
|
|
201
|
+
|
|
168
202
|
/**
|
|
169
203
|
* Resolves an end-time pick against the start. A pick that reads as earlier in
|
|
170
204
|
* the day is the wrapped option from `buildTimeOptions`, so it belongs to the
|