2024-02-21 21:55:38 -07:00
|
|
|
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
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2024-03-30 20:50:20 -06:00
|
|
|
cmd.Flags().BoolP("all", "a", false, "Show all conversations")
|
|
|
|
cmd.Flags().IntP("count", "c", LS_COUNT, "How many conversations to show")
|
2024-02-21 21:55:38 -07:00
|
|
|
|
|
|
|
return cmd
|
|
|
|
}
|