返回 DeepSeek-Reasonix
session_catalog_metadata_page.go
根目录 / desktop / session_catalog_metadata_page.go
1 package main
2
3 import (
4 "fmt"
5 "sort"
6 "strings"
7
8 "reasonix/internal/sessioncatalog"
9 )
10
11 func (a *App) metadataTopicPage(req ProjectTopicPageRequest) (ProjectTopicPage, error) {
12 var items []ProjectNode
13 if req.metadataSnapshot != nil {
14 items = cloneTopicPage(*req.metadataSnapshot)
15 } else {
16 items = a.metadataProjectTopics(req.Scope, req.WorkspaceRoot)
17 }
18 filteredByGroup := items[:0]
19 for _, item := range items {
20 if projectTopicRequestAllows(req, item.TopicID, item.Pinned) && projectNodeRequestAllows(req, item) {
21 filteredByGroup = append(filteredByGroup, item)
22 }
23 }
24 items = filteredByGroup
25 manualOrder := manualTopicOrderFor(req.Scope, req.WorkspaceRoot)
26 if req.readAllSources {
27 manualOrder = false
28 }
29 query := strings.ToLower(strings.TrimSpace(req.Query))
30 if query != "" {
31 filtered := items[:0]
32 for _, item := range items {
33 if strings.Contains(strings.ToLower(item.Label), query) {
34 filtered = append(filtered, item)
35 }
36 }
37 items = filtered
38 }
39 sort.SliceStable(items, func(i, j int) bool {
40 return projectTopicLess(items[i], items[j], req.SortMode, manualOrder)
41 })
42 start := 0
43 if lastID, ok := strings.CutPrefix(req.Cursor, "meta:"); ok {
44 if req.groupCursorBind != "" {
45 return ProjectTopicPage{Items: []ProjectNode{}}, fmt.Errorf("project topic cursor filter changed")
46 }
47 for index, item := range items {
48 if item.TopicID == lastID {
49 start = index + 1
50 break
51 }
52 }
53 } else if strings.TrimSpace(req.Cursor) != "" {
54 start = len(items)
55 for index, item := range items {
56 var after bool
57 var err error
58 if manualOrder {
59 after, err = sessioncatalog.TopicSortKeyAfterOrderedCursorBound(
60 req.Cursor, req.groupCursorBind, item.Pinned, item.SortOrder,
61 projectTopicSortValue(item.CreatedAt, item.LastActivityAt, req.SortMode), item.TopicID,
62 )
63 } else {
64 after, err = sessioncatalog.TopicSortKeyAfterCursorBound(
65 req.Cursor, req.groupCursorBind, item.Pinned,
66 projectTopicSortValue(item.CreatedAt, item.LastActivityAt, req.SortMode), item.TopicID,
67 )
68 }
69 if err != nil {
70 return ProjectTopicPage{Items: []ProjectNode{}}, err
71 }
72 if after {
73 start = index
74 break
75 }
76 }
77 }
78 limit := req.Limit
79 if limit <= 0 {
80 limit = sessioncatalog.DefaultLimit
81 }
82 if limit > sessioncatalog.MaxLimit {
83 limit = sessioncatalog.MaxLimit
84 }
85 end := min(start+limit, len(items))
86 page := ProjectTopicPage{Items: append([]ProjectNode(nil), items[start:end]...)}
87 if end < len(items) && end > start {
88 page.NextCursor = encodeProjectNodeCursor(items[end-1], req.SortMode, manualOrder, req.groupCursorBind)
89 }
90 return page, nil
91 }
92
92 lines GO