Skip to content
Open
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
57 changes: 57 additions & 0 deletions lua/leetcode-plugins/cn/queries.lua
Original file line number Diff line number Diff line change
Expand Up @@ -160,3 +160,60 @@ queries.session_progress = [[
}
}
]]

queries.company_list = [[
query InterviewHotCompanyCards($in: InterviewHotCompanyCardsInput!) {
interviewHotCompanyCards(in: $in) {
hasMore
total
cards {
companyInfo {
companyTag {
name
slug
imgUrl
translatedName
questionCount
}
}
}
}
}
]]

queries.company_questions = [[
query favoriteQuestionList($favoriteSlug: String!, $filter: FavoriteQuestionFilterInput, $searchKeyword: String, $filtersV2: QuestionFilterInput, $sortBy: QuestionSortByInput, $limit: Int, $skip: Int, $version: String = "v2") {
favoriteQuestionList(
favoriteSlug: $favoriteSlug
filter: $filter
filtersV2: $filtersV2
searchKeyword: $searchKeyword
sortBy: $sortBy
limit: $limit
skip: $skip
version: $version
) {
questions {
difficulty
id
paidOnly
questionFrontendId
status
title
titleSlug
translatedTitle
isInMyFavorites
frequency
acRate
contestPoint
topicTags {
name
nameTranslated
slug
}
}
totalLength
hasMore
}
}
]]
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 @@ -33,12 +33,19 @@ local daily = Button("Daily", {
on_press = cmd.qot,
})

local company = Button("Company", {
icon = "",
sc = "c",
on_press = cmd.company,
})

local back = BackButton("menu")

page:insert(Buttons({
list,
random,
daily,
company,
back,
}))

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

---@param cb function
function Problems.company_list(cb)
local query = queries.company_list
local variables = { ["in"] = { offset = 0, limit = 100 } }

utils.query(query, variables, {
endpoint = "/graphql/noj-go",
callback = function(res, err)
if err then
return cb(nil, err)
end

local data = res.data.interviewHotCompanyCards
local companies = {}
for _, card in ipairs(data.cards) do
local tag = card.companyInfo.companyTag
table.insert(companies, {
name = tag.name ~= "" and tag.name or tag.translatedName,
slug = tag.slug,
question_count = tag.questionCount,
})
end
cb(companies)
end,
})
end

---@param company_slug string
---@param cb function
function Problems.company_questions(company_slug, cb)
local query = queries.company_questions
local favorite_slug = company_slug .. "-thirty-days"
local variables = {
favoriteSlug = favorite_slug,
skip = 0,
limit = 500,
filtersV2 = {
filterCombineType = "ALL",
statusFilter = { questionStatuses = {}, operator = "IS" },
difficultyFilter = { difficulties = {}, operator = "IS" },
languageFilter = { languageSlugs = {}, operator = "IS" },
topicFilter = { topicSlugs = {}, operator = "IS" },
acceptanceFilter = vim.empty_dict(),
frequencyFilter = vim.empty_dict(),
frontendIdFilter = vim.empty_dict(),
lastSubmittedFilter = vim.empty_dict(),
publishedFilter = vim.empty_dict(),
companyFilter = { companySlugs = {}, operator = "IS" },
positionFilter = { positionSlugs = {}, operator = "IS" },
positionLevelFilter = { positionLevelSlugs = {}, operator = "IS" },
contestPointFilter = { contestPoints = {}, operator = "IS" },
premiumFilter = { premiumStatus = {} },
},
searchKeyword = "",
sortBy = { sortField = "CUSTOM", sortOrder = "ASCENDING" },
}

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

local data = res.data.favoriteQuestionList
cb(data.questions)
end,
})
end

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

Expand Down
7 changes: 7 additions & 0 deletions lua/leetcode/command/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,12 @@ function cmd.random_question(opts)
Question(item):mount()
end

function cmd.company()
require("leetcode.utils").auth_guard()
local picker = require("leetcode.picker")
picker.company()
end

function cmd.start_with_cmd()
local leetcode = require("leetcode")
if leetcode.start(false) then
Expand Down Expand Up @@ -634,6 +640,7 @@ cmd.commands = {
cmd.problems,
_args = arguments.list,
},
company = { cmd.company },
random = {
cmd.random_question,
_args = arguments.random,
Expand Down
44 changes: 44 additions & 0 deletions lua/leetcode/picker/company/fzf.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
local fzf = require("fzf-lua")
local t = require("leetcode.translator")
local company_picker = require("leetcode.picker.company")
local Picker = require("leetcode.picker")

local deli = " "

return function(companies)
local items = {}
for _, company in ipairs(companies) do
local entry = company_picker.entry(company)
local normalized = Picker.normalize({ { entry = entry, value = company } })[1]
.. deli
.. Picker.apply_hl(company.slug, "leetcode_alt")
table.insert(items, normalized)
end

fzf.fzf_exec(items, {
prompt = t("Select a Company") .. "> ",
winopts = {
height = company_picker.height,
width = company_picker.width,
},
fzf_opts = {
["--delimiter"] = deli,
["--nth"] = "3..-2",
},
actions = {
["default"] = function(selected)
local slug = Picker.hidden_field(selected[1], deli)
local company = nil
for _, c in ipairs(companies) do
if c.slug == slug then
company = c
break
end
end
if company then
company_picker.select(company)
end
end,
},
})
end
68 changes: 68 additions & 0 deletions lua/leetcode/picker/company/init.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
local config = require("leetcode.config")
local Picker = require("leetcode.picker")

---@class leet.Picker.Company: leet.Picker
local P = {}

P.width = 100
P.height = 0.6

---@param company { name: string, slug: string, question_count: number }
local function display_entry(company)
local name = { company.name, "leetcode_normal" }
local count = { ("(%d)"):format(company.question_count), "leetcode_ref" }
return { name, count }
end

---@param company { name: string, slug: string, question_count: number }
local function ordinal(company)
return ("%s %s"):format(company.name, company.slug)
end

---@param company { name: string, slug: string, question_count: number }
function P.entry(company)
return display_entry(company)
end

function P.ordinal(company)
return ordinal(company)
end

function P.select(selection, close)
if close then
close()
end

local problems_api = require("leetcode.api.problems")
local problemlist = require("leetcode.cache.problemlist")
local log = require("leetcode.logger")

problems_api.company_questions(selection.slug, function(questions, err)
if err then
return log.err(err)
end

if not questions or vim.tbl_isempty(questions) then
return log.warn("No questions found for this company")
end

local slug_order = {}
for i, q in ipairs(questions) do
slug_order[q.titleSlug] = i
end

local cached = problemlist.get()
local company_questions = vim.tbl_filter(function(q)
return slug_order[q.title_slug] ~= nil
end, cached)

table.sort(company_questions, function(a, b)
return slug_order[a.title_slug] < slug_order[b.title_slug]
end)

local question_picker = require("leetcode.picker")
question_picker.question(company_questions, {})
end)
end

return P
42 changes: 42 additions & 0 deletions lua/leetcode/picker/company/mini.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
local log = require("leetcode.logger")
local t = require("leetcode.translator")
local company_picker = require("leetcode.picker.company")

local picker = require("mini.pick")

return function(companies)
local items = {}
for _, company in ipairs(companies) do
local entry = company_picker.entry(company)
local text = company_picker.ordinal(company)
table.insert(items, {
entry = entry,
text = text,
value = company,
})
end

local ns_id = vim.api.nvim_create_namespace("MiniPick LeetCode Companies Picker")

picker.start({
source = {
items = items,
name = t("Select a Company"),
choose = function(item)
vim.schedule(function()
company_picker.select(item.value)
end)
return true
end,
show = function(buf_id, source_items)
require("leetcode.picker.mini_pick_utils").show_items(buf_id, ns_id, source_items)
end,
},
window = {
config = {
width = company_picker.width,
height = math.floor(vim.o.lines * company_picker.height),
},
},
})
end
63 changes: 63 additions & 0 deletions lua/leetcode/picker/company/snacks.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
local log = require("leetcode.logger")
local t = require("leetcode.translator")
local company_picker = require("leetcode.picker.company")

local picker = require("snacks.picker")

return function(companies)
local items = {}
local completed = false

for _, company in ipairs(companies) do
local entry = company_picker.entry(company)
local text = company_picker.ordinal(company)
table.insert(items, {
text = text,
value = company,
})
end

picker.pick({
items = items,
format = function(item)
local ret = {}
vim.tbl_map(function(col)
if type(col) == "table" then
ret[#ret + 1] = col
else
ret[#ret + 1] = { col }
end
ret[#ret + 1] = { " " }
end, item.entry)
return ret
end,
title = t("Select a Company"),
layout = {
preset = "select",
preview = false,
layout = {
height = company_picker.height,
width = company_picker.width,
},
},
actions = {
confirm = function(p, item)
if completed then
return
end
completed = true
p:close()
vim.schedule(function()
company_picker.select(item.value)
end)
end,
},
on_close = function()
if completed then
return
end
completed = true
log.warn("No selection")
end,
})
end
Loading