irongit

A Neovim plugin enabling you to solve LeetCode problems.

117 lines2.9 KBLua
1local Lines = require("leetcode-ui.lines")
2local Line = require("leetcode-ui.line")
3local utils = require("leetcode-ui.utils")
4local Spinner = require("leetcode.logger.spinner")
5local statistics = require("leetcode.api.statistics")
6local t = require("leetcode.translator")
7
8local log = require("leetcode.logger")
9
10---@class lc.ui.Solved : lc.ui.Lines
11local Solved = Lines:extend("LeetSolved")
12
13---@return NuiLine
14function Solved:progress_bar(width, solved, total_count, difficulty)
15 local line = Line()
16 local solved_len = math.ceil(width * (solved / total_count))
17
18 for _ = 1, solved_len do
19 line:append("󰝤", utils.diff_to_hl(difficulty))
20 end
21
22 for _ = solved_len, width do
23 line:append("󰝤", utils.diff_to_hl(difficulty) .. "_alt")
24 end
25
26 return line
27end
28
29---@param res lc.Stats.Res
30function Solved:handle_res(res)
31 self:clear()
32
33 local subs = {}
34
35 local max_count_len = 0
36 for _, stat in ipairs(res.submit_stats.acSubmissionNum) do
37 local total_count = vim.tbl_filter(function(c)
38 return c.difficulty == stat.difficulty
39 end, res.questions_count)[1].count
40
41 local solved_line = Line()
42 solved_line:append(tostring(stat.count))
43 solved_line:append(("/%d"):format(total_count), "leetcode_alt")
44 max_count_len = math.max(solved_line:content():len(), max_count_len)
45
46 subs[stat.difficulty] = {
47 total_count = total_count,
48 solved = stat.count,
49 line = solved_line,
50 }
51 end
52
53 local order = { "All", "Easy", "Medium", "Hard" }
54 local pad_len = 0
55 for _, diff in ipairs(order) do
56 pad_len = math.max(pad_len, vim.api.nvim_strwidth(t(diff)))
57 end
58
59 for _, diff in ipairs(order) do
60 local stat = subs[diff]
61 local diff_str = t(diff)
62
63 self:append(diff_str, utils.diff_to_hl(diff))
64
65 local pad1 = (" "):rep(pad_len + 2 - vim.api.nvim_strwidth(diff_str))
66 self:append(pad1)
67
68 self:append(stat.line)
69
70 local pad2 = (" "):rep(max_count_len + 2 - stat.line:content():len())
71 self:append(pad2)
72
73 self:append(self:progress_bar(50, stat.solved, stat.total_count, diff))
74
75 self:endl()
76 end
77
78 _Lc_state.menu:draw()
79end
80
81function Solved:update()
82 local spinner = Spinner:start("updating solved problems")
83 statistics.solved(function(res, err)
84 if err then
85 spinner:error(err.msg)
86 else
87 spinner:success("solved problems updated")
88 self:handle_res(res)
89 end
90 end)
91end
92
93function Solved:fetch()
94 statistics.solved(function(res, err)
95 if err then
96 return log.err(err)
97 end
98 self:handle_res(res)
99 end)
100end
101
102function Solved:init()
103 local opts = {
104 position = "center",
105 hl = "Keyword",
106 }
107
108 Solved.super.init(self, {}, opts)
109
110 self:append(t("Loading..."))
111 self:fetch()
112end
113
114---@type fun(): lc.ui.Solved
115local LeetSolved = Solved
116
117return LeetSolved