@@ -43,63 +43,68 @@ func (m *UI) loadSession(sessionID string) tea.Cmd {
43 return func() tea.Msg {
43 return func() tea.Msg {
44 session, err := m.com.App.Sessions.Get(context.Background(), sessionID)
44 session, err := m.com.App.Sessions.Get(context.Background(), sessionID)
45 if err != nil {
45 if err != nil {
46− // TODO: better error handling
47− return util.ReportError(err)()
46+ return util.ReportError(err)
50− files, err := m.com.App.History.ListBySession(context.Background(), sessionID)
49+ sessionFiles, err := m.loadSessionFiles(sessionID)
51 if err != nil {
50 if err != nil {
52− // TODO: better error handling
53− return util.ReportError(err)()
51+ return util.ReportError(err)
56− filesByPath := make(map[string][]history.File)
54+ return loadSessionMsg{
57− for _, f := range files {
55+ session: &session,
58− filesByPath[f.Path] = append(filesByPath[f.Path], f)
56+ files: sessionFiles,
61− sessionFiles := make([]SessionFile, 0, len(filesByPath))
61+func (m *UI) loadSessionFiles(sessionID string) ([]SessionFile, error) {
62− for _, versions := range filesByPath {
62+ files, err := m.com.App.History.ListBySession(context.Background(), sessionID)
63− if len(versions) == 0 {
63+ if err != nil {
64− continue
64+ return nil, err
69− for _, v := range versions {
70− if v.Version < first.Version {
73− if v.Version > last.Version {
78− _, additions, deletions := diff.GenerateDiff(first.Content, last.Content, first.Path)
67+ filesByPath := make(map[string][]history.File)
68+ for _, f := range files {
69+ filesByPath[f.Path] = append(filesByPath[f.Path], f)
80− sessionFiles = append(sessionFiles, SessionFile{
71+ sessionFiles := make([]SessionFile, 0, len(filesByPath))
81− FirstVersion: first,
72+ for _, versions := range filesByPath {
82− LatestVersion: last,
73+ if len(versions) == 0 {
83− Additions: additions,
74+ continue
84− Deletions: deletions,
88− slices.SortFunc(sessionFiles, func(a, b SessionFile) int {
77+ first := versions[0]
89− if a.LatestVersion.UpdatedAt > b.LatestVersion.UpdatedAt {
78+ last := versions[0]
90− return -1
79+ for _, v := range versions {
80+ if v.Version < first.Version {
92− if a.LatestVersion.UpdatedAt < b.LatestVersion.UpdatedAt {
83+ if v.Version > last.Version {
88+ _, additions, deletions := diff.GenerateDiff(first.Content, last.Content, first.Path)
90+ sessionFiles = append(sessionFiles, SessionFile{
93+ Additions: additions,
94+ Deletions: deletions,
98+ slices.SortFunc(sessionFiles, func(a, b SessionFile) int {
99+ if a.LatestVersion.UpdatedAt > b.LatestVersion.UpdatedAt {
98− return loadSessionMsg{
100+ return -1
100− files: sessionFiles,
102+ if a.LatestVersion.UpdatedAt < b.LatestVersion.UpdatedAt {
107+ return sessionFiles, nil
105// handleFileEvent processes file change events and updates the session file
110// handleFileEvent processes file change events and updates the session file
@@ -110,59 +115,14 @@ func (m *UI) handleFileEvent(file history.File) tea.Cmd {
112 return func() tea.Msg {
117 return func() tea.Msg {
113− existingIdx := -1
118+ sessionFiles, err := m.loadSessionFiles(m.session.ID)
114− for i, sf := range m.sessionFiles {
119+ // could not load session files
115− if sf.FirstVersion.Path == file.Path {
120+ if err != nil {
116− existingIdx = i
121+ return util.NewErrorMsg(err)
121− if existingIdx == -1 {
122− newFiles := make([]SessionFile, 0, len(m.sessionFiles)+1)
123− newFiles = append(newFiles, SessionFile{
125− LatestVersion: file,
129− newFiles = append(newFiles, m.sessionFiles...)
131− return loadSessionMsg{
137− updated := m.sessionFiles[existingIdx]
139− if file.Version < updated.FirstVersion.Version {
140− updated.FirstVersion = file
143− if file.Version > updated.LatestVersion.Version {
144− updated.LatestVersion = file
147− _, additions, deletions := diff.GenerateDiff(
148− updated.FirstVersion.Content,
149− updated.LatestVersion.Content,
150− updated.FirstVersion.Path,
152− updated.Additions = additions
153− updated.Deletions = deletions
155− newFiles := make([]SessionFile, 0, len(m.sessionFiles))
156− newFiles = append(newFiles, updated)
157− for i, sf := range m.sessionFiles {
158− if i != existingIdx {
159− newFiles = append(newFiles, sf)
163− return loadSessionMsg{
124+ return sessionFilesUpdatesMsg{
164− session: m.session,
125+ sessionFiles: sessionFiles,
@@ -177,9 +137,15 @@ func (m *UI) filesInfo(cwd string, width, maxItems int, isSection bool) string {
177 title = common.Section(t, "Modified Files", width)
137 title = common.Section(t, "Modified Files", width)
179 list := t.Subtle.Render("None")
139 list := t.Subtle.Render("None")
180−
140+ var filesWithChanges []SessionFile
181− if len(m.sessionFiles) > 0 {
141+ for _, f := range m.sessionFiles {
142+ if f.Additions == 0 && f.Deletions == 0 {
145+ filesWithChanges = append(filesWithChanges, f)
147+ if len(filesWithChanges) > 0 {
182− list = fileList(t, cwd, m.sessionFiles, width, maxItems)
148+ list = fileList(t, cwd, filesWithChanges, width, maxItems)
185 return lipgloss.NewStyle().Width(width).Render(fmt.Sprintf("%s\n\n%s", title, list))
151 return lipgloss.NewStyle().Width(width).Render(fmt.Sprintf("%s\n\n%s", title, list))
@@ -187,21 +153,13 @@ func (m *UI) filesInfo(cwd string, width, maxItems int, isSection bool) string {
188// fileList renders a list of files with their diff statistics, truncating to
154// fileList renders a list of files with their diff statistics, truncating to
189// maxItems and showing a "...and N more" message if needed.
155// maxItems and showing a "...and N more" message if needed.
190−func fileList(t *styles.Styles, cwd string, files []SessionFile, width, maxItems int) string {
156+func fileList(t *styles.Styles, cwd string, filesWithChanges []SessionFile, width, maxItems int) string {
191 if maxItems <= 0 {
157 if maxItems <= 0 {
192 return ""
158 return ""
194 var renderedFiles []string
160 var renderedFiles []string
195 filesShown := 0
161 filesShown := 0
197− var filesWithChanges []SessionFile
198− for _, f := range files {
199− if f.Additions == 0 && f.Deletions == 0 {
202− filesWithChanges = append(filesWithChanges, f)
205 for _, f := range filesWithChanges {
163 for _, f := range filesWithChanges {
206 // Skip files with no changes
164 // Skip files with no changes
207 if filesShown >= maxItems {
165 if filesShown >= maxItems {