package cmd import ( "fmt" "slices" "time" "git.mlow.ca/mlow/lmcli/pkg/lmcli" "git.mlow.ca/mlow/lmcli/pkg/util" "github.com/spf13/cobra" ) const ( LS_COUNT int = 5 ) func ListCmd(ctx *lmcli.Context) *cobra.Command { cmd := &cobra.Command{ Use: "list", Aliases: []string{"ls"}, Short: "List conversations", Long: `List conversations in order of recent activity`, RunE: func(cmd *cobra.Command, args []string) error { conversations, err := ctx.Store.Conversations() if err != nil { return fmt.Errorf("Could not fetch conversations: %v", err) } type Category struct { name string cutoff time.Duration } type ConversationLine struct { timeSinceReply time.Duration formatted string } now := time.Now() midnight := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location()) monthStart := time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, now.Location()) dayOfWeek := int(now.Weekday()) categories := []Category{ {"today", now.Sub(midnight)}, {"yesterday", now.Sub(midnight.AddDate(0, 0, -1))}, {"this week", now.Sub(midnight.AddDate(0, 0, -dayOfWeek))}, {"last week", now.Sub(midnight.AddDate(0, 0, -(dayOfWeek + 7)))}, {"this month", now.Sub(monthStart)}, {"last month", now.Sub(monthStart.AddDate(0, -1, 0))}, {"2 months ago", now.Sub(monthStart.AddDate(0, -2, 0))}, {"3 months ago", now.Sub(monthStart.AddDate(0, -3, 0))}, {"4 months ago", now.Sub(monthStart.AddDate(0, -4, 0))}, {"5 months ago", now.Sub(monthStart.AddDate(0, -5, 0))}, {"older", now.Sub(time.Time{})}, } categorized := map[string][]ConversationLine{} all, _ := cmd.Flags().GetBool("all") for _, conversation := range conversations { lastMessage, err := ctx.Store.LastMessage(&conversation) if lastMessage == nil || err != nil { continue } messageAge := now.Sub(lastMessage.CreatedAt) var category string for _, c := range categories { if messageAge < c.cutoff { category = c.name break } } formatted := fmt.Sprintf( "%s - %s - %s", conversation.ShortName.String, util.HumanTimeElapsedSince(messageAge), conversation.Title, ) categorized[category] = append( categorized[category], ConversationLine{messageAge, formatted}, ) } count, _ := cmd.Flags().GetInt("count") var conversationsPrinted int outer: for _, category := range categories { conversationLines, ok := categorized[category.name] if !ok { continue } slices.SortFunc(conversationLines, func(a, b ConversationLine) int { return int(a.timeSinceReply - b.timeSinceReply) }) fmt.Printf("%s:\n", category.name) for _, conv := range conversationLines { if conversationsPrinted >= count && !all { fmt.Printf("%d remaining message(s), use --all to view.\n", len(conversations)-conversationsPrinted) break outer } fmt.Printf(" %s\n", conv.formatted) conversationsPrinted++ } } return nil }, } cmd.Flags().Bool("all", false, "Show all conversations") cmd.Flags().Int("count", LS_COUNT, "How many conversations to show") return cmd }