Add @all mention type that notifies all workspace members (excluding agents). Includes backend parsing, notification expansion to all members, and frontend UI with autocomplete suggestion, rendering, and hover card.
43 lines
1.1 KiB
Go
43 lines
1.1 KiB
Go
package util
|
|
|
|
import "regexp"
|
|
|
|
// Mention represents a parsed @mention from markdown content.
|
|
type Mention struct {
|
|
Type string // "member", "agent", or "all"
|
|
ID string // user_id, agent_id, or "all"
|
|
}
|
|
|
|
// MentionRe matches [@Label](mention://type/id) in markdown.
|
|
var MentionRe = regexp.MustCompile(`\[@[^\]]*\]\(mention://(member|agent|all)/([0-9a-fA-F-]+|all)\)`)
|
|
|
|
// IsMentionAll returns true if the mention is an @all mention.
|
|
func (m Mention) IsMentionAll() bool {
|
|
return m.Type == "all"
|
|
}
|
|
|
|
// ParseMentions extracts deduplicated mentions from markdown content.
|
|
func ParseMentions(content string) []Mention {
|
|
matches := MentionRe.FindAllStringSubmatch(content, -1)
|
|
seen := make(map[string]bool)
|
|
var result []Mention
|
|
for _, m := range matches {
|
|
key := m[1] + ":" + m[2]
|
|
if seen[key] {
|
|
continue
|
|
}
|
|
seen[key] = true
|
|
result = append(result, Mention{Type: m[1], ID: m[2]})
|
|
}
|
|
return result
|
|
}
|
|
|
|
// HasMentionAll returns true if any mention in the slice is an @all mention.
|
|
func HasMentionAll(mentions []Mention) bool {
|
|
for _, m := range mentions {
|
|
if m.IsMentionAll() {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|