返回 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 if req.readContext != nil {
17 ctx = req.readContext
18 }
19 preferred, _ := catalog.PreferredOrdinarySessionPaths(ctx, req.Scope, req.WorkspaceRoot)
20 cursor := ""
21 for {
22 page, err := catalog.ListTopics(ctx, sessioncatalog.TopicPageRequest{
23 Scope: req.Scope, WorkspaceRoot: req.WorkspaceRoot, Cursor: cursor,
24 Limit: sessioncatalog.MaxLimit, Query: req.Query, TimeFilter: req.TimeFilter, SortMode: req.SortMode,
25 ManualOrder: false, IncludeTopicIDsJSON: req.groupIncludeJSON,
26 ExcludeTopicIDsJSON: req.groupExcludeJSON, ExcludePinned: req.ExcludePinned,
27 CursorBinding: req.groupCursorBind,
28 })
29 if err != nil {
30 return out, err
31 }
32 out.Revision = max(out.Revision, page.Revision)
33 for _, topic := range page.Items {
34 for _, node := range a.projectNodesFromCatalogTopic(topic, topicOverlays, sessionOverlays, preferred) {
35 if projectNodeRequestAllows(req, node) {
36 out.Items = append(out.Items, node)
37 }
38 }
39 }
40 if page.NextCursor == "" {
41 break
42 }
43 if page.NextCursor == cursor {
44 return ProjectTopicPage{Items: []ProjectNode{}}, fmt.Errorf("catalog session-order cursor did not advance")
45 }
46 cursor = page.NextCursor
47 }
48 sort.SliceStable(out.Items, func(i, j int) bool {
49 return projectTopicLess(out.Items[i], out.Items[j], req.SortMode, true)
50 })
51 offset := 0
52 if strings.TrimSpace(req.Cursor) != "" {
53 var err error
54 if !strings.HasPrefix(req.Cursor, "session-order:") {
55 return ProjectTopicPage{Items: []ProjectNode{}}, fmt.Errorf("session order cursor is stale")
56 }
57 offset, err = strconv.Atoi(strings.TrimPrefix(req.Cursor, "session-order:"))
58 if err != nil || offset < 0 || offset > len(out.Items) {
59 return ProjectTopicPage{Items: []ProjectNode{}}, fmt.Errorf("invalid session order cursor")
60 }
61 }
62 limit := req.Limit
63 if limit <= 0 {
64 limit = sessioncatalog.DefaultLimit
65 }
66 limit = min(limit, sessioncatalog.MaxLimit)
67 end := min(offset+limit, len(out.Items))
68 page := ProjectTopicPage{Items: append([]ProjectNode(nil), out.Items[offset:end]...), Revision: out.Revision}
69 if end < len(out.Items) {
70 page.NextCursor = "session-order:" + strconv.Itoa(end)
71 }
72 return page, nil
73 }
74
74 lines GO