This commit is contained in:
Isaac Johnson 2026-06-01 18:20:58 -05:00
parent 0c0b605610
commit d3676e635f
2 changed files with 81 additions and 2 deletions

View File

@ -139,6 +139,49 @@ export async function fetchIssues(
} }
} }
/**
* Fetches a single issue by number.
*/
export async function fetchIssue(
config: Config,
issueNumber: number
): Promise<Issue> {
const client = createAxiosInstance(config);
try {
const response = await client.get(`/repos/${config.owner}/${config.repo}/issues/${issueNumber}`);
const item = response.data;
return {
id: item.id,
number: item.number,
title: item.title,
state: item.state,
body: item.body || '',
user: {
id: item.user?.id || 0,
login: item.user?.login || 'unknown',
full_name: item.user?.full_name || '',
},
created_at: item.created_at,
updated_at: item.updated_at,
comments: item.comments_count || item.comments || 0,
labels: (item.labels || []).map((l: any) => ({
id: l.id,
name: l.name,
color: l.color,
})),
pull_request: item.pull_request,
};
} catch (error: any) {
if (error.response) {
if (error.response.status === 401) {
throw new Error('Unauthorized: Please check your token.');
}
throw new Error(`Failed to fetch issue: ${error.response.data?.message || error.message}`);
}
throw new Error(`Network Error: ${error.message}`);
}
}
/** /**
* Fetches comments for a specific issue. * Fetches comments for a specific issue.
*/ */

View File

@ -1,7 +1,7 @@
import readline from 'readline'; import readline from 'readline';
import chalk from 'chalk'; import chalk from 'chalk';
import { AppState, Issue, Comment } from './types.js'; import { AppState, Issue, Comment } from './types.js';
import { fetchIssues, fetchIssueComments, validateConnection, normalizeUrl, authenticateAndFetchRepos, createIssue, createIssueComment, editIssue } from './api.js'; import { fetchIssues, fetchIssue, fetchIssueComments, validateConnection, normalizeUrl, authenticateAndFetchRepos, createIssue, createIssueComment, editIssue } from './api.js';
import { saveGlobalConfig } from './config.js'; import { saveGlobalConfig } from './config.js';
// Setup readline for stdin keypress events // Setup readline for stdin keypress events
@ -198,6 +198,35 @@ export class TuiEngine {
} }
} }
/**
* Fetches the current single issue and its comments again.
*/
private async reloadSingleIssue() {
if (!this.state.selectedIssue) return;
this.state.loading = true;
this.state.error = null;
this.startSpinner();
try {
const issue = await fetchIssue(this.state.config, this.state.selectedIssue.number);
this.state.selectedIssue = issue;
// Update in the main list as well
const listIndex = this.state.issues.findIndex(i => i.number === issue.number);
if (listIndex !== -1) {
this.state.issues[listIndex] = issue;
}
await this.loadComments(issue);
} catch (err: any) {
this.state.error = `Failed to reload issue: ${err.message}`;
} finally {
this.state.loading = false;
this.stopSpinner();
this.render();
}
}
/** /**
* Fetches comments for the selected issue. * Fetches comments for the selected issue.
*/ */
@ -691,6 +720,13 @@ export class TuiEngine {
return; return;
} }
if (str === 'r' || str === 'R') {
if (this.state.selectedIssue) {
this.reloadSingleIssue();
}
return;
}
if ((key && (key.name === 'escape' || key.name === 'backspace')) || str === '\u001b' || str === 'q' || str === 'Q') { if ((key && (key.name === 'escape' || key.name === 'backspace')) || str === '\u001b' || str === 'q' || str === 'Q') {
this.state.screen = 'list'; this.state.screen = 'list';
this.state.selectedIssue = null; this.state.selectedIssue = null;
@ -1124,7 +1160,7 @@ export class TuiEngine {
scrollHelp += chalk.yellow(` (${pct}%)`); scrollHelp += chalk.yellow(` (${pct}%)`);
} }
const helpLine = chalk.gray(` [Esc/Backspace] Back to List [C] Add Comment [E] Edit [O] Settings ${scrollHelp}`); const helpLine = chalk.gray(` [Esc/Backspace] Back to List [C] Add Comment [E] Edit [R] Reload [O] Settings ${scrollHelp}`);
process.stdout.write(helpLine); process.stdout.write(helpLine);
} }