diff --git a/browser-extension/src/lib/config.ts b/browser-extension/src/lib/config.ts index 74b71b2..73f1820 100644 --- a/browser-extension/src/lib/config.ts +++ b/browser-extension/src/lib/config.ts @@ -9,6 +9,6 @@ export type LogLevel = (typeof LOG_LEVELS)[number] export const CONFIG = { ADDED_OVERTYPE_CLASS: 'gitcasso-overtype', EXTENSION_NAME: 'gitcasso', // decorates logs - LOG_LEVEL: 'DEBUG' satisfies LogLevel, + LOG_LEVEL: 'INFO' satisfies LogLevel, MODE: 'PROD' satisfies ModeType, } as const diff --git a/browser-extension/src/lib/enhancers/github/githubIssueNewComment.ts b/browser-extension/src/lib/enhancers/github/githubIssueNewComment.ts new file mode 100644 index 0000000..01c0333 --- /dev/null +++ b/browser-extension/src/lib/enhancers/github/githubIssueNewComment.ts @@ -0,0 +1,67 @@ +import OverType, { type OverTypeInstance } from 'overtype' +import type { CommentEnhancer, CommentSpot } from '../../enhancer' +import { logger } from '../../logger' +import { modifyDOM } from '../modifyDOM' +import { githubHighlighter } from './githubHighlighter' + +interface GitHubIssueNewCommentSpot extends CommentSpot { + type: 'GH_ISSUE_NEW_COMMENT' + domain: string + slug: string // owner/repo +} + +export class GitHubIssueNewCommentEnhancer implements CommentEnhancer { + forSpotTypes(): string[] { + return ['GH_ISSUE_NEW_COMMENT'] + } + + tryToEnhance(_textarea: HTMLTextAreaElement): GitHubIssueNewCommentSpot | null { + if (document.querySelector('meta[name="hostname"]')?.getAttribute('content') !== 'github.com') { + return null + } + + // Parse GitHub URL structure: /owner/repo/issues/123 or /owner/repo/pull/456 + logger.debug(`${this.constructor.name} examing url`, window.location.pathname) + + const match = window.location.pathname.match(/^\/([^/]+)\/([^/]+)(?:\/issues\/new)/) + logger.debug(`${this.constructor.name} found match`, window.location.pathname) + + if (!match) return null + const [, owner, repo] = match + const slug = `${owner}/${repo}` + const unique_key = `github.com:${slug}:new` + return { + domain: 'github.com', + slug, + type: 'GH_ISSUE_NEW_COMMENT', + unique_key, + } + } + + prepareForFirstEnhancement(): void { + OverType.setCodeHighlighter(githubHighlighter) + } + + enhance(textArea: HTMLTextAreaElement, _spot: GitHubIssueNewCommentSpot): OverTypeInstance { + const overtypeContainer = modifyDOM(textArea) + return new OverType(overtypeContainer, { + autoResize: true, + minHeight: '400px', + padding: 'var(--base-size-16)', + placeholder: 'Type your description here...', + })[0]! + } + + tableTitle(spot: GitHubIssueNewCommentSpot): string { + const { slug } = spot + return `${slug} New Issue` + } + + tableIcon(_: GitHubIssueNewCommentSpot): string { + return '🔄' // PR icon TODO: icon urls in /public + } + + buildUrl(spot: GitHubIssueNewCommentSpot): string { + return `https://${spot.domain}/${spot.slug}/issue/new` + } +} diff --git a/browser-extension/src/lib/enhancers/github/githubPRNewComment.ts b/browser-extension/src/lib/enhancers/github/githubPRNewComment.ts new file mode 100644 index 0000000..79f217b --- /dev/null +++ b/browser-extension/src/lib/enhancers/github/githubPRNewComment.ts @@ -0,0 +1,72 @@ +import OverType, { type OverTypeInstance } from 'overtype' +import type { CommentEnhancer, CommentSpot } from '../../enhancer' +import { logger } from '../../logger' +import { modifyDOM } from '../modifyDOM' +import { githubHighlighter } from './githubHighlighter' + +interface GitHubPRNewCommentSpot extends CommentSpot { + type: 'GH_PR_NEW_COMMENT' + domain: string + slug: string // owner/repo/base-branch/compare-branch +} + +export class GitHubPRNewCommentEnhancer implements CommentEnhancer { + forSpotTypes(): string[] { + return ['GH_PR_NEW_COMMENT'] + } + + tryToEnhance(_textarea: HTMLTextAreaElement): GitHubPRNewCommentSpot | null { + if (document.querySelector('meta[name="hostname"]')?.getAttribute('content') !== 'github.com') { + return null + } + + // /owner/repo/compare/feature/more-enhancers?expand=1 + // or /owner/repo/compare/feat/issue-static-and-dynamic...feature/more-enhancers?expand=1 + logger.info(`${this.constructor.name} examing url`, window.location.pathname) + + const match = window.location.pathname.match( + /^\/([^/]+)\/([^/]+)\/compare\/(?:([^.?]+)\.\.\.)?([^?]+)/, + ) + logger.info(`${this.constructor.name} found match`, window.location.pathname, match) + + if (!match) return null + const [, owner, repo, baseBranch, compareBranch] = match + const slug = baseBranch + ? `${owner}/${repo}/${baseBranch}...${compareBranch}` + : `${owner}/${repo}/${compareBranch}` + const unique_key = `github.com:${slug}` + return { + domain: 'github.com', + slug, + type: 'GH_PR_NEW_COMMENT', + unique_key, + } + } + + prepareForFirstEnhancement(): void { + OverType.setCodeHighlighter(githubHighlighter) + } + + enhance(textArea: HTMLTextAreaElement, _spot: GitHubPRNewCommentSpot): OverTypeInstance { + const overtypeContainer = modifyDOM(textArea) + return new OverType(overtypeContainer, { + autoResize: true, + minHeight: '250px', + padding: 'var(--base-size-16)', + placeholder: 'Type your description here...', + })[0]! + } + + tableTitle(spot: GitHubPRNewCommentSpot): string { + const { slug } = spot + return `${slug} New Issue` + } + + tableIcon(_: GitHubPRNewCommentSpot): string { + return '🔄' // PR icon TODO: icon urls in /public + } + + buildUrl(spot: GitHubPRNewCommentSpot): string { + return `https://${spot.domain}/${spot.slug}/issue/new` + } +} diff --git a/browser-extension/src/lib/registries.ts b/browser-extension/src/lib/registries.ts index 373a7a4..d6cf1aa 100644 --- a/browser-extension/src/lib/registries.ts +++ b/browser-extension/src/lib/registries.ts @@ -2,7 +2,9 @@ import type { OverTypeInstance } from 'overtype' import OverType from 'overtype' import type { CommentEnhancer, CommentSpot } from './enhancer' import { GitHubIssueAddCommentEnhancer } from './enhancers/github/githubIssueAddComment' +import { GitHubIssueNewCommentEnhancer } from './enhancers/github/githubIssueNewComment' import { GitHubPRAddCommentEnhancer } from './enhancers/github/githubPRAddComment' +import { GitHubPRNewCommentEnhancer } from './enhancers/github/githubPRNewComment' export interface EnhancedTextarea { textarea: HTMLTextAreaElement @@ -19,7 +21,9 @@ export class EnhancerRegistry { constructor() { // Register all available handlers this.register(new GitHubIssueAddCommentEnhancer()) + this.register(new GitHubIssueNewCommentEnhancer()) this.register(new GitHubPRAddCommentEnhancer()) + this.register(new GitHubPRNewCommentEnhancer()) const textColor = 'rgb(31, 35, 40)' const headingColor = 'rgb(174, 52, 151)' OverType.setTheme({ diff --git a/browser-extension/tests/har-fixture.ts b/browser-extension/tests/har-fixture.ts index b15cb39..60e7e90 100644 --- a/browser-extension/tests/har-fixture.ts +++ b/browser-extension/tests/har-fixture.ts @@ -41,7 +41,7 @@ export { expect } export function usingHar(harKey: keyof typeof PAGES) { return { it: (name: string, fn: () => void | Promise) => { - return baseTest(name, async () => { + return baseTest(`${harKey}:${name}`, async () => { // Setup HAR DOM before test await setupHarDOM(harKey) diff --git a/browser-extension/tests/lib/enhancers/github.test.ts b/browser-extension/tests/lib/enhancers/github.test.ts index 3952e81..1b56dea 100644 --- a/browser-extension/tests/lib/enhancers/github.test.ts +++ b/browser-extension/tests/lib/enhancers/github.test.ts @@ -21,6 +21,19 @@ describe('github', () => { } `) }) + usingHar('gh_new_pr').it('should create the correct spot object', async () => { + const enhancers = new EnhancerRegistry() + const textareas = document.querySelectorAll('textarea') + expect(textareas.length).toBe(2) + expect(enhancers.tryToEnhance(textareas[0]!)?.spot).toMatchInlineSnapshot(` + { + "domain": "github.com", + "slug": "diffplug/selfie/main...cavia-porcellus:selfie:main", + "type": "GH_PR_NEW_COMMENT", + "unique_key": "github.com:diffplug/selfie/main...cavia-porcellus:selfie:main", + } + `) + }) usingHar('gh_issue').it('should create the correct spot object', async () => { const enhancers = new EnhancerRegistry() const textareas = document.querySelectorAll('textarea') @@ -35,4 +48,17 @@ describe('github', () => { } `) }) + usingHar('gh_new_issue').it('should create the correct spot object', async () => { + const enhancers = new EnhancerRegistry() + const textareas = document.querySelectorAll('textarea') + expect(textareas.length).toBe(1) + expect(enhancers.tryToEnhance(textareas[0]!)?.spot).toMatchInlineSnapshot(` + { + "domain": "github.com", + "slug": "diffplug/selfie", + "type": "GH_ISSUE_NEW_COMMENT", + "unique_key": "github.com:diffplug/selfie:new", + } + `) + }) })