Home's feedback band ends with "⭐ Star on GitHub" and Settings -> Help and feedback has a "Star it on GitHub" row; both open the project page in a new tab (feedback.js openRepoPage). No pop-up, no reminder and no request is made: the page opens only when pressed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
99 lines
4.5 KiB
JavaScript
99 lines
4.5 KiB
JavaScript
/**
|
|
* Feedback on GitHub: what was written in the feedback window (ui_feedback_dialog.js)
|
|
* opens as a new issue in the browser's language, with the environment folded at the end,
|
|
* and the same environment can be copied for other channels.
|
|
* The environment is versions and hardware only (plugin, ComfyUI, Python, PyTorch, GPU,
|
|
* browser, page, language): never a path, a file name or ComfyUI's command line.
|
|
* Nothing is sent anywhere; the person reads it in the issue before posting.
|
|
*/
|
|
|
|
import { isTtsInstalled } from './audio_engines.js';
|
|
import { translate } from './locales.js';
|
|
|
|
const t = (key, params) => translate(key, params);
|
|
|
|
const REPO = 'https://github.com/DemonGatanjieu/Anomalous_Model_Browser';
|
|
|
|
/** The project page, where a Star helps others find the browser. Opened only on a press; nothing is fetched. */
|
|
export function openRepoPage() {
|
|
window.open(REPO, '_blank', 'noopener');
|
|
}
|
|
|
|
async function fetchJson(url) {
|
|
try {
|
|
const res = await fetch(url);
|
|
return res.ok ? await res.json() : null;
|
|
} catch {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/** "Chrome 141" / "Edge 140" / "Firefox 133" from the user agent, or the agent's last word. */
|
|
function browserName() {
|
|
const agent = navigator.userAgent || '';
|
|
for (const [name, pattern] of [['Edge', /Edg\/(\d+)/], ['Firefox', /Firefox\/(\d+)/], ['Chrome', /Chrome\/(\d+)/], ['Safari', /Version\/(\d+).*Safari/]]) {
|
|
const match = pattern.exec(agent);
|
|
if (match) return `${name} ${match[1]}`;
|
|
}
|
|
return agent.split(' ').pop() || 'unknown';
|
|
}
|
|
|
|
function gigabytes(bytes) {
|
|
return bytes ? `${Math.round(bytes / 1024 ** 3)} GB` : '';
|
|
}
|
|
|
|
/** The environment as lines of "name: value", for an issue or a chat. */
|
|
export async function collectDiagnostics(owner) {
|
|
const [version, stats, tts] = await Promise.all([
|
|
fetchJson('/anomalous/version'), fetchJson('/system_stats'), isTtsInstalled().catch(() => false),
|
|
]);
|
|
const state = version?.state || {};
|
|
const system = stats?.system || {};
|
|
const device = stats?.devices?.[0];
|
|
// "cuda:0 NVIDIA GeForce RTX 4050 Laptop GPU : cudaMallocAsync" -> the card's name.
|
|
const gpu = device ? String(device.name || '').replace(/^\S+:\d+\s+/, '').replace(/\s+:\s+\S+$/, '') : '';
|
|
const plugin = [state.label || state.tag || state.commit || 'unknown', state.branch && state.branch !== 'main' ? `(${state.branch})` : '',
|
|
state.dirty ? '(modified)' : ''].filter(Boolean).join(' ');
|
|
const lines = [
|
|
['Anomalous Model Browser', plugin],
|
|
['ComfyUI', [system.comfyui_version, window.__COMFYUI_FRONTEND_VERSION__ && `frontend ${window.__COMFYUI_FRONTEND_VERSION__}`].filter(Boolean).join(' · ')],
|
|
['Python / PyTorch', [String(system.python_version || '').split(' ')[0], system.pytorch_version].filter(Boolean).join(' / ')],
|
|
['GPU', [gpu, gigabytes(device?.vram_total)].filter(Boolean).join(' · ')],
|
|
['RAM', gigabytes(system.ram_total)],
|
|
['OS / Browser', [system.os, browserName()].filter(Boolean).join(' / ')],
|
|
['Anomalous_TTS', tts ? 'installed' : 'not installed'],
|
|
['Page / language', [owner?.currentShellPage?.(), window.anomalous_browser_lang].filter(Boolean).join(' / ')],
|
|
];
|
|
return lines.filter(([, value]) => value).map(([name, value]) => `- ${name}: ${value}`).join('\n');
|
|
}
|
|
|
|
/** "[Bug] the first words of what was written", short enough for a list of issues. */
|
|
function issueTitle(kind, text) {
|
|
const first = String(text || '').trim().split('\n')[0].trim();
|
|
const short = first.length > 60 ? `${first.slice(0, 59)}…` : first;
|
|
return `${t(kind === 'bug' ? 'feedbackIssueBugPrefix' : 'feedbackIssueIdeaPrefix')}${short}`;
|
|
}
|
|
|
|
/**
|
|
* Opens a new GitHub issue with what was written, in the browser's language; the
|
|
* environment, when attached, is folded at the end so the issue reads as the person wrote it.
|
|
*/
|
|
export async function openIssue(owner, kind, text, { environment = true } = {}) {
|
|
const parts = [String(text || '').trim()];
|
|
if (environment) {
|
|
parts.push('', `<details><summary>${t('feedbackIssueEnvironment')}</summary>`, '', await collectDiagnostics(owner), '', '</details>');
|
|
}
|
|
const query = new URLSearchParams({ title: issueTitle(kind, text), body: parts.join('\n') });
|
|
window.open(`${REPO}/issues/new?${query}`, '_blank', 'noopener');
|
|
}
|
|
|
|
/** Copies the environment; true when it reached the clipboard. */
|
|
export async function copyDiagnostics(owner) {
|
|
try {
|
|
await navigator.clipboard.writeText(await collectDiagnostics(owner));
|
|
return true;
|
|
} catch {
|
|
return false;
|
|
}
|
|
}
|