mirror of
https://github.com/EnixCoda/Gitako.git
synced 2026-03-11 08:54:44 +00:00
fix: support new pull request experience new data structure
This commit is contained in:
parent
f67065bcf4
commit
ecaf9087a3
6 changed files with 77 additions and 45 deletions
|
|
@ -2,7 +2,11 @@ import { errors } from 'platforms'
|
|||
import { isEnterprise } from '.'
|
||||
import { is } from '../../utils/is'
|
||||
import { gitakoServiceHost } from '../../utils/networkService'
|
||||
import { continuousLoadFragmentedPages, getDOM, resolveHeaderLink } from './utils'
|
||||
import {
|
||||
continuousLoadFragmentedPages,
|
||||
continuousLoadFragmentedPagesFromUrl,
|
||||
resolveHeaderLink,
|
||||
} from './utils'
|
||||
|
||||
function isAPIRateLimitExceeded(content: JSONValue) {
|
||||
return (
|
||||
|
|
@ -145,15 +149,15 @@ export async function getPullPageDocuments(
|
|||
repoName: string,
|
||||
pullId: string,
|
||||
document?: Document,
|
||||
): Promise<Document[]> {
|
||||
// Response of this API contains view of few files but is not complete.
|
||||
return continuousLoadFragmentedPages(
|
||||
document ||
|
||||
(await getDOM(`${window.location.origin}/${userName}/${repoName}/pull/${pullId}/files`)),
|
||||
)
|
||||
) {
|
||||
if (document) {
|
||||
return continuousLoadFragmentedPages(document)
|
||||
}
|
||||
// Response of this contains view of few files but is not complete.
|
||||
return continuousLoadFragmentedPagesFromUrl(`/${userName}/${repoName}/pull/${pullId}/files`)
|
||||
}
|
||||
|
||||
export async function getCommitPageDocuments(): Promise<Document[]> {
|
||||
export async function getCommitPageDocuments() {
|
||||
/* userName: string,
|
||||
repoName: string,
|
||||
commitId: string, */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import * as s from 'superstruct'
|
||||
|
||||
const repo = s.object({
|
||||
const repo = s.type({
|
||||
id: s.number(),
|
||||
defaultBranch: s.string(),
|
||||
name: s.string(),
|
||||
|
|
@ -15,13 +15,13 @@ const repo = s.object({
|
|||
isOrgOwned: s.boolean(),
|
||||
})
|
||||
|
||||
const user = s.object({
|
||||
const user = s.type({
|
||||
id: s.number(),
|
||||
login: s.string(),
|
||||
userEmail: s.string(),
|
||||
})
|
||||
|
||||
const rel = s.object({
|
||||
const rel = s.type({
|
||||
name: s.string(),
|
||||
listCacheKey: s.string(),
|
||||
canEdit: s.boolean(),
|
||||
|
|
@ -29,13 +29,13 @@ const rel = s.object({
|
|||
currentOid: s.string(),
|
||||
})
|
||||
|
||||
const treeItem = s.object({
|
||||
const treeItem = s.type({
|
||||
name: s.string(),
|
||||
path: s.string(),
|
||||
contentType: s.string(),
|
||||
})
|
||||
|
||||
const tree = s.object({
|
||||
const tree = s.type({
|
||||
items: s.array(treeItem),
|
||||
templateDirectorySuggestionUrl: s.nullable(s.never()),
|
||||
readme: s.nullable(s.never()),
|
||||
|
|
@ -43,7 +43,7 @@ const tree = s.object({
|
|||
showBranchInfobar: s.boolean(),
|
||||
})
|
||||
|
||||
const repoPayload = s.object({
|
||||
const repoPayload = s.type({
|
||||
allShortcutsEnabled: s.boolean(),
|
||||
path: s.string(),
|
||||
repo: repo,
|
||||
|
|
@ -59,18 +59,18 @@ const repoPayload = s.object({
|
|||
overview: s.unknown(),
|
||||
})
|
||||
|
||||
const reposOverview = s.object({
|
||||
props: s.object({
|
||||
const reposOverview = s.type({
|
||||
props: s.type({
|
||||
initialPayload: repoPayload,
|
||||
appPayload: s.unknown(),
|
||||
}),
|
||||
})
|
||||
|
||||
const app = s.object({
|
||||
const app = s.type({
|
||||
payload: repoPayload,
|
||||
})
|
||||
|
||||
const diffSummary = s.object({
|
||||
const diffSummary = s.type({
|
||||
changeType: s.string(),
|
||||
highestAnnotationLevel: s.nullable(s.string()),
|
||||
isCodeowner: s.nullable(s.boolean()),
|
||||
|
|
@ -87,11 +87,18 @@ const diffSummary = s.object({
|
|||
|
||||
export type DiffSummary = s.Infer<typeof diffSummary>
|
||||
|
||||
const pullRequest = s.object({
|
||||
payload: s.object({
|
||||
pullRequestsFilesRoute: s.object({
|
||||
diffSummaries: s.array(diffSummary),
|
||||
}),
|
||||
const pullRequest = s.type({
|
||||
payload: s.type({
|
||||
pullRequestsFilesRoute: s.optional(
|
||||
s.type({
|
||||
diffSummaries: s.array(diffSummary),
|
||||
}),
|
||||
),
|
||||
pullRequestsChangesRoute: s.optional(
|
||||
s.type({
|
||||
diffSummaries: s.array(diffSummary),
|
||||
}),
|
||||
),
|
||||
}),
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ export async function getCommitTreeData(
|
|||
.map(({ files }) => files)
|
||||
.flat()
|
||||
|
||||
const documents = await API.getCommitPageDocuments(/* userName, repoName, commitSHA */)
|
||||
const [, documents] = await API.getCommitPageDocuments(/* userName, repoName, commitSHA */)
|
||||
|
||||
const getItemURL = (path: string) => {
|
||||
for (const doc of documents) {
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ export async function getPullRequestTreeData(
|
|||
API.getPullComments(userName, repoName, pullId, accessToken),
|
||||
])
|
||||
|
||||
const docs = await API.getPullPageDocuments(
|
||||
const [fileChangesPagePath, docs] = await API.getPullPageDocuments(
|
||||
userName,
|
||||
repoName,
|
||||
pullId,
|
||||
|
|
@ -53,7 +53,7 @@ export async function getPullRequestTreeData(
|
|||
: resolveFileHashMap(docs)
|
||||
|
||||
const url = new URL(sanitizedLocation.href)
|
||||
url.pathname = `/${userName}/${repoName}/pull/${pullId}/files`
|
||||
url.pathname = fileChangesPagePath
|
||||
const commentsMap = getCommentsMap(commentData)
|
||||
const nodes: TreeNode[] = treeData.map(
|
||||
({
|
||||
|
|
@ -117,12 +117,15 @@ function resolveDiffSummaryMap(docs: Document[]) {
|
|||
return docs
|
||||
.map(resolveEmbeddedPullRequestData)
|
||||
.map(json => {
|
||||
try {
|
||||
return json?.payload.pullRequestsFilesRoute.diffSummaries
|
||||
} catch (error) {
|
||||
return null
|
||||
const payload = json?.payload
|
||||
if (!payload) return null
|
||||
if ('pullRequestsFilesRoute' in payload) {
|
||||
return payload.pullRequestsFilesRoute
|
||||
} else if ('pullRequestsChangesRoute' in payload) {
|
||||
return payload.pullRequestsChangesRoute
|
||||
}
|
||||
})
|
||||
.map(pullRequests => pullRequests?.diffSummaries)
|
||||
.reduce((map, curr) => {
|
||||
curr?.forEach(record => {
|
||||
map.set(record.path, record)
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import { findMapFirst } from '../../utils/findMapFirst'
|
||||
|
||||
/**
|
||||
* Resolved from response header `link`
|
||||
*
|
||||
|
|
@ -75,10 +77,19 @@ export function resolveHeaderLink(raw: string) {
|
|||
}
|
||||
|
||||
export async function getDOM(url: string) {
|
||||
return new DOMParser().parseFromString(await (await fetch(url)).text(), 'text/html')
|
||||
const res = await fetch(url)
|
||||
const content = await res.text()
|
||||
return new DOMParser().parseFromString(content, 'text/html')
|
||||
}
|
||||
|
||||
export async function continuousLoadFragmentedPages(doc: Document) {
|
||||
export async function continuousLoadFragmentedPages(
|
||||
doc: Document,
|
||||
docs: Document[] = [],
|
||||
): Promise<[string, Document[]]> {
|
||||
docs.push(doc)
|
||||
|
||||
// const data = resolveEmbeddedPullRequestData(doc)
|
||||
|
||||
/**
|
||||
* <include-fragment
|
||||
* src="..."
|
||||
|
|
@ -92,22 +103,22 @@ export async function continuousLoadFragmentedPages(doc: Document) {
|
|||
'.js-diff-progressive-container include-fragment[src]', // legacy support
|
||||
]
|
||||
|
||||
const documents: Document[] = [doc]
|
||||
|
||||
const selector = fragmentSelectors.find(selector => doc.querySelector(selector))
|
||||
if (selector) {
|
||||
// eslint-disable-next-line no-constant-condition
|
||||
while (true) {
|
||||
const fragment = doc.querySelector(selector)
|
||||
if (!(fragment instanceof HTMLElement)) break
|
||||
const src = fragment.getAttribute('src')
|
||||
if (!src) break
|
||||
const fragment = findMapFirst(fragmentSelectors, selector => doc.querySelector(selector))
|
||||
if (fragment instanceof HTMLElement) {
|
||||
const src = fragment.getAttribute('src')
|
||||
if (src) {
|
||||
// Using `src` without origin below would fail in Firefox if the src is an absolute path
|
||||
doc = await getDOM(new URL(src, window.location.origin).href)
|
||||
documents.push(doc)
|
||||
await continuousLoadFragmentedPagesFromUrl(src, docs)
|
||||
}
|
||||
}
|
||||
return documents
|
||||
return [new URL(doc.baseURI).pathname, docs]
|
||||
}
|
||||
|
||||
export async function continuousLoadFragmentedPagesFromUrl(url: string, docs: Document[] = []) {
|
||||
return continuousLoadFragmentedPages(
|
||||
await getDOM(new URL(url, window.location.origin).href),
|
||||
docs,
|
||||
)
|
||||
}
|
||||
|
||||
export function getCommentsMap(commentData: GitHubAPI.PullComments) {
|
||||
|
|
|
|||
7
src/utils/findMapFirst.ts
Normal file
7
src/utils/findMapFirst.ts
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
export const findMapFirst = <T, R>(array: T[], map: (item: T) => R): R | null => {
|
||||
for (const item of array) {
|
||||
const result = map(item)
|
||||
if (result) return result
|
||||
}
|
||||
return null
|
||||
}
|
||||
Loading…
Reference in a new issue