Skip to content

Commit 4c79e5d

Browse files
committed
feat: update new API syntax from backend
1 parent 20f6bcf commit 4c79e5d

File tree

8 files changed

+309
-584
lines changed

8 files changed

+309
-584
lines changed

lua/codeme/init.lua

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -92,11 +92,8 @@ function M.track(is_save)
9292
end
9393

9494
--- Get stats from backend
95-
function M.get_stats(callback, today_only)
96-
local cmd = M.config.codeme_bin .. " stats --json"
97-
if today_only then
98-
cmd = cmd .. " --today"
99-
end
95+
function M.get_stats(callback)
96+
local cmd = M.config.codeme_bin .. " api --compress"
10097

10198
vim.fn.jobstart(cmd, {
10299
stdout_buffered = true,

lua/codeme/profile/tabs/activity.lua

Lines changed: 55 additions & 138 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,21 @@
11
local state = require("codeme.profile.state")
22
local fmt = require("codeme.profile.formatters")
3-
local helpers = require("codeme.profile.helpers")
43
local ui = require("codeme.ui")
54

65
local M = {}
76

87
function M.render()
9-
local s = state.stats
8+
local s = state.stats or {}
109
local lines = {}
1110

12-
-- Header with daily summary
13-
local today_date = os.date("%A, %B %d")
14-
local today_sessions = s.today.sessions or {}
15-
local total_time = 0
16-
for _, session in ipairs(today_sessions) do
17-
total_time = total_time + (session.duration or 0)
18-
end
11+
local today = s.today or {}
12+
local total_time = today.total_time or 0
13+
local focus_score = s.focus_score or 0
14+
local peak_hour = today.peak_hour
15+
local languages = today.languages or {}
1916

20-
local total_time = 0
21-
for _, session in ipairs(today_sessions) do
22-
total_time = total_time + (session.duration or 0)
23-
end
17+
-- Header
18+
local today_date = os.date("%A, %B %d")
2419

2520
table.insert(lines, {})
2621
table.insert(lines, {
@@ -32,23 +27,17 @@ function M.render()
3227
})
3328
table.insert(lines, {})
3429

35-
if #today_sessions == 0 then
36-
table.insert(lines, { { " No coding sessions yet today", "commentfg" } })
30+
if total_time == 0 then
31+
table.insert(lines, { { " No coding activity yet today", "commentfg" } })
3732
table.insert(lines, { { " Start working to track your productivity!", "commentfg" } })
3833
table.insert(lines, {})
3934
return lines
4035
end
4136

42-
-- 📖 Your Story Today (narrative summary)
37+
-- 📖 Your Story Today (aggregated, backend-safe)
4338
table.insert(lines, { { " 📖 Your Story Today", "exgreen" } })
4439
table.insert(lines, {})
4540

46-
local first_session = today_sessions[1]
47-
local last_session = today_sessions[#today_sessions]
48-
local start_hour = tonumber(first_session.start:sub(12, 13))
49-
local end_hour = tonumber(last_session["end"]:sub(12, 13))
50-
local focus_score = s.focus_score or 0
51-
5241
local function get_period(hour)
5342
if hour >= 5 and hour < 12 then
5443
return "morning", "🌅"
@@ -61,125 +50,57 @@ function M.render()
6150
end
6251
end
6352

64-
local start_period, start_icon = get_period(start_hour)
65-
local end_period, end_icon = get_period(end_hour)
66-
67-
-- Generate a human story
68-
local story_parts = {
69-
{ " You started coding in the ", "commentfg" },
70-
{ start_period, "normal" },
71-
{ " " .. start_icon, "normal" },
72-
}
73-
74-
if #today_sessions > 1 then
75-
table.insert(story_parts, { " and had ", "commentfg" })
76-
table.insert(story_parts, { tostring(#today_sessions), "exgreen" })
77-
table.insert(story_parts, { " coding sessions", "commentfg" })
78-
else
79-
table.insert(story_parts, { " for one focused session", "commentfg" })
80-
end
53+
local story = { { " You spent ", "commentfg" }, { fmt.fmt_time(total_time), "exgreen" } }
8154

82-
if start_period ~= end_period then
83-
table.insert(story_parts, { ", continuing into the ", "commentfg" })
84-
table.insert(story_parts, { end_period, "normal" })
85-
table.insert(story_parts, { " " .. end_icon, "normal" })
55+
if peak_hour ~= nil and peak_hour >= 0 then
56+
local period, icon = get_period(peak_hour)
57+
table.insert(story, { " coding mostly in the ", "commentfg" })
58+
table.insert(story, { period, "normal" })
59+
table.insert(story, { " " .. icon, "normal" })
8660
end
8761

88-
table.insert(story_parts, { ".", "commentfg" })
89-
90-
table.insert(lines, story_parts)
62+
table.insert(story, { ".", "commentfg" })
63+
table.insert(lines, story)
9164
table.insert(lines, {})
9265

93-
-- Add focus insight on separate line
94-
local focus_insight = { { " ", "commentfg" } }
66+
-- 🎯 Focus Insight
67+
local focus_line = { { " ", "commentfg" } }
9568
if focus_score >= 80 then
96-
table.insert(focus_insight, { "Deep focus mode! 🎯", "exgreen" })
69+
table.insert(focus_line, { "Deep focus mode! 🎯", "exgreen" })
9770
elseif focus_score >= 60 then
98-
table.insert(focus_insight, { "Good concentration.", "exgreen" })
71+
table.insert(focus_line, { "Good concentration.", "exgreen" })
9972
elseif focus_score >= 40 then
100-
table.insert(focus_insight, { "Some interruptions.", "exyellow" })
73+
table.insert(focus_line, { "Some interruptions.", "exyellow" })
10174
else
102-
table.insert(focus_insight, { "Lots of context switching.", "exred" })
75+
table.insert(focus_line, { "Lots of context switching.", "exred" })
10376
end
104-
105-
table.insert(lines, focus_insight)
106-
table.insert(lines, {})
107-
108-
-- ⏰ Session Timeline (compact with breaks)
109-
table.insert(lines, { { " ⏰ Session Timeline", "exgreen" } })
77+
table.insert(lines, focus_line)
11078
table.insert(lines, {})
11179

112-
local longest_duration = 0
113-
local longest_index = 1
114-
for i, session in ipairs(today_sessions) do
115-
local duration = session.duration or 0
116-
if duration > longest_duration then
117-
longest_duration = duration
118-
longest_index = i
119-
end
120-
end
121-
122-
local tbl = { { "Time", "Duration", "Project", "Languages" } }
123-
124-
for i, session in ipairs(today_sessions) do
125-
local is_peak = (i == longest_index and #today_sessions > 1)
126-
127-
-- Get project
128-
local project = session.project or "General"
129-
130-
-- Get ALL languages (not just first)
131-
local langs = ""
132-
local languages_count = helpers.safe_length(session.languages)
133-
if session.languages and languages_count > 0 then
134-
local languages_table = helpers.safe_array_to_table(session.languages)
135-
langs = helpers.format_list(session.languages)
136-
if project == "General" and #languages_table > 0 then
137-
project = languages_table[1]
138-
end
139-
end
80+
-- ⏰ Time by Language (replaces session timeline)
81+
if #languages > 0 then
82+
table.insert(lines, { { " ⏰ Time by Language", "exgreen" } })
83+
table.insert(lines, {})
14084

141-
-- Format time
142-
local time_str = session.start:sub(12, 16)
143-
local duration_str = fmt.fmt_time(session.duration or 0)
144-
if is_peak then
145-
duration_str = duration_str .. ""
85+
local tbl = { { "Language", "Time" } }
86+
for _, lang in ipairs(languages) do
87+
table.insert(tbl, {
88+
lang.name,
89+
fmt.fmt_time(lang.value),
90+
})
14691
end
14792

148-
tbl[#tbl + 1] = {
149-
time_str,
150-
duration_str,
151-
project,
152-
langs ~= "" and langs or "-",
153-
}
154-
155-
-- Show breaks between sessions (from original!)
156-
if i < #today_sessions then
157-
if session.break_after and session.break_after > 300 then
158-
local break_icon = session.break_after < 1800 and "" or "🍽️"
159-
tbl[#tbl + 1] = {
160-
"",
161-
break_icon .. " " .. fmt.fmt_time(session.break_after),
162-
"-",
163-
"",
164-
}
165-
end
93+
for _, l in ipairs(ui.table(tbl, state.width - 8)) do
94+
table.insert(lines, l)
16695
end
96+
table.insert(lines, {})
16797
end
16898

169-
for _, l in ipairs(ui.table(tbl, state.width - 8)) do
170-
table.insert(lines, l)
171-
end
172-
table.insert(lines, {})
173-
17499
-- 📊 Quick Stats
175-
local avg_time = math.floor(total_time / #today_sessions)
176-
177100
table.insert(lines, {
178101
{ " 📊 ", "exgreen" },
179102
{ fmt.fmt_time(total_time), "exgreen" },
180103
{ " total • ", "commentfg" },
181-
{ fmt.fmt_time(avg_time), "normal" },
182-
{ " avg • ", "commentfg" },
183104
{ string.format("Focus %d%%", focus_score), focus_score >= 70 and "exgreen" or "exyellow" },
184105
})
185106
table.insert(lines, {})
@@ -188,7 +109,6 @@ function M.render()
188109
local hourly_activity = s.hourly_activity or {}
189110
local total_hourly = 0
190111

191-
-- Use pairs() like insight.lua does (not indexed 0-23)
192112
for _, time in pairs(hourly_activity) do
193113
total_hourly = total_hourly + (time or 0)
194114
end
@@ -197,16 +117,6 @@ function M.render()
197117
table.insert(lines, { { " ⏰ Your Peak Hours", "exgreen" } })
198118
table.insert(lines, {})
199119

200-
-- Build hourly map from the data structure
201-
local hourly_map = {}
202-
for hour_key, time in pairs(hourly_activity) do
203-
local hour_num = tonumber(hour_key)
204-
if hour_num then
205-
hourly_map[hour_num] = time
206-
end
207-
end
208-
209-
-- 6 blocks (better granularity)
210120
local blocks = {
211121
{ label = "Night 00-04", start_h = 0, end_h = 3, icon = "🌙" },
212122
{ label = "Early 04-08", start_h = 4, end_h = 7, icon = "🌅" },
@@ -216,13 +126,12 @@ function M.render()
216126
{ label = "Night 20-24", start_h = 20, end_h = 23, icon = "🌃" },
217127
}
218128

219-
local max_pct = 0
220-
local peak_block = nil
129+
local peak_block, max_pct = nil, 0
221130

222131
for _, block in ipairs(blocks) do
223132
local block_time = 0
224133
for h = block.start_h, block.end_h do
225-
block_time = block_time + (hourly_map[h] or 0)
134+
block_time = block_time + (hourly_activity[tostring(h)] or 0)
226135
end
227136

228137
if block_time > 0 then
@@ -232,39 +141,47 @@ function M.render()
232141
peak_block = block.label
233142
end
234143

235-
local bar_hl = pct >= 30 and "exgreen" or pct >= 15 and "exblue" or "commentfg"
144+
local hl = pct >= 30 and "exgreen" or pct >= 15 and "exblue" or "commentfg"
236145
local line = {
237146
{ " " .. block.icon .. " ", "normal" },
238147
{ block.label .. " ", "commentfg" },
239148
}
240-
for _, seg in ipairs(ui.progress(pct, 18, bar_hl)) do
149+
for _, seg in ipairs(ui.progress(pct, 18, hl)) do
241150
table.insert(line, seg)
242151
end
243152
table.insert(line, { string.format(" %d%%", pct), "commentfg" })
244153
table.insert(lines, line)
245154
end
246155
end
247156

248-
-- Add insight
249157
if peak_block then
250158
table.insert(lines, {})
251159
table.insert(lines, {
252160
{ " 💡 You're most productive in the ", "commentfg" },
253-
{ peak_block:sub(8), "exgreen" }, -- Remove icon prefix
161+
{ peak_block:sub(8), "exgreen" },
254162
})
255163
end
256164

257165
table.insert(lines, {})
258166
end
259167

260-
-- 🎯 Productivity Insight (from backend)
168+
-- 🎯 Productivity Trend
261169
local productivity_trend = s.productivity_trend or ""
262170
if productivity_trend ~= "" then
171+
local trend_text
172+
if productivity_trend == "increasing" then
173+
trend_text = "📈 Productivity Increasing"
174+
elseif productivity_trend == "decreasing" then
175+
trend_text = "📉 Slowing Down"
176+
else
177+
trend_text = "➡️ Stable Pace"
178+
end
179+
263180
table.insert(lines, { { " 🎯 Trend", "exgreen" } })
264181
table.insert(lines, {})
265182
table.insert(lines, {
266183
{ " ", "commentfg" },
267-
{ productivity_trend, "exgreen" },
184+
{ trend_text, "exgreen" },
268185
})
269186
table.insert(lines, {})
270187
end

0 commit comments

Comments
 (0)