Skip to content

Commit b9a201c

Browse files
committed
refactor(ui/loading_animation): simplify session status handling
Revert to simpler jobs_count logic
1 parent 0187086 commit b9a201c

2 files changed

Lines changed: 31 additions & 112 deletions

File tree

lua/opencode/ui/loading_animation.lua

Lines changed: 31 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -62,74 +62,48 @@ function M._format_status_text(status)
6262
end
6363

6464
local function unsubscribe_session_status_event(manager)
65-
-- No-op: disable session.status event subscription introduced recently.
66-
-- Reverting session.status handling to avoid interfering with existing
67-
-- behavior. This keeps the loading animation logic focused on job_count
68-
-- and user_message_count as before.
69-
return
65+
if manager and M._animation.status_event_manager == manager then
66+
manager:unsubscribe('session.status', M.on_session_status)
67+
M._animation.status_event_manager = nil
68+
end
7069
end
7170

7271
local function subscribe_session_status_event(manager)
73-
-- No-op: do not subscribe to session.status events. See note in
74-
-- unsubscribe_session_status_event for rationale.
75-
return
76-
end
77-
78-
local function is_active_session_busy()
79-
local active_session = state.active_session
80-
local session_id = active_session and active_session.id
81-
if session_id and ((state.user_message_count or {})[session_id] or 0) > 0 then
82-
return true
72+
if not manager then
73+
return
8374
end
8475

85-
local ok, question_window = pcall(require, 'opencode.ui.question_window')
86-
if ok and question_window.has_question and question_window.belongs_to_active_session then
87-
local current_question = question_window._current_question
88-
if question_window.has_question() and question_window.belongs_to_active_session(current_question) then
89-
return true
90-
end
76+
if M._animation.status_event_manager and M._animation.status_event_manager ~= manager then
77+
unsubscribe_session_status_event(M._animation.status_event_manager)
9178
end
9279

93-
if M._animation.status_data and M._animation.status_data.type ~= 'idle' then
94-
return true
80+
if M._animation.status_event_manager == manager then
81+
return
9582
end
9683

97-
return state.jobs.is_running()
84+
manager:subscribe('session.status', M.on_session_status)
85+
M._animation.status_event_manager = manager
9886
end
9987

10088
function M.on_session_status(properties)
101-
-- Disabled: Ignore session.status updates to keep loading animation
102-
-- behavior stable. Previously this updated status_data and triggered
103-
-- a render which caused regressions in some environments.
104-
return
89+
if not properties or type(properties) ~= 'table' then
90+
return
91+
end
92+
93+
local active_session = state.active_session
94+
if active_session and active_session.id and properties.sessionID ~= active_session.id then
95+
return
96+
end
97+
98+
M._animation.status_data = properties.status
99+
M.render(state.windows)
105100
end
106101

107102
local function on_active_session_change(_, new_session, old_session)
108103
local new_id = new_session and new_session.id
109104
local old_id = old_session and old_session.id
110105
if new_id ~= old_id then
111106
M._animation.status_data = nil
112-
if is_active_session_busy() then
113-
M.start(state.windows)
114-
else
115-
M.stop()
116-
end
117-
end
118-
end
119-
120-
local function on_user_message_count_change()
121-
if not state.windows then
122-
return
123-
end
124-
125-
if is_active_session_busy() then
126-
if not M.is_running() then
127-
M.start(state.windows)
128-
else
129-
M.render(state.windows)
130-
end
131-
else
132-
M.stop()
133107
end
134108
end
135109

@@ -164,7 +138,7 @@ M.render = vim.schedule_wrap(function(windows)
164138
return false
165139
end
166140

167-
if not is_active_session_busy() then
141+
if not state.jobs.is_running() then
168142
M.stop()
169143
return false
170144
end
@@ -194,7 +168,7 @@ function M._start_animation_timer(windows)
194168
on_tick = function()
195169
M._animation.current_frame = M._next_frame()
196170
M.render(state.windows)
197-
if is_active_session_busy() then
171+
if state.jobs.is_running() then
198172
return true
199173
else
200174
M.stop()
@@ -240,32 +214,25 @@ local function on_running_change(_, new_value)
240214
return
241215
end
242216

243-
if (new_value and new_value > 0) or is_active_session_busy() then
244-
if not M.is_running() then
245-
M.start(state.windows)
246-
else
247-
M.render(state.windows)
248-
end
217+
if not M.is_running() and new_value and new_value > 0 then
218+
M.start(state.windows)
249219
else
250220
M.stop()
251221
end
252222
end
253223

254224
function M.setup()
255225
state.store.subscribe('job_count', on_running_change)
256-
state.store.subscribe('user_message_count', on_user_message_count_change)
257226
state.store.subscribe('active_session', on_active_session_change)
258-
if is_active_session_busy() then
259-
M.start(state.windows)
260-
else
261-
M.stop()
262-
end
227+
state.store.subscribe('event_manager', on_event_manager_change)
228+
subscribe_session_status_event(state.event_manager)
263229
end
264230

265231
function M.teardown()
266232
state.store.unsubscribe('job_count', on_running_change)
267-
state.store.unsubscribe('user_message_count', on_user_message_count_change)
268233
state.store.unsubscribe('active_session', on_active_session_change)
234+
state.store.unsubscribe('event_manager', on_event_manager_change)
235+
unsubscribe_session_status_event(M._animation.status_event_manager)
269236
M._animation.status_data = nil
270237
end
271238

tests/unit/loading_animation_spec.lua

Lines changed: 0 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,17 @@ local loading_animation = require('opencode.ui.loading_animation')
33

44
describe('loading_animation status text', function()
55
local original_time
6-
local original_windows
76

87
before_each(function()
98
original_time = os.time
10-
original_windows = state.windows
119
loading_animation._animation.status_data = nil
1210
state.session.clear_active()
13-
state.session.set_user_message_count({})
1411
end)
1512

1613
after_each(function()
1714
os.time = original_time
1815
loading_animation._animation.status_data = nil
1916
state.session.clear_active()
20-
state.session.set_user_message_count({})
21-
state.ui.set_windows(original_windows)
2217
end)
2318

2419
it('renders busy as thinking text', function()
@@ -59,47 +54,4 @@ describe('loading_animation status text', function()
5954

6055
assert.is_nil(loading_animation._animation.status_data)
6156
end)
62-
63-
it('treats pending work on the active session as busy', function()
64-
state.session.set_active({ id = 'ses_active' })
65-
state.session.set_user_message_count({ ses_active = 1 })
66-
67-
assert.is_true(loading_animation._get_display_text():find('Thinking', 1, true) ~= nil)
68-
end)
69-
70-
it('starts when the active session still has pending work after reopening', function()
71-
local output_buf = vim.api.nvim_create_buf(false, true)
72-
local footer_buf = vim.api.nvim_create_buf(false, true)
73-
state.ui.set_windows({ output_buf = output_buf, footer_buf = footer_buf })
74-
state.session.set_active({ id = 'ses_active' })
75-
state.session.set_user_message_count({ ses_active = 1 })
76-
77-
loading_animation.setup()
78-
79-
assert.is_true(loading_animation.is_running())
80-
81-
loading_animation.teardown()
82-
pcall(vim.api.nvim_buf_delete, output_buf, { force = true })
83-
pcall(vim.api.nvim_buf_delete, footer_buf, { force = true })
84-
end)
85-
86-
it('keeps spinner active while the active session has a pending question', function()
87-
local question_window = require('opencode.ui.question_window')
88-
state.session.set_active({ id = 'ses_active' })
89-
question_window._current_question = {
90-
id = 'q1',
91-
sessionID = 'ses_active',
92-
questions = {
93-
{
94-
question = 'Pick one',
95-
header = 'Test',
96-
options = { { label = 'One', description = 'first' } },
97-
},
98-
},
99-
}
100-
101-
assert.is_true(loading_animation._get_display_text():find('Thinking', 1, true) ~= nil)
102-
103-
question_window._current_question = nil
104-
end)
10557
end)

0 commit comments

Comments
 (0)