X-Git-Url: https://git.giacomolli.uk/onechat/blobdiff_plain/1a1e3835458e37b4b56897d6ff7804660798d60c..f4509310b5abe5012cb83bed3960404e8fa92217:/whatsapp_inbox.go diff --git a/whatsapp_inbox.go b/whatsapp_inbox.go index c9ca81b..8bf8a97 100644 --- a/whatsapp_inbox.go +++ b/whatsapp_inbox.go @@ -32,24 +32,6 @@ const ( whatsappCatchupTimeout = time.Minute ) -// newWhatsAppInbox returns the inbox of the batches in state, with clock for -// the times of the batch texts and groups for the names of the groups. images -// holds shared images, and logger gets image failures. Audio shares the data -// directory of state. -func newWhatsAppInbox(state *WhatsAppState, clock func() time.Time, groups *WhatsAppGroups, images *ImageStore, logger *slog.Logger) *WhatsAppInbox { - return &WhatsAppInbox{ - state: state, - clock: clock, - groups: groups, - images: images, - voices: &VoiceStore{dir: filepath.Join(filepath.Dir(filepath.Dir(state.path)), voiceDirName)}, - voice: &VoiceTranscriber{}, - logger: logger, - wake: make(chan struct{}, 1), - failures: make(chan error, 1), - } -} - // WhatsAppInbox puts messages into batches, one chat at a time, as // WhatsAppState says. deliver logs each closed batch as a work message that // starts with [WhatsApp], and a batch that needs the user wakes the turn loop. @@ -90,6 +72,24 @@ type WhatsAppInbox struct { catchupTimer *time.Timer } +// newWhatsAppInbox returns the inbox of the batches in state, with clock for +// the times of the batch texts and groups for the names of the groups. images +// holds shared images, and logger gets image failures. Audio shares the data +// directory of state. +func newWhatsAppInbox(state *WhatsAppState, clock func() time.Time, groups *WhatsAppGroups, images *ImageStore, logger *slog.Logger) *WhatsAppInbox { + return &WhatsAppInbox{ + state: state, + clock: clock, + groups: groups, + images: images, + voices: &VoiceStore{dir: filepath.Join(filepath.Dir(filepath.Dir(state.path)), voiceDirName)}, + voice: &VoiceTranscriber{}, + logger: logger, + wake: make(chan struct{}, 1), + failures: make(chan error, 1), + } +} + // due returns a channel that gets a value when the next open batch is due, or // nil when no batch is open. func (i *WhatsAppInbox) due() <-chan time.Time { @@ -129,7 +129,7 @@ func (i *WhatsAppInbox) deliver(ctx context.Context, l *TurnLoop, link WhatsAppL } if err != nil { - return err + return fmt.Errorf("close due WhatsApp batches: %w", err) } batches := i.state.Closed() @@ -183,7 +183,7 @@ func (i *WhatsAppInbox) deliver(ctx context.Context, l *TurnLoop, link WhatsAppL err = i.state.Remove(batch.Number) if err != nil { - return err + return fmt.Errorf("remove delivered WhatsApp batch: %w", err) } if batch.Turn() { @@ -230,6 +230,36 @@ func (i *WhatsAppInbox) startCatchup() { }) } +// caughtUpBy ends the catch-up of the connection with the number catchups, when +// no later connection started a new one. +func (i *WhatsAppInbox) caughtUpBy(catchups int) { + i.mutex.Lock() + defer i.mutex.Unlock() + + if i.catchups == catchups { + i.finishCatchup() + } +} + +// finishCatchup ends a running catch-up and wakes Run, which logs all batches. +// The caller holds the mutex. +func (i *WhatsAppInbox) finishCatchup() { + if !i.catchingUp { + return + } + + i.catchingUp = false + i.caughtUp = true + if i.catchupTimer != nil { + i.catchupTimer.Stop() + } + + select { + case i.wake <- struct{}{}: + default: + } +} + // receive stores images and transcribed voice notes before their batches and // wakes Run. link gives the device and the own IDs. It returns false when the // state file cannot hold the message, so that the library does not acknowledge @@ -292,36 +322,6 @@ func (i *WhatsAppInbox) imageText(ctx context.Context, link WhatsAppLink, event return imageText([]string{name}, caption) } -// caughtUpBy ends the catch-up of the connection with the number catchups, when -// no later connection started a new one. -func (i *WhatsAppInbox) caughtUpBy(catchups int) { - i.mutex.Lock() - defer i.mutex.Unlock() - - if i.catchups == catchups { - i.finishCatchup() - } -} - -// finishCatchup ends a running catch-up and wakes Run, which logs all batches. -// The caller holds the mutex. -func (i *WhatsAppInbox) finishCatchup() { - if !i.catchingUp { - return - } - - i.catchingUp = false - i.caughtUp = true - if i.catchupTimer != nil { - i.catchupTimer.Stop() - } - - select { - case i.wake <- struct{}{}: - default: - } -} - // endCatchup ends a running catch-up at OfflineSyncCompleted. func (i *WhatsAppInbox) endCatchup() { i.mutex.Lock()