diff --git a/src/components/FileExplorer.tsx b/src/components/FileExplorer.tsx index a63172f..923dff2 100644 --- a/src/components/FileExplorer.tsx +++ b/src/components/FileExplorer.tsx @@ -46,7 +46,7 @@ const RawFileExplorer: React.FC = function RawFileExplor searched, } = props const { - value: { accessToken, compressSingletonFolder, searchMode }, + value: { accessToken, compressSingletonFolder, searchMode, commentToggle }, } = useConfigs() const onSearch = React.useCallback( @@ -105,18 +105,26 @@ const RawFileExplorer: React.FC = function RawFileExplor ) : undefined + const renderFileCommentAmounts = (node: TreeNode): React.ReactNode => + node.comments !== undefined && + node.comments > 0 && ( + + {node.comments} + + ) const renders: ((node: TreeNode) => React.ReactNode)[] = [] + if (commentToggle) renders.push(renderFileCommentAmounts) if (searchMode === 'fuzzy') renders.push(renderFindInFolderButton) if (searched) renders.push(renderGoToButton) return renders.length ? node => renders.map((render, i) => {render(node)}) : undefined - }, [goTo, onSearch, searched, searchMode]) + }, [goTo, onSearch, searched, searchMode, commentToggle]) const renderLabelText = React.useCallback( - node => searchModes[searchMode].renderNodeLabelText(node, searchKey), + (node: TreeNode) => searchModes[searchMode].renderNodeLabelText(node, searchKey), [searchKey, searchMode], ) diff --git a/src/components/Icon.tsx b/src/components/Icon.tsx index 1316963..d3f8eb4 100644 --- a/src/components/Icon.tsx +++ b/src/components/Icon.tsx @@ -2,6 +2,7 @@ import { ChevronDownIcon as ChevronDown, ChevronRightIcon as ChevronRight, ClockIcon as Clock, + CommentIcon as Comment, FileCodeIcon as FileCode, FileIcon as File, FileMediaIcon as FileMedia, @@ -25,6 +26,7 @@ import { cx } from 'utils/cx' const iconToComponentMap = { Search, Clock, + Comment, Hourglass, Submodule, Grabber, @@ -53,6 +55,7 @@ const typeToIconComponentMap: { submodule: 'Submodule', grabber: 'Grabber', octoface: 'Octoface', + comment: 'Comment', x: 'X', pin: 'Pin', tab: 'Tab', diff --git a/src/components/settings/SidebarSettings.tsx b/src/components/settings/SidebarSettings.tsx index 1370a66..69b7955 100644 --- a/src/components/settings/SidebarSettings.tsx +++ b/src/components/settings/SidebarSettings.tsx @@ -107,6 +107,14 @@ export function SidebarSettings(props: React.PropsWithChildren) { }, }} /> + ) } diff --git a/src/global.d.ts b/src/global.d.ts index 2bd80d8..80a88bb 100644 --- a/src/global.d.ts +++ b/src/global.d.ts @@ -16,6 +16,7 @@ type TreeNode = { url?: string sha?: string accessDenied?: boolean + comments?: number } type IO = { diff --git a/src/platforms/GitHub/API.ts b/src/platforms/GitHub/API.ts index 083912e..0491ef9 100644 --- a/src/platforms/GitHub/API.ts +++ b/src/platforms/GitHub/API.ts @@ -106,6 +106,16 @@ export async function getPullTreeData( return await request(url, { accessToken }) } +export async function getPullComments( + userName: string, + repoName: string, + pullId: string, + accessToken?: string, +): Promise { + const url = `https://${API_ENDPOINT}/repos/${userName}/${repoName}/pulls/${pullId}/comments` + return await request(url, { accessToken }) +} + export async function getPullPageDocument( userName: string, repoName: string, diff --git a/src/platforms/GitHub/Request.d.ts b/src/platforms/GitHub/Request.d.ts index a010a1c..5b9d8c1 100644 --- a/src/platforms/GitHub/Request.d.ts +++ b/src/platforms/GitHub/Request.d.ts @@ -35,7 +35,19 @@ declare namespace GitHubAPI { changed_files: number } + type PullComment = { + path: string + pull_request_review_id: number + id: number + node_id: string + diff_hunk: string + body: string + html_url: string + author_association: string + } + type PullTreeData = PullTreeItem[] + type PullComments = PullComment[] type MetaData = { name: string diff --git a/src/platforms/GitHub/index.ts b/src/platforms/GitHub/index.ts index 9668172..159d1b1 100644 --- a/src/platforms/GitHub/index.ts +++ b/src/platforms/GitHub/index.ts @@ -160,9 +160,10 @@ export const GitHub: Platform = { GITHUB_API_RESPONSE_LENGTH_LIMIT / GITHUB_API_PAGED_RESPONSE_LENGTH_LIMIT, ) let page = 1 - const [pullData, treeData] = await Promise.all([ + const [pullData, treeData, commentData] = await Promise.all([ API.getPullData(userName, repoName, pullId, accessToken), API.getPullTreeData(userName, repoName, pullId, page, accessToken), + API.getPullComments(userName, repoName, pullId, accessToken), ]) const count = pullData.changed_files @@ -190,6 +191,7 @@ export const GitHub: Platform = { window.location.search }#${creator(item.filename) || ''}`, sha: item.sha, + comments: commentData?.filter(comment => item.filename === comment.path).length, })) const root = processTree(nodes) diff --git a/src/styles/index.scss b/src/styles/index.scss index 91138d6..ecd8320 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -524,6 +524,12 @@ $minimal-z-index: max($github-header-z-index, $github-pull-request-float-header- .node-item { background: var(--gitako-bg-primary); + &:hover { + text-decoration: initial; // revert underline from .gitako-side-bar a:hover + .node-item-label { + text-decoration: underline; // apply underline like .gitako-side-bar a:hover + } + } &.focused, &:hover { background: var(--gitako-bg-tertiary); @@ -598,6 +604,15 @@ $minimal-z-index: max($github-header-z-index, $github-pull-request-float-header- } } + .node-item-comment { + padding: 0 4px; + color: var(--gitako-text-tertiary); + + .octicon-wrapper { + margin: 0; // make it closer to the comment amount label + } + } + .go-to-button, .find-in-folder-button { @include icon-button(); diff --git a/src/utils/config/helper.ts b/src/utils/config/helper.ts index 9680976..2bacbcf 100644 --- a/src/utils/config/helper.ts +++ b/src/utils/config/helper.ts @@ -17,6 +17,7 @@ export type Config = { recursiveToggleFolder: 'shift' | 'alt' searchMode: SearchMode sidebarToggleMode: 'persistent' | 'float' + commentToggle: boolean } enum configKeys { @@ -33,6 +34,7 @@ enum configKeys { recursiveToggleFolder = 'recursiveToggleFolder', searchMode = 'searchMode', sidebarToggleMode = 'sidebarToggleMode', + commentToggle = 'commentToggle', } export const defaultConfigs: Config = { @@ -49,6 +51,7 @@ export const defaultConfigs: Config = { recursiveToggleFolder: 'shift', searchMode: 'fuzzy', sidebarToggleMode: 'float', + commentToggle: true, } const configKeyArray = Object.values(configKeys)