lmcli/pkg/cmd/list.go

123 lines
3.2 KiB
Go

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
}