diff --git a/src/components/FileExplorer.tsx b/src/components/FileExplorer.tsx index 81002d4..d39dd59 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( @@ -104,18 +104,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 c5d9f07..ce98f05 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, @@ -28,6 +29,11 @@ function getSVGIconComponent( name: string } { switch (type) { + case 'comment': + return { + IconComponent: Comment, + name: 'Comment', + } case 'search': return { IconComponent: Search, diff --git a/src/components/settings/SidebarSettings.tsx b/src/components/settings/SidebarSettings.tsx index 8f805b0..3ac1ed8 100644 --- a/src/components/settings/SidebarSettings.tsx +++ b/src/components/settings/SidebarSettings.tsx @@ -102,6 +102,14 @@ export function SidebarSettings(props: React.PropsWithChildren) { }, }} /> + ) } diff --git a/src/global.d.ts b/src/global.d.ts index 081c987..199ec17 100644 --- a/src/global.d.ts +++ b/src/global.d.ts @@ -14,6 +14,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 4b63d68..f37bff6 100644 --- a/src/platforms/GitHub/index.ts +++ b/src/platforms/GitHub/index.ts @@ -177,9 +177,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 @@ -207,6 +208,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 85a3e31..ee47712 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -500,6 +500,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); @@ -574,6 +580,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/configHelper.ts b/src/utils/configHelper.ts index bbedd31..01c1869 100644 --- a/src/utils/configHelper.ts +++ b/src/utils/configHelper.ts @@ -14,6 +14,7 @@ export type Config = { toggleButtonContent: 'logo' | 'octoface' recursiveToggleFolder: 'shift' | 'alt' searchMode: SearchMode + commentToggle: boolean } enum configKeys { @@ -29,6 +30,7 @@ enum configKeys { toggleButtonContent = 'toggleButtonContent', recursiveToggleFolder = 'recursiveToggleFolder', searchMode = 'searchMode', + commentToggle = 'commentToggle', } const defaultConfigs: Config = { @@ -44,6 +46,7 @@ const defaultConfigs: Config = { toggleButtonContent: 'logo', recursiveToggleFolder: 'shift', searchMode: 'fuzzy', + commentToggle: true, } const configKeyArray = Object.values(configKeys) @@ -85,6 +88,7 @@ async function migrateConfig() { 'copySnippetButton', 'intelligentToggle', 'icons', + 'commentToggle', ]) if (config && (!('configVersion' in config) || config.configVersion < version)) { await storageHelper.set({ platform_GitHub: config, configVersion: version })