Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: favorite #113

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions lua/leetcode-ui/group/page/problems.lua
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ local list = Button("List", {
on_press = cmd.problems,
})

local favorite = Button("Favorite", {
icon = "★",
sc = "f",
on_press = cmd.favorite_list,
})

local random = Button("Random", {
icon = "",
sc = "r",
Expand All @@ -37,6 +43,7 @@ local back = BackButton("menu")

page:insert(Buttons({
list,
favorite,
random,
daily,
back,
Expand Down
1 change: 1 addition & 0 deletions lua/leetcode-ui/types.lua
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
---| "cache"
---| "signin"
---| "loading"
---| "favorite"

--------------------------------------------
--- Leet Component
Expand Down
29 changes: 29 additions & 0 deletions lua/leetcode/api/problems.lua
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,35 @@ function Problems.question_of_today(cb)
})
end

function Problems.favorite_list(cb)
local query = queries.favorite_list

utils.query(query, {}, {
callback = function(res, err)
if err then
return cb(nil, err)
end

local data = res.data
cb(data.myCollectedFavoriteList.favorites)
end,
})
end

function Problems.favorite_question_list(favorite_slug, cb)
local query = queries.favorite_question_list

utils.query(query, { favoriteSlug = favorite_slug }, {
callback = function(res, err)
if err then
return cb(nil, err)
end
local normalized = utils.normalize_favorites(res.data.favoriteQuestionList.questions)
cb(normalized)
end,
})
end

function Problems.translated_titles(cb)
local query = queries.translations

Expand Down
52 changes: 52 additions & 0 deletions lua/leetcode/api/queries.lua
Original file line number Diff line number Diff line change
Expand Up @@ -179,4 +179,56 @@ queries.session_progress = [[
}
]]

queries.favorite_list = [[
query myFavoriteList {
myCreatedFavoriteList {
favorites {
coverUrl
coverEmoji
coverBackgroundColor
hasCurrentQuestion
isPublicFavorite
lastQuestionAddedAt
name
slug
}
hasMore
totalLength
}
myCollectedFavoriteList {
hasMore
totalLength
favorites {
coverUrl
coverEmoji
coverBackgroundColor
hasCurrentQuestion
isPublicFavorite
name
slug
lastQuestionAddedAt
}
}
}
]]

queries.favorite_question_list = [[
query favoriteQuestionList($favoriteSlug: String!) {
favoriteQuestionList(favoriteSlug: $favoriteSlug) {
questions {
id
questionFrontendId
paidOnly
title
titleSlug
difficulty
topicTags {
name
slug
}
}
}
}
]]

return queries
9 changes: 9 additions & 0 deletions lua/leetcode/api/types.lua
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,15 @@
---@field lvl integer

---@alias lc.err lc.Api.err|nil
--
--------------------------------------------
--- Favorite
--------------------------------------------
---@class lc.Favorite
---@field name string
---@field slug string
---@field isPublicFavorite boolean
---@field hasCurrentQuestion boolean

--------------------------------------------
--- Sessions
Expand Down
23 changes: 23 additions & 0 deletions lua/leetcode/api/utils.lua
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,29 @@ function utils.lvl_to_name(lvl)
return ({ "Easy", "Medium", "Hard" })[lvl]
end

function utils.normalize_favorites(questions)
local diff = {
EASY = 1,
MEDIUM = 2,
HARD = 3,
}
return vim.tbl_map(function(q)
return {
id = q.id,
frontend_id = tonumber(q.questionFrontendId),
title = q.title,
title_slug = q.titleSlug,
title_cn = "",
paid_only = q.paidOnly,
link = ("https://leetcode.%s/problems/%s/"):format(config.domain, q.titleSlug),
ac_rate = 0,
difficulty = utils.lvl_to_name(diff[q.difficulty]),
starred = true,
topic_tags = {},
}
end, questions)
end

---@return lc.cache.Question[]
function utils.normalize_problems(problems)
problems = vim.tbl_filter(function(p)
Expand Down
24 changes: 24 additions & 0 deletions lua/leetcode/command/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,30 @@ function cmd.qot()
end)
end

function cmd.favorite_list()
require("leetcode.utils").auth_guard()

local problems = require("leetcode.api.problems")

problems.favorite_list(function(favorites, fav_err)
if fav_err then
return log.err(fav_err)
end
require("leetcode.pickers.favorite").pick(favorites, function(selection)
if not selection then
return
end
local slug = selection.slug
problems.favorite_question_list(slug, function(data, fav_q_err)
if fav_q_err then
return log.err(fav_q_err)
end
require("leetcode.pickers.question").pick(data)
end)
end)
end)
end

function cmd.random_question(opts)
require("leetcode.utils").auth_guard()

Expand Down
79 changes: 79 additions & 0 deletions lua/leetcode/pickers/favorite.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
local t = require("leetcode.translator")

local pickers = require("telescope.pickers")
local finders = require("telescope.finders")
local conf = require("telescope.config").values

local entry_display = require("telescope.pickers.entry_display")
local actions = require("telescope.actions")
local action_state = require("telescope.actions.state")

---@param f lc.Favorite
---
---@return string
local function favorite_formatter(f)
return string.format("%s - %s", f.slug, f.name)
end

---@param favorite lc.Favorite
local function display_favorite(favorite)
return {
favorite.name,
favorite.slug,
}
end

local displayer = entry_display.create({
separator = " ",
items = {
{ remaining = true },
},
})

-- @param entry lc.Favorite
local function make_display(entry)
---@type lc.Favorite
local f = entry.value

return displayer({
display_favorite(f),
})
end

-- @param entry lc.Favorite
local function entry_maker(entry)
return {
value = entry,
display = make_display,
ordinal = favorite_formatter(entry),
}
end

local opts = require("telescope.themes").get_dropdown()

return {
pick = function(favorites, cb)
pickers
.new(opts, {
prompt_title = t("Select a Favorite List"),
finder = finders.new_table({
results = favorites,
entry_maker = entry_maker,
}),
sorter = conf.generic_sorter(theme),
attach_mappings = function(prompt_bufnr)
actions.select_default:replace(function()
actions.close(prompt_bufnr)
local selection = action_state.get_selected_entry()

if not selection then
return
end
cb(selection.value)
end)
return true
end,
})
:find()
end,
}