Skip to content

Commit 701f221

Browse files
authored
useful-not-found-page - Improve style and reliability (#9812)
1 parent 89b9f05 commit 701f221

11 files changed

Lines changed: 217 additions & 205 deletions

build/__snapshots__/features-meta.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1031,6 +1031,7 @@
10311031
{
10321032
"id": "useful-not-found-page",
10331033
"description": "Adds possible related pages and alternatives on 404 pages.",
1034+
"css": true,
10341035
"screenshot": "https://user-images.githubusercontent.com/1402241/46402857-7bdada80-c733-11e8-91a1-856573078ff5.png"
10351036
},
10361037
{

build/features.test.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,10 @@ class FeatureFile {
9797
get css(): FeatureFile {
9898
return new FeatureFile(this.id + '.css');
9999
}
100+
101+
get svelte(): FeatureFile {
102+
return new FeatureFile(this.id + '.svelte');
103+
}
100104
}
101105

102106
function validateReadme(featureId: FeatureId): void {
@@ -158,8 +162,9 @@ function validateGql(file: FeatureFile): void {
158162
);
159163

160164
assert(
161-
file.tsx.contents().includes(`from './${file.name}';`),
162-
`Should be imported by \`${file.tsx.name}\``,
165+
file.tsx.contents().includes(`from './${file.name}';`)
166+
|| file.svelte.exists() && file.svelte.contents().includes(`from './${file.name}';`),
167+
`Should be imported by \`${file.tsx.name}\` or \`${file.svelte.name}\``,
163168
);
164169
}
165170

package-lock.json

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
"filter-altered-clicks": "^2.1.1",
4040
"flat-zip": "^1.0.1",
4141
"github-reserved-names": "^2.2.0",
42-
"github-url-detection": "^11.2.2",
42+
"github-url-detection": "^11.2.3",
4343
"indent-textarea": "^4.0.0",
4444
"js-abbreviation-number": "^1.4.0",
4545
"linkify-issues": "^4.2.0",

source/features/easy-toggle-commit-messages.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ void features.add(import.meta.url, {
5151
pageDetect.isSingleFile,
5252
],
5353
exclude: [
54-
pageDetect.isRepoFile404,
54+
pageDetect.is404,
5555
],
5656
init,
5757
});

source/features/file-age-color.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ void features.add(import.meta.url, {
3636
pageDetect.isRepoTree,
3737
],
3838
exclude: [
39-
pageDetect.isRepoFile404,
39+
pageDetect.is404,
4040
],
4141
init,
4242
});

source/features/quick-file-edit.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ void features.add(import.meta.url, {
3232
pageDetect.isRepoTree,
3333
],
3434
exclude: [
35-
pageDetect.isRepoFile404,
35+
pageDetect.is404,
3636
isArchivedRepoAsync,
3737
isPermalink,
3838
],
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
/* Missing file */
2+
.flex-items-center a[aria-label='go to Overview'],
3+
/* Missing branch */
4+
.flex-items-center a[aria-label='go to default branch'] {
5+
display: none;
6+
}
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
<script lang="ts">
2+
import api from '../github-helpers/api.js';
3+
import getDefaultBranch from '../github-helpers/get-default-branch.js';
4+
import GitHubFileUrl from '../github-helpers/github-file-url.js';
5+
import {isUrlReachable} from '../github-helpers/index.js';
6+
import GetLatestCommitToFile from './useful-not-found-page.gql';
7+
8+
type File = {
9+
previous_filename?: string;
10+
filename: string;
11+
status: string;
12+
blob_url: string;
13+
};
14+
15+
type FileChanges = {
16+
file: File;
17+
commit: {
18+
parentSha: string;
19+
date: Date;
20+
url: string;
21+
};
22+
};
23+
24+
type GitHistory = {
25+
oldFilename: string;
26+
lastVersionUrl: string;
27+
status: string;
28+
movedUrl: string;
29+
commitUrl: string;
30+
commitDate: Date;
31+
};
32+
33+
function getType(): string {
34+
return location.pathname.split('/').pop()!.includes('.') ? 'file' : 'object';
35+
}
36+
37+
async function getLatestCommitToFile(
38+
branch: string,
39+
filePath: string,
40+
): Promise<string> {
41+
const {repository} = await api.v4(GetLatestCommitToFile, {
42+
variables: {branch, filePath},
43+
});
44+
45+
return repository.object
46+
// Missing if the ref doesn't exist
47+
?.history.nodes[0]
48+
// Missing if the ref exists but the file never existed
49+
?.oid;
50+
}
51+
52+
async function getChangesToFileInCommit(
53+
sha: string,
54+
filePath: string,
55+
): Promise<FileChanges | undefined> {
56+
const commit = await api.v3(`commits/${sha}`);
57+
for (const fileInfo of commit.files as File[]) {
58+
if ([fileInfo.filename, fileInfo.previous_filename].includes(filePath)) {
59+
return {
60+
commit: {
61+
parentSha: commit.parents[0].sha,
62+
date: commit.commit.committer.date,
63+
url: commit.html_url,
64+
},
65+
file: fileInfo,
66+
};
67+
}
68+
}
69+
70+
return undefined;
71+
}
72+
73+
async function getUrlToFileOnDefaultBranch(): Promise<string | undefined> {
74+
const parsedUrl = new GitHubFileUrl(location.href);
75+
if (!parsedUrl.branch) {
76+
return undefined;
77+
}
78+
79+
parsedUrl.assign({branch: await getDefaultBranch()});
80+
const urlOnDefault = parsedUrl.href;
81+
if (urlOnDefault !== location.href && await isUrlReachable(urlOnDefault)) {
82+
return urlOnDefault;
83+
}
84+
85+
return undefined;
86+
}
87+
88+
async function getGitHistory(): Promise<GitHistory | undefined> {
89+
const url = new GitHubFileUrl(location.href);
90+
if (!url.branch || !url.filePath) {
91+
return undefined;
92+
}
93+
94+
const commitSha = await getLatestCommitToFile(url.branch, url.filePath);
95+
if (!commitSha) {
96+
// Never existed
97+
return undefined;
98+
}
99+
100+
const fileChanges = await getChangesToFileInCommit(commitSha, url.filePath);
101+
if (!fileChanges) {
102+
return undefined;
103+
}
104+
105+
return {
106+
oldFilename: fileChanges.file.previous_filename ?? fileChanges.file.filename,
107+
lastVersionUrl: fileChanges.file.status === 'removed'
108+
? fileChanges.file.blob_url
109+
: url.href,
110+
status: fileChanges.file.status,
111+
movedUrl: decodeURIComponent(fileChanges.file.blob_url), // Why is the API returning dir%2Ffile.js??!
112+
commitUrl: fileChanges.commit.url,
113+
commitDate: fileChanges.commit.date,
114+
};
115+
}
116+
117+
const type = getType();
118+
</script>
119+
120+
<div class="color-fg-muted rgh-hide-if-empty">
121+
{#await getGitHistory()}
122+
Loading history of this {type}...
123+
{:then gitHistory}
124+
{#if gitHistory}
125+
<span class="commit-ref">
126+
<a href={gitHistory.commitUrl}>
127+
{new GitHubFileUrl(gitHistory.commitUrl).branch.slice(0, 8)}
128+
</a>
129+
</span>
130+
{gitHistory.status}
131+
<a href={gitHistory.lastVersionUrl}>{gitHistory.oldFilename}</a>
132+
{#if gitHistory.status !== 'removed'}
133+
to <a href={gitHistory.movedUrl}>{
134+
gitHistory.movedUrl.split('/').slice(7).join('/')
135+
}</a>
136+
{/if}
137+
<relative-time datetime={gitHistory.commitDate}></relative-time>.
138+
{:else}
139+
<!-- TODO: Handle scenario. Can be because branch OR file is 404 -->
140+
{/if}
141+
{/await}
142+
</div>
143+
144+
<div class="color-fg-muted rgh-hide-if-empty">
145+
{#await getUrlToFileOnDefaultBranch()}
146+
Loading default branch...
147+
{:then defaultBranchUrl}
148+
{#if defaultBranchUrl}
149+
<a href={defaultBranchUrl}>{
150+
new GitHubFileUrl(defaultBranchUrl).filePath
151+
}</a> exists on the default branch.
152+
{/if}
153+
{/await}
154+
</div>

0 commit comments

Comments
 (0)