fix(mail): 답장도 리스트에 각각 표시(스레드 단위 가시성) + 동기화 진행 신호
All checks were successful
build-and-push / build (push) Successful in 32s
All checks were successful
build-and-push / build (push) Successful in 32s
- 가시성을 메일 단위 → '내가 참여한 스레드 전체'로: 한 스레드에서 한 통이라도 from/to/cc면 그 스레드의 원문·답장 모두 노출(각각의 행). 무관 스레드는 숨김. - isSyncing(): 백필/수동 동기화 진행 중이면 mails 응답에 syncing=true → 프론트 폴링 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
7e1bb6606e
commit
14e8a62f76
@ -603,6 +603,9 @@ func (s *Server) handleListProjectMails(w http.ResponseWriter, r *http.Request)
|
||||
if st.LastError != "" {
|
||||
resp["error"] = st.LastError
|
||||
}
|
||||
if isSyncing(id) {
|
||||
resp["syncing"] = true
|
||||
}
|
||||
// First ever view → kick off full backfill in the background (only if mail
|
||||
// integration is configured). Already-stored mail is shown regardless.
|
||||
if !synced && s.mail.Enabled() {
|
||||
@ -619,10 +622,24 @@ func (s *Server) handleListProjectMails(w http.ResponseWriter, r *http.Request)
|
||||
notes[n.MessageID] = n
|
||||
}
|
||||
me := s.email(r)
|
||||
// 가시성: 내가 참여한 "스레드 전체"를 노출(원문 + 답장 각각). 한 스레드에서
|
||||
// 한 통이라도 내가 from/to/cc면 그 스레드의 모든 메일이 보인다.
|
||||
myThreads := map[string]bool{}
|
||||
involvedSolo := map[string]bool{}
|
||||
for _, row := range rows {
|
||||
m := mailsync.Message{From: row.FromAddr, To: row.ToAddr, Cc: row.CcAddr}
|
||||
if m.Involves(me) {
|
||||
if row.ThreadID != "" {
|
||||
myThreads[row.ThreadID] = true
|
||||
} else {
|
||||
involvedSolo[row.MessageID] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
items := make([]mailItem, 0, len(rows))
|
||||
for _, row := range rows {
|
||||
m := mailsync.Message{ID: row.MessageID, From: row.FromAddr, To: row.ToAddr, Cc: row.CcAddr}
|
||||
if !m.Involves(me) {
|
||||
visible := involvedSolo[row.MessageID] || (row.ThreadID != "" && myThreads[row.ThreadID])
|
||||
if !visible {
|
||||
continue
|
||||
}
|
||||
it := mailItem{ProjectMailMsg: row}
|
||||
|
||||
@ -16,6 +16,12 @@ import (
|
||||
// syncInFlight prevents concurrent syncs of the same project.
|
||||
var syncInFlight sync.Map // projectID -> struct{}
|
||||
|
||||
// isSyncing reports whether a sync is currently running for the project.
|
||||
func isSyncing(projectID string) bool {
|
||||
_, ok := syncInFlight.Load(projectID)
|
||||
return ok
|
||||
}
|
||||
|
||||
// syncProjectMail pulls the project's client-domain mail across ALL active member
|
||||
// mailboxes (domain-wide delegation), upserts the headers into ProjectMailMsg, and
|
||||
// records sync state. full=true pages the entire history; otherwise just the newest
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user