返回 DeepSeek-Reasonix
session_catalog_ordered_page.go
根目录 / desktop / session_catalog_ordered_page.go
1 package main
2
3 import (
4 "fmt"
5 "reasonix/internal/sessioncatalog"
6 "sort"
7 "strconv"
8 "strings"
9 )
10
11 func (a *App) catalogSessionOrderedPage(catalog *sessioncatalog.Catalog, req ProjectTopicPageRequest) (ProjectTopicPage, error) {
12 out := ProjectTopicPage{Items: []ProjectNode{}}
13 topicOverlays, sessionOverlays := a.catalogRuntimeOverlays()
14 ctx, cancel := a.catalogReadContext()
15 defer cancel()
16 preferred, _ := catalog.PreferredOrdinarySessionPaths(ctx, req.Scope, req.WorkspaceRoot)
17 cursor := ""
18 for {
19 page, err := catalog.ListTopics(ctx, sessioncatalog.TopicPageRequest{
20 Scope: req.Scope, WorkspaceRoot: req.WorkspaceRoot, Cursor: cursor,
21 Limit: sessioncatalog.MaxLimit, Query: req.Query, TimeFilter: req.TimeFilter, SortMode: req.SortMode,
22 ManualOrder: false, IncludeTopicIDsJSON: req.groupIncludeJSON,
23 ExcludeTopicIDsJSON: req.groupExcludeJSON, ExcludePinned: req.ExcludePinned,
24 CursorBinding: req.groupCursorBind,
25 })
26 if err != nil {
27 return out, err
28 }
29 out.Revision = max(out.Revision, page.Revision)
30 for _, topic := range page.Items {
31 for _, node := range a.projectNodesFromCatalogTopic(topic, topicOverlays, sessionOverlays, preferred) {
32 if projectNodeRequestAllows(req, node) {
33 out.Items = append(out.Items, node)
34 }
35 }
36 }
37 if page.NextCursor == "" {
38 break
39 }
40 if page.NextCursor == cursor {
41 return ProjectTopicPage{Items: []ProjectNode{}}, fmt.Errorf("catalog session-order cursor did not advance")
42 }
43 cursor = page.NextCursor
44 }
45 sort.SliceStable(out.Items, func(i, j int) bool {
46 return projectTopicLess(out.Items[i], out.Items[j], req.SortMode, true)
47 })
48 offset := 0
49 if strings.TrimSpace(req.Cursor) != "" {
50 var err error
51 if !strings.HasPrefix(req.Cursor, "session-order:") {
52 return ProjectTopicPage{Items: []ProjectNode{}}, fmt.Errorf("session order cursor is stale")
53 }
54 offset, err = strconv.Atoi(strings.TrimPrefix(req.Cursor, "session-order:"))
55 if err != nil || offset < 0 || offset > len(out.Items) {
56 return ProjectTopicPage{Items: []ProjectNode{}}, fmt.Errorf("invalid session order cursor")
57 }
58 }
59 limit := req.Limit
60 if limit <= 0 {
61 limit = sessioncatalog.DefaultLimit
62 }
63 limit = min(limit, sessioncatalog.MaxLimit)
64 end := min(offset+limit, len(out.Items))
65 page := ProjectTopicPage{Items: append([]ProjectNode(nil), out.Items[offset:end]...), Revision: out.Revision}
66 if end < len(out.Items) {
67 page.NextCursor = "session-order:" + strconv.Itoa(end)
68 }
69 return page, nil
70 }
71
71 lines GO