From 0ab90f032b321170fa719153c4d39a2f25b6262c Mon Sep 17 00:00:00 2001 From: Will Dean <57733339+wd60622@users.noreply.github.com> Date: Thu, 6 Feb 2025 10:46:31 +0100 Subject: [PATCH] Feat: repo specific notifications (#849) * add configuration option * implement for the telescope picker * Use info over error Co-authored-by: Tristan Knight * use short circuit Co-authored-by: Tristan Knight * use current_repo_only over current_repo * use cleaner var name --------- Co-authored-by: Tristan Knight --- README.md | 3 ++ lua/octo/config.lua | 16 ++++++++++ lua/octo/pickers/telescope/entry_maker.lua | 21 ++++++++----- lua/octo/pickers/telescope/provider.lua | 35 ++++++++++++++++------ 4 files changed, 59 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index aca3dad5..4ac9dfcd 100644 --- a/README.md +++ b/README.md @@ -149,6 +149,9 @@ require"octo".setup({ }, always_select_remote_on_create = false -- always give prompt to select base remote repo when creating PRs }, + notifications = { + current_repo_only = false, -- show notifications for current repo only + }, file_panel = { size = 10, -- changed files panel rows use_icons = true -- use web-devicons in file panel (if false, nvim-web-devicons does not need to be installed) diff --git a/lua/octo/config.lua b/lua/octo/config.lua index 3bc3285d..8459fab2 100644 --- a/lua/octo/config.lua +++ b/lua/octo/config.lua @@ -43,6 +43,9 @@ local M = {} ---@class OctoConfigDiscussions ---@field order_by OctoConfigOrderBy +---@class OctoConfigNotifications +---@field current_repo_only boolean + ---@class OctoConfigPR ---@field order_by OctoConfigOrderBy ---@field always_select_remote_on_create boolean @@ -91,6 +94,7 @@ local M = {} ---@field mappings { [OctoMappingsWindow]: OctoMappingsList} ---@field mappings_disable_default boolean ---@field discussions OctoConfigDiscussions +---@field notifications OctoConfigNotifications --- Returns the default octo config values ---@return OctoConfig @@ -150,6 +154,9 @@ function M.get_default_values() direction = "DESC", }, }, + notifications = { + current_repo_only = false, + }, reviews = { auto_show_threads = true, focus = "right", @@ -429,6 +436,14 @@ function M.validate_config() validate_type(config.pull_requests.always_select_remote_on_create, "always_select_remote_on_create", "boolean") end + local function validate_notifications() + if not validate_type(config.notifications, "notifications", "table") then + err("notifications", "Expected notifications to be a table") + return + end + validate_type(config.notifications.current_repo_only, "notifications.current_repo_only", "boolean") + end + local function validate_mappings() -- TODO(jarviliam): Validate each keymap if not validate_type(config.mappings, "mappings", "table") then @@ -479,6 +494,7 @@ function M.validate_config() validate_issues() validate_reviews() validate_pull_requests() + validate_notifications() if validate_type(config.file_panel, "file_panel", "table") then validate_type(config.file_panel.size, "file_panel.size", "number") validate_type(config.file_panel.use_icons, "file_panel.use_icons", "boolean") diff --git a/lua/octo/pickers/telescope/entry_maker.lua b/lua/octo/pickers/telescope/entry_maker.lua index ae84d849..9a5e6986 100644 --- a/lua/octo/pickers/telescope/entry_maker.lua +++ b/lua/octo/pickers/telescope/entry_maker.lua @@ -656,7 +656,8 @@ function M.gen_from_octo_actions(width) end end -function M.gen_from_notification() +function M.gen_from_notification(opts) + opts = opts or { show_repo_info = false } local make_display = function(entry) if not entry then return nil @@ -670,15 +671,21 @@ function M.gen_from_notification() { string.sub(entry.obj.repository.full_name, 1, 50), "TelescopeResultsNumber" }, { string.sub(entry.obj.subject.title, 1, 100) }, } + local items = { + { width = 2 }, + { width = 6 }, + { width = math.min(#entry.obj.repository.full_name, 50) }, + { width = math.min(#entry.obj.subject.title, 100) }, + } + + if not opts.show_repo_info then + table.remove(columns, 3) + table.remove(items, 3) + end local displayer = entry_display.create { separator = " ", - items = { - { width = 2 }, - { width = 6 }, - { width = math.min(#entry.obj.repository.full_name, 50) }, - { width = math.min(#entry.obj.subject.title, 100) }, - }, + items = items, } return displayer(columns) diff --git a/lua/octo/pickers/telescope/provider.lua b/lua/octo/pickers/telescope/provider.lua index 8841cef0..22e7cca1 100644 --- a/lua/octo/pickers/telescope/provider.lua +++ b/lua/octo/pickers/telescope/provider.lua @@ -1204,28 +1204,45 @@ local function mark_notification_read() end end -function M.notifications() +function M.notifications(opts) + opts = opts or {} local cfg = octo_config.values - local opts = { - preview_title = "", - prompt_title = "Github Notifications", - results_title = "", - } + + if cfg.notifications.current_repo_only then + opts.repo = utils.get_remote_name() + end + + local endpoint = "/notifications" + if opts.repo then + local owner, name = utils.split_repo(opts.repo) + endpoint = string.format("/repos/%s/%s/notifications", owner, name) + end + opts.prompt_title = opts.repo and string.format("%s Notifications", opts.repo) or "Github Notifications" + + opts.preview_title = "" + opts.results_title = "" gh.run { - args = { "api", "--paginate", "/notifications" }, + args = { "api", "--paginate", endpoint }, headers = { "Accept: application/vnd.github.v3.diff" }, cb = function(output, stderr) if stderr and not utils.is_blank(stderr) then utils.error(stderr) elseif output then local resp = vim.json.decode(output) + + if #resp == 0 then + utils.info "There are no notifications" + return + end + pickers .new(opts, { - finder = finders.new_table { results = resp, - entry_maker = entry_maker.gen_from_notification(), + entry_maker = entry_maker.gen_from_notification { + show_repo_info = not opts.repo, + }, }, sorter = conf.generic_sorter(opts), previewer = previewers.issue.new(opts),