fix(maildir): 同步邮件已读状态到 maildir 标记

- 读取邮件时同步更新 maildir 的 `S` 标记,避免数据库已读状态与文件名不同步。
- 写入邮件到 `maildir` 时保留已有非托管标记,并确保已读/星标标记正确拼接。
- 补充测试,校验已发送邮件和草稿的原始路径包含已读标记。
This commit is contained in:
LanQin_
2026-06-24 15:33:56 +08:00
parent f8d058f7e4
commit 632a8a4896
3 changed files with 34 additions and 3 deletions
+24 -3
View File
@@ -120,6 +120,7 @@ func (a *App) writeRawMessageToMaildirFolder(ctx context.Context, messageID, fol
filename := maildirFilename(messageID, state.MessageID)
tmpPath := filepath.Join(folderBase, "tmp", filename)
finalPath := filepath.Join(folderBase, subdir, filename)
finalPath = maildirPathWithFlags(finalPath, state.IsRead, state.IsStarred)
if err := os.WriteFile(tmpPath, raw, 0o600); err != nil {
return err
}
@@ -490,15 +491,17 @@ func maildirPathWithFlags(path string, read, starred bool) string {
}
base := name
sep := maildirFlagSeparator()
existingFlags := ""
if idx := strings.LastIndex(base, sep); idx >= 0 {
existingFlags = base[idx+len(sep):]
base = base[:idx]
}
flags := ""
flags := preserveMaildirFlags(existingFlags, "SF")
if read {
flags += "S"
flags = appendMaildirFlag(flags, 'S')
}
if starred {
flags += "F"
flags = appendMaildirFlag(flags, 'F')
}
if flags != "" {
base += sep + flags
@@ -506,6 +509,24 @@ func maildirPathWithFlags(path string, read, starred bool) string {
return filepath.Join(dir, base)
}
func preserveMaildirFlags(flags, managed string) string {
var b strings.Builder
for _, flag := range flags {
if strings.ContainsRune(managed, flag) || strings.ContainsRune(b.String(), flag) {
continue
}
b.WriteRune(flag)
}
return b.String()
}
func appendMaildirFlag(flags string, flag rune) string {
if strings.ContainsRune(flags, flag) {
return flags
}
return flags + string(flag)
}
func maildirFlagSeparator() string {
if runtime.GOOS == "windows" {
return "!2,"