From 5c066c81e417bc37802009b7beaea865d7dad68f Mon Sep 17 00:00:00 2001 From: Filip Christiansen <22807962+filipchristiansen@users.noreply.github.com> Date: Fri, 4 Jul 2025 17:16:31 +0200 Subject: [PATCH 1/2] chore(pre-commit) / refactor(templates): add ESLint hook + remove `result.jinja` * Add `eslint` to `pre-commit` hooks * Remove `result.jinja` * `getFileName` + `toggleFile` moved to `utils.js` * `getFileName` + `toggleFile` moved to `utils.js` * leftover `
You can also replace 'hub' with 'ingest' in any GitHub URL.
- {% include 'components/result.jinja' %} + {{ results_container() }} {% endblock %} diff --git a/src/static/js/git.js b/src/static/js/git.js index 7ddc6a90..8879063b 100644 --- a/src/static/js/git.js +++ b/src/static/js/git.js @@ -1,27 +1,29 @@ - function waitForStars() { return new Promise((resolve) => { const check = () => { - const stars = document.getElementById("github-stars"); - if (stars && stars.textContent !== "0") resolve(); - else setTimeout(check, 10); + const stars = document.getElementById('github-stars'); + + if (stars && stars.textContent !== '0') {resolve();} + else {setTimeout(check, 10);} }; + check(); }); } -document.addEventListener("DOMContentLoaded", () => { - const urlInput = document.getElementById("input_text"); - const form = document.getElementById("ingestForm"); +document.addEventListener('DOMContentLoaded', () => { + const urlInput = document.getElementById('input_text'); + const form = document.getElementById('ingestForm'); if (urlInput && urlInput.value.trim() && form) { - // Wait for stars to be loaded before submitting + // Wait for stars to be loaded before submitting waitForStars().then(() => { - const submitEvent = new SubmitEvent("submit", { + const submitEvent = new SubmitEvent('submit', { cancelable: true, bubbles: true }); - Object.defineProperty(submitEvent, "target", { + + Object.defineProperty(submitEvent, 'target', { value: form, enumerable: true }); diff --git a/src/static/js/git_form.js b/src/static/js/git_form.js index e8eb78b0..217b4b6b 100644 --- a/src/static/js/git_form.js +++ b/src/static/js/git_form.js @@ -1,44 +1,45 @@ // Strike-through / un-strike file lines when the pattern-type menu flips. function changePattern() { - const files = document.getElementsByName("tree-line"); + const files = document.getElementsByName('tree-line'); files.forEach((el) => { - if (el.textContent.includes("Directory structure:")) return; + if (el.textContent.includes('Directory structure:')) {return;} [ - "line-through", - "text-gray-500", - "hover:text-inherit", - "hover:no-underline", - "hover:line-through", - "hover:text-gray-500", + 'line-through', + 'text-gray-500', + 'hover:text-inherit', + 'hover:no-underline', + 'hover:line-through', + 'hover:text-gray-500', ].forEach((cls) => el.classList.toggle(cls)); }); } // Show/hide the Personal-Access-Token section when the “Private repository” checkbox is toggled. function toggleAccessSettings() { - const container = document.getElementById("accessSettingsContainer"); - const examples = document.getElementById("exampleRepositories"); - const show = document.getElementById('showAccessSettings')?.checked; - container?.classList.toggle("hidden", !show); - examples?.classList.toggle("lg:mt-0", show); + const container = document.getElementById('accessSettingsContainer'); + const examples = document.getElementById('exampleRepositories'); + const show = document.getElementById('showAccessSettings')?.checked; + + container?.classList.toggle('hidden', !show); + examples?.classList.toggle('lg:mt-0', show); } -document.addEventListener("DOMContentLoaded", () => { +document.addEventListener('DOMContentLoaded', () => { document - .getElementById("pattern_type") - ?.addEventListener("change", () => changePattern()); + .getElementById('pattern_type') + ?.addEventListener('change', () => changePattern()); document - .getElementById("showAccessSettings") - ?.addEventListener("change", toggleAccessSettings); + .getElementById('showAccessSettings') + ?.addEventListener('change', toggleAccessSettings); - /* 3. Initial UI sync -------------------------------- */ + // Initial UI sync toggleAccessSettings(); changePattern(); - }); +}); // Make them available to existing inline attributes diff --git a/src/static/js/index.js b/src/static/js/index.js index a0a99cc2..0ad44ae8 100644 --- a/src/static/js/index.js +++ b/src/static/js/index.js @@ -1,5 +1,6 @@ function submitExample(repoName) { - const input = document.getElementById("input_text"); + const input = document.getElementById('input_text'); + if (input) { input.value = repoName; input.focus(); diff --git a/src/static/js/navbar.js b/src/static/js/navbar.js index f0db1a37..2e64eab4 100644 --- a/src/static/js/navbar.js +++ b/src/static/js/navbar.js @@ -1,22 +1,26 @@ // Fetch GitHub stars function formatStarCount(count) { - if (count >= 1000) return (count / 1000).toFixed(1) + 'k'; + if (count >= 1000) {return `${ (count / 1000).toFixed(1) }k`;} + return count.toString(); - } +} - async function fetchGitHubStars() { +async function fetchGitHubStars() { try { - const res = await fetch('https://api.github.com/repos/cyclotruc/gitingest'); - if (!res.ok) throw new Error(`${res.status} ${res.statusText}`); - const data = await res.json(); - document.getElementById('github-stars').textContent = + const res = await fetch('https://api.github.com/repos/cyclotruc/gitingest'); + + if (!res.ok) {throw new Error(`${res.status} ${res.statusText}`);} + const data = await res.json(); + + document.getElementById('github-stars').textContent = formatStarCount(data.stargazers_count); } catch (err) { - console.error('Error fetching GitHub stars:', err); - const el = document.getElementById('github-stars').parentElement; - if (el) el.style.display = 'none'; + console.error('Error fetching GitHub stars:', err); + const el = document.getElementById('github-stars').parentElement; + + if (el) {el.style.display = 'none';} } - } +} - // auto-run when script loads - fetchGitHubStars(); +// auto-run when script loads +fetchGitHubStars(); diff --git a/src/static/js/posthog.js b/src/static/js/posthog.js index bffa541b..5945b3cc 100644 --- a/src/static/js/posthog.js +++ b/src/static/js/posthog.js @@ -1,12 +1,13 @@ +/* eslint-disable */ !function (t, e) { - var o, n, p, r; - if (e.__SV) return; // already loaded + let o, n, p, r; + if (e.__SV) {return;} // already loaded window.posthog = e; e._i = []; e.init = function (i, s, a) { function g(t, e) { - var o = e.split("."); + const o = e.split("."); if (o.length === 2) { t = t[o[0]]; e = o[1]; @@ -20,12 +21,12 @@ p.type = "text/javascript"; p.crossOrigin = "anonymous"; p.async = true; - p.src = s.api_host.replace(".i.posthog.com", "-assets.i.posthog.com") + "/static/array.js"; + p.src = `${ s.api_host.replace(".i.posthog.com", "-assets.i.posthog.com") }/static/array.js`; r = t.getElementsByTagName("script")[0]; r.parentNode.insertBefore(p, r); - var u = e; + let u = e; if (a !== undefined) { u = e[a] = []; } else { @@ -34,13 +35,13 @@ u.people = u.people || []; u.toString = function (t) { - var e = "posthog"; - if (a !== "posthog") e += "." + a; - if (!t) e += " (stub)"; + let e = "posthog"; + if (a !== "posthog") {e += `.${ a }`;} + if (!t) {e += " (stub)";} return e; }; u.people.toString = function () { - return u.toString(1) + ".people (stub)"; + return `${ u.toString(1) }.people (stub)`; }; @@ -58,9 +59,9 @@ "createPersonProfile", "opt_in_capturing", "opt_out_capturing", "has_opted_in_capturing", "has_opted_out_capturing", "clear_opt_in_out_capturing", "debug", "getPageViewId" - ]; + ]; - for (n = 0; n < o.length; n++) g(u, o[n]); + for (n = 0; n < o.length; n++) {g(u, o[n]);} e._i.push([i, s, a]); }; diff --git a/src/static/js/utils.js b/src/static/js/utils.js index cbcc0f20..393fe12d 100644 --- a/src/static/js/utils.js +++ b/src/static/js/utils.js @@ -3,19 +3,22 @@ function copyText(className) { let textToCopy; if (className === 'directory-structure') { - // For directory structure, get the hidden input value + // For directory structure, get the hidden input value const hiddenInput = document.getElementById('directory-structure-content'); - if (!hiddenInput) return; + + if (!hiddenInput) {return;} textToCopy = hiddenInput.value; } else { - // For other elements, get the textarea value - const textarea = document.querySelector('.' + className); - if (!textarea) return; + // For other elements, get the textarea value + const textarea = document.querySelector(`.${ className }`); + + if (!textarea) {return;} textToCopy = textarea.value; } const button = document.querySelector(`button[onclick="copyText('${className}')"]`); - if (!button) return; + + if (!button) {return;} // Copy text navigator.clipboard.writeText(textToCopy) @@ -31,9 +34,10 @@ function copyText(className) { button.innerHTML = originalContent; }, 1000); }) - .catch(err => { - // Show error in button + .catch((err) => { + console.error('Failed to copy text:', err); const originalContent = button.innerHTML; + button.innerHTML = 'Failed to copy'; setTimeout(() => { button.innerHTML = originalContent; @@ -41,17 +45,74 @@ function copyText(className) { }); } +function getFileName(element) { + const indentSize = 4; + let path = ''; + let prevIndentLevel = null; + + while (element) { + const line = element.textContent; + const index = line.search(/[a-zA-Z0-9_.-]/); + const indentLevel = index / indentSize; + + // Stop when we reach or go above the top-level directory + if (indentLevel <= 1) { + break; + } + if (prevIndentLevel === null || indentLevel === prevIndentLevel - 1) { + const fileName = line.substring(index).trim(); + + path = fileName + path; + prevIndentLevel = indentLevel; + } + element = element.previousElementSibling; + } + + return path; +} + +function toggleFile(element) { + const patternInput = document.getElementById('pattern'); + const patternFiles = patternInput.value + ? patternInput.value.split(',').map((item) => item.trim()) + : []; + + const directoryContainer = document.getElementById('directory-structure-container'); + const treeLineElements = Array.from(directoryContainer.children).filter( + (child) => child.tagName === 'PRE', + ); + + // Skip header and repository name + if (treeLineElements.slice(0, 2).includes(element)) { + return; + } + + element.classList.toggle('line-through'); + element.classList.toggle('text-gray-500'); + + const fileName = getFileName(element); + const idx = patternFiles.indexOf(fileName); + + if (idx !== -1) { + patternFiles.splice(idx, 1); + } else { + patternFiles.push(fileName); + } + + patternInput.value = patternFiles.join(', '); +} function handleSubmit(event, showLoading = false) { event.preventDefault(); const form = event.target || document.getElementById('ingestForm'); - if (!form) return; + + if (!form) {return;} // Declare resultsSection before use const resultsSection = document.querySelector('[data-results]'); if (resultsSection) { - // Show in-content loading spinner + // Show in-content loading spinner resultsSection.innerHTML = ` elements
const dirPre = document.getElementById('directory-structure-pre');
+
if (dirPre && data.tree) {
dirPre.innerHTML = '';
- data.tree.split('\n').forEach(line => {
+ data.tree.split('\n').forEach((line) => {
const pre = document.createElement('pre');
+
pre.setAttribute('name', 'tree-line');
pre.className = 'cursor-pointer hover:line-through hover:text-gray-500';
pre.textContent = line;
- pre.onclick = function() { toggleFile(this); };
+ pre.onclick = function () { toggleFile(this); };
dirPre.appendChild(pre);
});
}
@@ -209,14 +276,17 @@ function handleSubmit(event, showLoading = false) {
// Scroll to results
resultsSection.scrollIntoView({ behavior: 'smooth', block: 'start' });
})
- .catch(error => {
+ .catch((error) => {
// Hide loading overlay
- if (resultsSection) resultsSection.innerHTML = '';
+ if (resultsSection) {
+ resultsSection.innerHTML = '';
+ }
submitButton.disabled = false;
submitButton.innerHTML = originalContent;
- const resultsSection = document.querySelector('[data-results]');
- if (resultsSection) {
- resultsSection.innerHTML = `${error}`;
+ const errorContainer = document.querySelector('[data-results]');
+
+ if (errorContainer) {
+ errorContainer.innerHTML = `${error}`;
}
});
}
@@ -239,9 +309,10 @@ function copyFullDigest() {
setTimeout(() => {
button.innerHTML = originalText;
}, 2000);
- }).catch(err => {
- console.error('Failed to copy text: ', err);
- });
+ })
+ .catch((err) => {
+ console.error('Failed to copy text: ', err);
+ });
}
function downloadFullDigest() {
@@ -258,8 +329,9 @@ function downloadFullDigest() {
// Create a download link
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
+
a.href = url;
- a.download = 'codebase-digest.txt';
+ a.download = 'digest.txt';
document.body.appendChild(a);
a.click();
@@ -288,7 +360,8 @@ function logSliderToSize(position) {
const maxPosition = 500;
const maxValue = Math.log(102400); // 100 MB
- const value = Math.exp(maxValue * Math.pow(position / maxPosition, 1.5));
+ const value = Math.exp(maxValue * (position / maxPosition)**1.5);
+
return Math.round(value);
}
@@ -297,10 +370,11 @@ function initializeSlider() {
const slider = document.getElementById('file_size');
const sizeValue = document.getElementById('size_value');
- if (!slider || !sizeValue) return;
+ if (!slider || !sizeValue) {return;}
function updateSlider() {
const value = logSliderToSize(slider.value);
+
sizeValue.textContent = formatSize(value);
slider.style.backgroundSize = `${(slider.value / slider.max) * 100}% 100%`;
}
@@ -315,24 +389,18 @@ function initializeSlider() {
// Add helper function for formatting size
function formatSize(sizeInKB) {
if (sizeInKB >= 1024) {
- return Math.round(sizeInKB / 1024) + 'MB';
+ return `${ Math.round(sizeInKB / 1024) }MB`;
}
- return Math.round(sizeInKB) + 'kB';
-}
-// Make sure these are available globally
-window.copyText = copyText;
-
-window.handleSubmit = handleSubmit;
-window.initializeSlider = initializeSlider;
-window.formatSize = formatSize;
-window.downloadFullDigest = downloadFullDigest;
+ return `${ Math.round(sizeInKB) }kB`;
+}
// Add this new function
function setupGlobalEnterHandler() {
- document.addEventListener('keydown', function (event) {
+ document.addEventListener('keydown', (event) => {
if (event.key === 'Enter' && !event.target.matches('textarea')) {
const form = document.getElementById('ingestForm');
+
if (form) {
handleSubmit(new Event('submit'), true);
}
@@ -345,3 +413,11 @@ document.addEventListener('DOMContentLoaded', () => {
initializeSlider();
setupGlobalEnterHandler();
});
+
+
+// Make sure these are available globally
+window.handleSubmit = handleSubmit;
+window.toggleFile = toggleFile;
+window.copyText = copyText;
+window.copyFullDigest = copyFullDigest;
+window.downloadFullDigest = downloadFullDigest;
From edfd88dd609637ab9186dfbc03c9b77586ddbf11 Mon Sep 17 00:00:00 2001
From: Filip Christiansen <22807962+filipchristiansen@users.noreply.github.com>
Date: Fri, 4 Jul 2025 17:32:17 +0200
Subject: [PATCH 2/2] pr fix
---
src/server/templates/components/_macros.jinja | 4 ----
src/server/templates/components/result.jinja | 1 +
src/server/templates/git.jinja | 3 +--
src/server/templates/index.jinja | 3 +--
4 files changed, 3 insertions(+), 8 deletions(-)
create mode 100644 src/server/templates/components/result.jinja
diff --git a/src/server/templates/components/_macros.jinja b/src/server/templates/components/_macros.jinja
index 3a565199..224fcbba 100644
--- a/src/server/templates/components/_macros.jinja
+++ b/src/server/templates/components/_macros.jinja
@@ -8,7 +8,3 @@
{{ label }}
{%- endmacro %}
-{# Results container (empty - JS will populate it) #}
-{% macro results_container() -%}
-
-{%- endmacro %}
diff --git a/src/server/templates/components/result.jinja b/src/server/templates/components/result.jinja
new file mode 100644
index 00000000..a5a0a803
--- /dev/null
+++ b/src/server/templates/components/result.jinja
@@ -0,0 +1 @@
+
diff --git a/src/server/templates/git.jinja b/src/server/templates/git.jinja
index fedd8e94..9d5fe653 100644
--- a/src/server/templates/git.jinja
+++ b/src/server/templates/git.jinja
@@ -1,5 +1,4 @@
{% extends "base.jinja" %}
-{% from 'components/_macros.jinja' import results_container %}
{% block content %}
{% if error_message %}
@@ -26,5 +25,5 @@
You can also replace 'hub' with 'ingest' in any GitHub URL.
- {{ results_container() }}
+ {% include 'components/result.jinja' %}
{% endblock %}