/** * UI Management Module * Handles DOM manipulation and view switching */ class UIManager { constructor() { this.currentFile = null; this.currentHistory = null; this.initializeElements(); } initializeElements() { // Views this.welcomeView = document.getElementById('welcomeView'); this.fileView = document.getElementById('fileView'); this.historyView = document.getElementById('historyView'); this.diffView = document.getElementById('diffView'); // File view elements this.fileName = document.getElementById('fileName'); this.filePath = document.getElementById('filePath'); this.fileContent = document.getElementById('fileContent'); this.historyBtn = document.getElementById('historyBtn'); this.diffBtn = document.getElementById('diffBtn'); // History view elements this.historyContent = document.getElementById('historyContent'); this.backFromHistoryBtn = document.getElementById('backFromHistoryBtn'); // Diff view elements this.rev1Select = document.getElementById('rev1Select'); this.rev2Select = document.getElementById('rev2Select'); this.generateDiffBtn = document.getElementById('generateDiffBtn'); this.diffContent = document.getElementById('diffContent'); this.backFromDiffBtn = document.getElementById('backFromDiffBtn'); // Tree elements this.treeContainer = document.getElementById('treeContainer'); this.refreshBtn = document.getElementById('refreshBtn'); // Status this.status = document.getElementById('status'); } /** * Show a specific view and hide others * @param {HTMLElement} view - View to show */ showView(view) { [this.welcomeView, this.fileView, this.historyView, this.diffView].forEach(v => { if (v) v.classList.add('hidden'); }); if (view) view.classList.remove('hidden'); } /** * Display file content * @param {string} path - File path * @param {string} content - File content */ displayFile(path, content) { this.currentFile = path; this.fileName.textContent = path.split('/').pop(); this.filePath.textContent = path; // Escape HTML and display content const escapedContent = this.escapeHtml(content); this.fileContent.innerHTML = `
${escapedContent}`;
this.showView(this.fileView);
}
/**
* Display file history
* @param {Array} history - Array of revision objects
*/
displayHistory(history) {
this.currentHistory = history;
if (!history || history.length === 0) {
this.historyContent.innerHTML = '${colorizedLines}`;
this.showView(this.diffView);
}
/**
* Populate revision selectors
* @param {Array} history - Array of revision objects
*/
populateRevisionSelectors(history) {
if (!history || history.length === 0) {
this.rev1Select.innerHTML = '';
this.rev2Select.innerHTML = '';
return;
}
const options = history.map(rev =>
``
).join('');
this.rev1Select.innerHTML = options;
this.rev2Select.innerHTML = options;
// Set default selections
if (history.length > 1) {
this.rev1Select.selectedIndex = history.length - 1;
this.rev2Select.selectedIndex = 0;
}
}
/**
* Update status indicator
* @param {string} message - Status message
* @param {string} type - Status type: 'connecting', 'connected', 'error'
*/
updateStatus(message, type = 'connecting') {
this.status.textContent = message;
this.status.className = `status ${type}`;
}
/**
* Show loading state
* @param {string} message - Loading message
*/
showLoading(message = 'Loading...') {
this.fileContent.innerHTML = `