1- import { useMutation , useQuery , useQueryClient } from "@tanstack/react-query" ;
1+ import { useMutation , useQuery } from "@tanstack/react-query" ;
22import { AlertCircleIcon , ArrowRightIcon , CheckIcon } from "lucide-react" ;
3- import { useMemo , useState } from "react" ;
3+ import { useEffect , useMemo } from "react" ;
44
55import {
66 commands as appleCalendarCommands ,
@@ -18,6 +18,7 @@ import {
1818import { Button } from "@hypr/ui/components/ui/button" ;
1919import { cn } from "@hypr/utils" ;
2020
21+ import * as main from "../../../../store/tinybase/main" ;
2122import { PROVIDERS } from "../shared" ;
2223import {
2324 type CalendarGroup ,
@@ -131,24 +132,74 @@ function appleColorToCss(color?: CalendarColor | null): string | undefined {
131132}
132133
133134function useAppleCalendarSelection ( ) {
134- const queryClient = useQueryClient ( ) ;
135- const [ enabledCalendars , setEnabledCalendars ] = useState < Set < string > > (
136- new Set ( ) ,
137- ) ;
135+ const { user_id } = main . UI . useValues ( main . STORE_ID ) ;
136+ const calendarsTable = main . UI . useTable ( "calendars" , main . STORE_ID ) ;
138137
139- const { data : appleCalendars } = useQuery ( {
138+ const {
139+ data : appleCalendars ,
140+ refetch,
141+ isFetching,
142+ } = useQuery ( {
140143 queryKey : [ "appleCalendars" ] ,
141144 queryFn : async ( ) => {
142- const result = await appleCalendarCommands . listCalendars ( ) ;
143- if ( result . status === "ok" ) {
144- return result . data ;
145+ const operation = appleCalendarCommands . listCalendars ( ) ;
146+ const minDelay = new Promise ( ( resolve ) => setTimeout ( resolve , 500 ) ) ;
147+
148+ const [ result ] = await Promise . all ( [ operation , minDelay ] ) ;
149+ if ( result . status === "error" ) {
150+ throw new Error ( result . error ) ;
145151 }
146- throw new Error ( result . error ) ;
152+ return result . data ;
147153 } ,
148154 } ) ;
149155
156+ const createCalendarRow = main . UI . useSetRowCallback (
157+ "calendars" ,
158+ ( p : { id : string ; name : string } ) => p . id ,
159+ ( p : { id : string ; name : string } ) => ( {
160+ user_id : user_id ?? "" ,
161+ created_at : new Date ( ) . toISOString ( ) ,
162+ name : p . name ,
163+ enabled : false ,
164+ } ) ,
165+ [ user_id ] ,
166+ main . STORE_ID ,
167+ ) ;
168+
169+ const updateCalendarName = main . UI . useSetCellCallback (
170+ "calendars" ,
171+ ( p : { id : string ; name : string } ) => p . id ,
172+ "name" ,
173+ ( p : { id : string ; name : string } ) => p . name ,
174+ [ ] ,
175+ main . STORE_ID ,
176+ ) ;
177+
178+ useEffect ( ( ) => {
179+ if ( ! appleCalendars || ! user_id ) {
180+ return ;
181+ }
182+
183+ for ( const cal of appleCalendars ) {
184+ const existing = calendarsTable [ cal . id ] ;
185+ if ( ! existing ) {
186+ createCalendarRow ( { id : cal . id , name : cal . title } ) ;
187+ } else if ( existing . name !== cal . title ) {
188+ updateCalendarName ( { id : cal . id , name : cal . title } ) ;
189+ }
190+ }
191+ } , [
192+ appleCalendars ,
193+ user_id ,
194+ calendarsTable ,
195+ createCalendarRow ,
196+ updateCalendarName ,
197+ ] ) ;
198+
150199 const groups = useMemo ( ( ) : CalendarGroup [ ] => {
151- if ( ! appleCalendars ) return [ ] ;
200+ if ( ! appleCalendars ) {
201+ return [ ] ;
202+ }
152203
153204 const grouped = new Map < string , CalendarItem [ ] > ( ) ;
154205 for ( const cal of appleCalendars ) {
@@ -170,30 +221,47 @@ function useAppleCalendarSelection() {
170221 } , [ appleCalendars ] ) ;
171222
172223 const isCalendarEnabled = ( calendarId : string ) : boolean => {
173- return enabledCalendars . has ( calendarId ) ;
224+ const calendar = calendarsTable [ calendarId ] ;
225+ return calendar ?. enabled === true ;
174226 } ;
175227
176- const handleToggle = ( calendar : CalendarItem , enabled : boolean ) => {
177- setEnabledCalendars ( ( prev ) => {
178- const next = new Set ( prev ) ;
179- if ( enabled ) {
180- next . add ( calendar . id ) ;
181- } else {
182- next . delete ( calendar . id ) ;
228+ const setCalendarRow = main . UI . useSetRowCallback (
229+ "calendars" ,
230+ ( p : { calendarId : string ; enabled : boolean } ) => p . calendarId ,
231+ ( p : { calendarId : string ; enabled : boolean } ) => {
232+ const existing = calendarsTable [ p . calendarId ] ;
233+ if ( ! existing ) {
234+ return {
235+ user_id : user_id ?? "" ,
236+ created_at : new Date ( ) . toISOString ( ) ,
237+ name : "" ,
238+ enabled : p . enabled ,
239+ } ;
183240 }
184- return next ;
185- } ) ;
186- } ;
241+ return {
242+ ...existing ,
243+ enabled : p . enabled ,
244+ } ;
245+ } ,
246+ [ calendarsTable , user_id ] ,
247+ main . STORE_ID ,
248+ ) ;
187249
188- const handleRefresh = ( ) => {
189- queryClient . invalidateQueries ( { queryKey : [ "appleCalendars" ] } ) ;
250+ const handleToggle = ( calendar : CalendarItem , enabled : boolean ) => {
251+ setCalendarRow ( { calendarId : calendar . id , enabled } ) ;
190252 } ;
191253
192- return { groups, isCalendarEnabled, handleToggle, handleRefresh } ;
254+ return {
255+ groups,
256+ isCalendarEnabled,
257+ handleToggle,
258+ handleRefresh : refetch ,
259+ isLoading : isFetching ,
260+ } ;
193261}
194262
195263function AppleCalendarSelection ( ) {
196- const { groups, isCalendarEnabled, handleToggle, handleRefresh } =
264+ const { groups, isCalendarEnabled, handleToggle, handleRefresh, isLoading } =
197265 useAppleCalendarSelection ( ) ;
198266
199267 return (
@@ -202,6 +270,7 @@ function AppleCalendarSelection() {
202270 isCalendarEnabled = { isCalendarEnabled }
203271 onToggle = { handleToggle }
204272 onRefresh = { handleRefresh }
273+ isLoading = { isLoading }
205274 />
206275 ) ;
207276}
0 commit comments