coder/coder that groups changes into generated, tests, backend, frontend, and other, with checkboxes to show/hide each category.",
+ "css": true,
+ "screenshot": null
+ },
{
"id": "collapsible-content-button",
"description": "Adds a button in the text editor to insert collapsible content (via <details>).",
@@ -519,11 +525,6 @@
"description": "Adds links to view the raw version, the blame, and the history of files in PRs and commits.",
"screenshot": "https://user-images.githubusercontent.com/46634000/145016304-aec5a8b8-4cdb-48e6-936f-b214a3fb4b49.png"
},
- {
- "id": "netiquette",
- "description": "Adds unobtrusive netiquette reminders (old closed issues, highly-active issues, draft PRs, …).",
- "screenshot": "https://github.com/user-attachments/assets/8646d663-7458-4e6d-888a-68d38110fcda"
- },
{
"id": "new-milestone-button",
"description": "Adds a 'New Milestone' button to the milestone page.",
diff --git a/build/__snapshots__/imported-features.json b/build/__snapshots__/imported-features.json
index 469e6f68990f..b8bfdec51431 100644
--- a/build/__snapshots__/imported-features.json
+++ b/build/__snapshots__/imported-features.json
@@ -22,6 +22,7 @@
"close-out-of-view-modals",
"closing-remarks",
"cmd-enter",
+ "coder-pr-loc-stats",
"collapsible-content-button",
"comments-time-machine-links",
"confirm-release",
@@ -86,7 +87,6 @@
"mark-pinned",
"mark-private-orgs",
"more-file-links",
- "netiquette",
"new-milestone-button",
"new-or-deleted-file",
"new-repo-disable-projects-and-wikis",
diff --git a/build/features.test.ts b/build/features.test.ts
index 63d89a0c3b90..bf391d3f174f 100755
--- a/build/features.test.ts
+++ b/build/features.test.ts
@@ -31,6 +31,7 @@ const noScreenshotExceptions = new Set([
'monospace-textareas',
'new-tab-links',
'extensible-nav', // No visual or behavior change
+ 'coder-pr-loc-stats', // Fork-only feature, no upstream screenshot
'hide-navigation-hover-highlight', // TODO: Add side-by-side GIF
'hide-inactive-deployments', // TODO: side-by-side PNG
diff --git a/package-lock.json b/package-lock.json
index ca39164b7c93..8650bd0648a1 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -208,9 +208,6 @@
"arm64"
],
"dev": true,
- "libc": [
- "glibc"
- ],
"license": "MIT OR Apache-2.0",
"optional": true,
"os": [
@@ -228,9 +225,6 @@
"arm64"
],
"dev": true,
- "libc": [
- "musl"
- ],
"license": "MIT OR Apache-2.0",
"optional": true,
"os": [
@@ -248,9 +242,6 @@
"x64"
],
"dev": true,
- "libc": [
- "glibc"
- ],
"license": "MIT OR Apache-2.0",
"optional": true,
"os": [
@@ -268,9 +259,6 @@
"x64"
],
"dev": true,
- "libc": [
- "musl"
- ],
"license": "MIT OR Apache-2.0",
"optional": true,
"os": [
@@ -392,9 +380,6 @@
"arm64"
],
"dev": true,
- "libc": [
- "glibc"
- ],
"license": "MIT",
"optional": true,
"os": [
@@ -409,9 +394,6 @@
"arm64"
],
"dev": true,
- "libc": [
- "musl"
- ],
"license": "MIT",
"optional": true,
"os": [
@@ -426,9 +408,6 @@
"loong64"
],
"dev": true,
- "libc": [
- "glibc"
- ],
"license": "MIT",
"optional": true,
"os": [
@@ -443,9 +422,6 @@
"loong64"
],
"dev": true,
- "libc": [
- "musl"
- ],
"license": "MIT",
"optional": true,
"os": [
@@ -460,9 +436,6 @@
"ppc64"
],
"dev": true,
- "libc": [
- "glibc"
- ],
"license": "MIT",
"optional": true,
"os": [
@@ -477,9 +450,6 @@
"ppc64"
],
"dev": true,
- "libc": [
- "musl"
- ],
"license": "MIT",
"optional": true,
"os": [
@@ -494,9 +464,6 @@
"riscv64"
],
"dev": true,
- "libc": [
- "glibc"
- ],
"license": "MIT",
"optional": true,
"os": [
@@ -511,9 +478,6 @@
"x64"
],
"dev": true,
- "libc": [
- "glibc"
- ],
"license": "MIT",
"optional": true,
"os": [
@@ -528,9 +492,6 @@
"x64"
],
"dev": true,
- "libc": [
- "musl"
- ],
"license": "MIT",
"optional": true,
"os": [
@@ -1122,9 +1083,6 @@
"x64"
],
"dev": true,
- "libc": [
- "glibc"
- ],
"license": "MIT",
"optional": true,
"os": [
@@ -1307,9 +1265,6 @@
"arm64"
],
"dev": true,
- "libc": [
- "glibc"
- ],
"license": "MIT",
"optional": true,
"os": [
@@ -1327,9 +1282,6 @@
"arm64"
],
"dev": true,
- "libc": [
- "musl"
- ],
"license": "MIT",
"optional": true,
"os": [
@@ -1347,9 +1299,6 @@
"ppc64"
],
"dev": true,
- "libc": [
- "glibc"
- ],
"license": "MIT",
"optional": true,
"os": [
@@ -1367,9 +1316,6 @@
"s390x"
],
"dev": true,
- "libc": [
- "glibc"
- ],
"license": "MIT",
"optional": true,
"os": [
@@ -1387,9 +1333,6 @@
"x64"
],
"dev": true,
- "libc": [
- "glibc"
- ],
"license": "MIT",
"optional": true,
"os": [
@@ -1407,9 +1350,6 @@
"x64"
],
"dev": true,
- "libc": [
- "musl"
- ],
"license": "MIT",
"optional": true,
"os": [
@@ -1705,9 +1645,6 @@
"arm"
],
"dev": true,
- "libc": [
- "glibc"
- ],
"license": "MIT",
"optional": true,
"os": [
@@ -1722,9 +1659,6 @@
"arm"
],
"dev": true,
- "libc": [
- "musl"
- ],
"license": "MIT",
"optional": true,
"os": [
@@ -1739,9 +1673,6 @@
"arm64"
],
"dev": true,
- "libc": [
- "glibc"
- ],
"license": "MIT",
"optional": true,
"os": [
@@ -1756,9 +1687,6 @@
"arm64"
],
"dev": true,
- "libc": [
- "musl"
- ],
"license": "MIT",
"optional": true,
"os": [
@@ -1773,9 +1701,6 @@
"loong64"
],
"dev": true,
- "libc": [
- "glibc"
- ],
"license": "MIT",
"optional": true,
"os": [
@@ -1790,9 +1715,6 @@
"loong64"
],
"dev": true,
- "libc": [
- "musl"
- ],
"license": "MIT",
"optional": true,
"os": [
@@ -1807,9 +1729,6 @@
"ppc64"
],
"dev": true,
- "libc": [
- "glibc"
- ],
"license": "MIT",
"optional": true,
"os": [
@@ -1824,9 +1743,6 @@
"ppc64"
],
"dev": true,
- "libc": [
- "musl"
- ],
"license": "MIT",
"optional": true,
"os": [
@@ -1841,9 +1757,6 @@
"riscv64"
],
"dev": true,
- "libc": [
- "glibc"
- ],
"license": "MIT",
"optional": true,
"os": [
@@ -1858,9 +1771,6 @@
"riscv64"
],
"dev": true,
- "libc": [
- "musl"
- ],
"license": "MIT",
"optional": true,
"os": [
@@ -1875,9 +1785,6 @@
"s390x"
],
"dev": true,
- "libc": [
- "glibc"
- ],
"license": "MIT",
"optional": true,
"os": [
@@ -1892,9 +1799,6 @@
"x64"
],
"dev": true,
- "libc": [
- "glibc"
- ],
"license": "MIT",
"optional": true,
"os": [
@@ -1909,9 +1813,6 @@
"x64"
],
"dev": true,
- "libc": [
- "musl"
- ],
"license": "MIT",
"optional": true,
"os": [
@@ -3101,9 +3002,6 @@
"arm64"
],
"dev": true,
- "libc": [
- "glibc"
- ],
"license": "MIT",
"optional": true,
"os": [
@@ -3118,9 +3016,6 @@
"arm64"
],
"dev": true,
- "libc": [
- "musl"
- ],
"license": "MIT",
"optional": true,
"os": [
@@ -3135,9 +3030,6 @@
"loong64"
],
"dev": true,
- "libc": [
- "glibc"
- ],
"license": "MIT",
"optional": true,
"os": [
@@ -3152,9 +3044,6 @@
"loong64"
],
"dev": true,
- "libc": [
- "musl"
- ],
"license": "MIT",
"optional": true,
"os": [
@@ -3169,9 +3058,6 @@
"ppc64"
],
"dev": true,
- "libc": [
- "glibc"
- ],
"license": "MIT",
"optional": true,
"os": [
@@ -3186,9 +3072,6 @@
"riscv64"
],
"dev": true,
- "libc": [
- "glibc"
- ],
"license": "MIT",
"optional": true,
"os": [
@@ -3203,9 +3086,6 @@
"riscv64"
],
"dev": true,
- "libc": [
- "musl"
- ],
"license": "MIT",
"optional": true,
"os": [
@@ -3220,9 +3100,6 @@
"s390x"
],
"dev": true,
- "libc": [
- "glibc"
- ],
"license": "MIT",
"optional": true,
"os": [
@@ -3237,9 +3114,6 @@
"x64"
],
"dev": true,
- "libc": [
- "glibc"
- ],
"license": "MIT",
"optional": true,
"os": [
@@ -3254,9 +3128,6 @@
"x64"
],
"dev": true,
- "libc": [
- "musl"
- ],
"license": "MIT",
"optional": true,
"os": [
@@ -6736,9 +6607,6 @@
"arm64"
],
"dev": true,
- "libc": [
- "glibc"
- ],
"license": "MPL-2.0",
"optional": true,
"os": [
@@ -6760,9 +6628,6 @@
"arm64"
],
"dev": true,
- "libc": [
- "musl"
- ],
"license": "MPL-2.0",
"optional": true,
"os": [
@@ -6784,9 +6649,6 @@
"x64"
],
"dev": true,
- "libc": [
- "glibc"
- ],
"license": "MPL-2.0",
"optional": true,
"os": [
@@ -6808,9 +6670,6 @@
"x64"
],
"dev": true,
- "libc": [
- "musl"
- ],
"license": "MPL-2.0",
"optional": true,
"os": [
diff --git a/readme.md b/readme.md
index 20e478d37181..46889bbd6b0e 100644
--- a/readme.md
+++ b/readme.md
@@ -231,6 +231,7 @@ https://github.com/refined-github/refined-github/wiki/Contributing#metadata-guid
- [](# "cross-deleted-pr-branches") [Adds a line-through to the deleted branches in PRs.](https://github-production-user-asset-6210df.s3.amazonaws.com/140871606/256963526-646ac7d0-3e7f-40c6-ba39-014b49bc0063.png)
- [](# "batch-mark-files-as-viewed") [Mark/unmark multiple files as “Viewed” in the PR Files tab. Click on the first checkbox you want to mark/unmark and then `shift`-click another one; all the files between the two checkboxes will be marked/unmarked as “Viewed”.](https://github-production-user-asset-6210df.s3.amazonaws.com/140871606/257009611-17249bee-d2e2-42ac-bdf0-ebc90029544e.gif)
- [](# "closing-remarks") 🔥 [Shows the first Git tag a merged PR was included in or suggests creating a release if not yet released.](https://user-images.githubusercontent.com/1402241/169497171-85d4a97f-413a-41b4-84ba-885dca2b51cf.png)
+- [](# "coder-pr-loc-stats") Adds a LOC stats panel to the PR Files tab on `coder/coder` that groups changes into generated, tests, backend, frontend, and other, with checkboxes to show/hide each category.
- [](# "pr-jump-to-first-non-viewed-file") [Jumps to first non-viewed file in a PR when clicking on the progress bar.](https://github-production-user-asset-6210df.s3.amazonaws.com/140871606/257011208-764f509d-fed9-424b-84e9-c01cf2fd428b.gif)
- [](# "view-last-pr-deployment") [Adds a link to open the latest deployment to the PR header.](https://github.com/user-attachments/assets/90d2498d-ef65-45b9-96eb-07e7988bea61)
- [](# "no-unnecessary-split-diff-view") [Always uses unified diffs on files where split diffs aren’t useful.](https://user-images.githubusercontent.com/46634000/121495005-89af8600-c9d9-11eb-822d-77e0b987e3b1.png)
@@ -352,7 +353,6 @@ https://github.com/refined-github/refined-github/wiki/Contributing#metadata-guid
### Netiquette
-- [](# "netiquette") [Adds unobtrusive netiquette reminders (old closed issues, highly-active issues, draft PRs, …).](https://github.com/user-attachments/assets/8646d663-7458-4e6d-888a-68d38110fcda)
- [](# "warn-pr-from-master") [Warns you when creating a PR from the default branch, as it’s an anti-pattern.](https://user-images.githubusercontent.com/1402241/52543516-3ca94e00-2de5-11e9-9f80-ff8f9fe8bdc4.png)
- [](# "warning-for-disallow-edits") [Warns you when unchecking `Allow edits from maintainers`, as it’s maintainer-hostile.](https://user-images.githubusercontent.com/1402241/53151888-24101380-35ef-11e9-8d30-d6315ad97325.gif)
diff --git a/source/feature-renames.json b/source/feature-renames.json
index f992c7af9cff..72f0a0cea0dc 100644
--- a/source/feature-renames.json
+++ b/source/feature-renames.json
@@ -53,8 +53,6 @@
"highlight-deleted-and-added-files-in-diffs": "new-or-deleted-file",
"enable-file-links-in-compare-view": "actionable-pr-view-file",
"use-first-commit-message-for-new-prs": "pr-first-commit-title",
- "comment-on-draft-pr-indicator": "netiquette",
- "draft-pr-notice": "netiquette",
"comment-excess": "hidden-content",
"highlight-collaborators-and-own-conversations": "conversation-authors"
}
diff --git a/source/features/coder-pr-loc-stats.css b/source/features/coder-pr-loc-stats.css
new file mode 100644
index 000000000000..14c1b2b13fb9
--- /dev/null
+++ b/source/features/coder-pr-loc-stats.css
@@ -0,0 +1,52 @@
+.rgh-coder-loc-stats {
+ position: fixed;
+ inset-block-end: 16px;
+ inset-inline-end: 16px;
+ z-index: 30;
+ max-width: 320px;
+ padding: 8px 12px;
+ font-size: 12px;
+ background: var(--bgColor-default, fuchsia);
+ border: 1px solid var(--borderColor-default, fuchsia);
+ border-radius: 6px;
+ box-shadow: var(--shadow-floating-small, var(--color-shadow-medium));
+}
+
+.rgh-coder-loc-stats summary {
+ cursor: pointer;
+ user-select: none;
+}
+
+.rgh-coder-loc-stats table {
+ margin-top: 8px;
+ border-spacing: 0;
+}
+
+.rgh-coder-loc-stats th {
+ font-weight: var(--base-text-weight-semibold, 600);
+ text-align: start;
+ color: var(--fgColor-muted, fuchsia);
+}
+
+.rgh-coder-loc-stats th,
+.rgh-coder-loc-stats td {
+ padding: 2px 0;
+ padding-inline-end: 12px;
+ white-space: nowrap;
+}
+
+.rgh-coder-loc-stats td:last-child,
+.rgh-coder-loc-stats th:last-child {
+ padding-inline-end: 0;
+}
+
+.rgh-coder-loc-stats label {
+ display: flex;
+ gap: 6px;
+ align-items: center;
+ cursor: pointer;
+}
+
+.rgh-coder-loc-count {
+ color: var(--fgColor-muted, fuchsia);
+}
diff --git a/source/features/coder-pr-loc-stats.tsx b/source/features/coder-pr-loc-stats.tsx
new file mode 100644
index 000000000000..76d6e9d6562f
--- /dev/null
+++ b/source/features/coder-pr-loc-stats.tsx
@@ -0,0 +1,236 @@
+import './coder-pr-loc-stats.css';
+import {onAbort} from 'abort-utils';
+import React from 'dom-chef';
+import * as pageDetect from 'github-url-detection';
+import {stringToUint8Array, uint8ArrayToHex} from 'uint8array-extras';
+
+import features from '../feature-manager.js';
+import api from '../github-helpers/api.js';
+import {getConversationNumber, getRepo} from '../github-helpers/index.js';
+import {
+ categorizeCoderFile,
+ coderFileCategories,
+ type CoderFileCategory,
+ type GitattributesRule,
+ parseGitattributes,
+} from '../helpers/coder-pr-file-categories.js';
+
+type PrFile = {
+ filename: string;
+ previous_filename?: string;
+ additions: number;
+ deletions: number;
+};
+
+type CategoryStats = {
+ files: number;
+ additions: number;
+ deletions: number;
+ diffIds: string[];
+};
+
+const categoryLabels: Record| Show | +Files | +Added | +Deleted | +
|---|