A Neovim plugin enabling you to solve LeetCode problems.
feat(menu): streak counter display
12 files changed, +96 -2
+10-0lua/leetcode-plugins/cn/queries.lua
| @@ -139,3 +139,13 @@ queries.skills = [[ | ||
| 139 | 139 | } |
| 140 | 140 | } |
| 141 | 141 | ]] |
| 142 | + | |
| 143 | +queries.streak = [[ | |
| 144 | + query getStreakCounter { | |
| 145 | + streakCounter: problemsetStreakCounter { | |
| 146 | + streakCount | |
| 147 | + daysSkipped | |
| 148 | + todayCompleted | |
| 149 | + } | |
| 150 | + } | |
| 151 | + ]] |
+1-0lua/leetcode-plugins/cn/urls.lua
| @@ -12,3 +12,4 @@ urls.interpret = "/problems/%s/interpret_solution/" | ||
| 12 | 12 | urls.submit = "/problems/%s/submit/" |
| 13 | 13 | urls.run = "/problems/%s/interpret_solution/" |
| 14 | 14 | urls.check = "/submissions/detail/%s/check/" |
| 15 | +urls.streak_counter = "/graphql/noj-go/" |
+3-0lua/leetcode-ui/group/page/cache.lua
| @@ -3,6 +3,7 @@ local Title = require("leetcode-ui.lines.title") | ||
| 3 | 3 | local Footer = require("leetcode-ui.lines.footer") |
| 4 | 4 | local Buttons = require("leetcode-ui.group.buttons.menu") |
| 5 | 5 | local Page = require("leetcode-ui.group.page") |
| 6 | +local Stats = require("leetcode-ui.lines.stats") | |
| 6 | 7 | |
| 7 | 8 | local Button = require("leetcode-ui.lines.button.menu") |
| 8 | 9 | local BackButton = require("leetcode-ui.lines.button.menu.back") |
| @@ -30,4 +31,6 @@ page:insert(Buttons({ | ||
| 30 | 31 | |
| 31 | 32 | page:insert(Footer()) |
| 32 | 33 | |
| 34 | +page:insert(Stats) | |
| 35 | + | |
| 33 | 36 | return page |
+3-0lua/leetcode-ui/group/page/cookie.lua
| @@ -3,6 +3,7 @@ local Title = require("leetcode-ui.lines.title") | ||
| 3 | 3 | local Footer = require("leetcode-ui.lines.footer") |
| 4 | 4 | local Buttons = require("leetcode-ui.group.buttons.menu") |
| 5 | 5 | local Page = require("leetcode-ui.group.page") |
| 6 | +local Stats = require("leetcode-ui.lines.stats") | |
| 6 | 7 | |
| 7 | 8 | local Button = require("leetcode-ui.lines.button.menu") |
| 8 | 9 | local BackButton = require("leetcode-ui.lines.button.menu.back") |
| @@ -37,4 +38,6 @@ page:insert(Buttons({ | ||
| 37 | 38 | |
| 38 | 39 | page:insert(Footer()) |
| 39 | 40 | |
| 41 | +page:insert(Stats) | |
| 42 | + | |
| 40 | 43 | return page |
+3-0lua/leetcode-ui/group/page/problems.lua
| @@ -8,6 +8,7 @@ local Button = require("leetcode-ui.lines.button.menu") | ||
| 8 | 8 | local BackButton = require("leetcode-ui.lines.button.menu.back") |
| 9 | 9 | local Buttons = require("leetcode-ui.group.buttons.menu") |
| 10 | 10 | local Page = require("leetcode-ui.group.page") |
| 11 | +local Stats = require("leetcode-ui.lines.stats") | |
| 11 | 12 | |
| 12 | 13 | local page = Page() |
| 13 | 14 | |
| @@ -44,4 +45,6 @@ page:insert(Buttons({ | ||
| 44 | 45 | |
| 45 | 46 | page:insert(Footer()) |
| 46 | 47 | |
| 48 | +page:insert(Stats) | |
| 49 | + | |
| 47 | 50 | return page |
+3-0lua/leetcode-ui/group/page/stats.lua
| @@ -7,6 +7,7 @@ local Buttons = require("leetcode-ui.group.buttons.menu") | ||
| 7 | 7 | local Button = require("leetcode-ui.lines.button.menu") |
| 8 | 8 | local BackButton = require("leetcode-ui.lines.button.menu.back") |
| 9 | 9 | local Title = require("leetcode-ui.lines.title") |
| 10 | +local Stats = require("leetcode-ui.lines.stats") | |
| 10 | 11 | |
| 11 | 12 | local cmd = require("leetcode.command") |
| 12 | 13 | local config = require("leetcode.config") |
| @@ -63,4 +64,6 @@ page:insert(buttons) | ||
| 63 | 64 | |
| 64 | 65 | page:insert(Footer()) |
| 65 | 66 | |
| 67 | +page:insert(Stats) | |
| 68 | + | |
| 66 | 69 | return page |
+41-0lua/leetcode-ui/lines/stats.lua
| @@ -0,0 +1,41 @@ | ||
| 1 | +local Lines = require("leetcode-ui.lines") | |
| 2 | +local t = require("leetcode.translator") | |
| 3 | +local log = require("leetcode.logger") | |
| 4 | +local stats_api = require("leetcode.api.statistics") | |
| 5 | + | |
| 6 | +---@class lc.ui.menu.Stats : lc.ui.Lines | |
| 7 | +---@field streak? integer | |
| 8 | +---@field today_completed? boolean | |
| 9 | +local Stats = Lines:extend("LeetMenuTitle") | |
| 10 | + | |
| 11 | +function Stats:contents() | |
| 12 | + self:clear() | |
| 13 | + | |
| 14 | + local hl = self.today_completed and "leetcode_hard" or "leetcode_alt" | |
| 15 | + self:append(" ", hl) | |
| 16 | + self:append(self.streak and tostring(self.streak) or "-") | |
| 17 | + | |
| 18 | + return Stats.super.contents(self) | |
| 19 | +end | |
| 20 | + | |
| 21 | +function Stats:update() | |
| 22 | + stats_api.streak(function(res, err) | |
| 23 | + if err then return log.err(err) end | |
| 24 | + | |
| 25 | + self.streak = res.streakCount | |
| 26 | + self.today_completed = res.todayCompleted | |
| 27 | + | |
| 28 | + if _Lc_Menu then _Lc_Menu:draw() end | |
| 29 | + end) | |
| 30 | +end | |
| 31 | + | |
| 32 | +function Stats:init() -- | |
| 33 | + Stats.super.init(self, {}, {}) | |
| 34 | + | |
| 35 | + self:update() | |
| 36 | +end | |
| 37 | + | |
| 38 | +---@type fun(): lc.ui.menu.Stats | |
| 39 | +local LeetMenuStats = Stats | |
| 40 | + | |
| 41 | +return LeetMenuStats() |
+1-1lua/leetcode/api/interpreter.lua
| @@ -54,7 +54,7 @@ function interpreter.listener(id, callback) | ||
| 54 | 54 | local function listen() |
| 55 | 55 | interpreter.check(id, function(item, err) |
| 56 | 56 | if err then |
| 57 | - require("leetcode.runner"):stop() | |
| 57 | + callback(false) | |
| 58 | 58 | return noti:stop(err.msg, false) |
| 59 | 59 | end |
| 60 | 60 |
+10-0lua/leetcode/api/queries.lua
| @@ -155,4 +155,14 @@ queries.languages = [[ | ||
| 155 | 155 | } |
| 156 | 156 | ]] |
| 157 | 157 | |
| 158 | +queries.streak = [[ | |
| 159 | + query getStreakCounter { | |
| 160 | + streakCounter { | |
| 161 | + streakCount | |
| 162 | + daysSkipped | |
| 163 | + todayCompleted: currentDayCompleted | |
| 164 | + } | |
| 165 | + } | |
| 166 | + ]] | |
| 167 | + | |
| 158 | 168 | return queries |
+17-1lua/leetcode/api/statistics.lua
| @@ -4,7 +4,7 @@ local log = require("leetcode.logger") | ||
| 4 | 4 | local urls = require("leetcode.api.urls") |
| 5 | 5 | local queries = require("leetcode.api.queries") |
| 6 | 6 | |
| 7 | ----@lc.api.statistics | |
| 7 | +---@class lc.api.statistics | |
| 8 | 8 | local statistics = {} |
| 9 | 9 | |
| 10 | 10 | function statistics.calendar(cb) |
| @@ -95,4 +95,20 @@ function statistics.languages(cb) | ||
| 95 | 95 | }) |
| 96 | 96 | end |
| 97 | 97 | |
| 98 | +function statistics.streak(cb) | |
| 99 | + local variables = vim.empty_dict() | |
| 100 | + | |
| 101 | + local query = queries.streak | |
| 102 | + | |
| 103 | + utils.query(query, variables, { | |
| 104 | + endpoint = urls.streak_counter, | |
| 105 | + callback = function(res, err) | |
| 106 | + if err then return cb(nil, err) end | |
| 107 | + local data = res.data | |
| 108 | + local streak = data["streakCounter"] | |
| 109 | + cb(streak) | |
| 110 | + end, | |
| 111 | + }) | |
| 112 | +end | |
| 113 | + | |
| 98 | 114 | return statistics |
+1-0lua/leetcode/api/urls.lua
| @@ -14,5 +14,6 @@ urls.submit = "/problems/%s/submit/" | ||
| 14 | 14 | urls.run = "/problems/%s/interpret_solution/" |
| 15 | 15 | urls.check = "/submissions/detail/%s/check/" |
| 16 | 16 | urls.latest_submission = "/submissions/latest/?qid=%s&lang=%s" |
| 17 | +urls.streak_counter = "/graphql/" | |
| 17 | 18 | |
| 18 | 19 | return urls |