Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
.vscode/
node_modules/
dist/
logs/
*.vsix
.DS_Store
filter_exception_decoder.py
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## [0.26.5] - 2026-05-xx

### New Feature**
- **Filter save** - operations now provide visual feedback to users, confirming successful saves with "Saved ✓" messages or displaying error details if an issue occurs.
- Save button shows a disabled state while processing and displays timed feedback that clearly indicates whether the operation succeeded or failed.

## [0.26.4] - 2026-05-18

### Changed
Expand Down
74 changes: 67 additions & 7 deletions src/webviewPanel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -471,12 +471,21 @@ export class EspDecoderWebviewPanel implements vscode.WebviewViewProvider {
this.crashCapturer.reset();
break;
case 'saveFilters': {
const cfg = vscode.workspace.getConfiguration('esp-decoder');
await cfg.update('serialFilters.timestamp', message.timestamp, vscode.ConfigurationTarget.Global);
await cfg.update('serialFilters.suppressPattern', message.suppressPattern, vscode.ConfigurationTarget.Global);
await cfg.update('serialFilters.highlightPattern', message.highlightPattern, vscode.ConfigurationTarget.Global);
await cfg.update('serialFilters.dedupPattern', message.dedupPattern, vscode.ConfigurationTarget.Global);
await cfg.update('serialFilters.dedupThreshold', message.dedupThreshold, vscode.ConfigurationTarget.Global);
try {
const cfg = vscode.workspace.getConfiguration('esp-decoder');
await cfg.update('serialFilters.timestamp', message.timestamp, vscode.ConfigurationTarget.Global);
await cfg.update('serialFilters.suppressPattern', message.suppressPattern, vscode.ConfigurationTarget.Global);
await cfg.update('serialFilters.highlightPattern', message.highlightPattern, vscode.ConfigurationTarget.Global);
await cfg.update('serialFilters.dedupPattern', message.dedupPattern, vscode.ConfigurationTarget.Global);
await cfg.update('serialFilters.dedupThreshold', message.dedupThreshold, vscode.ConfigurationTarget.Global);
this.postMessage({ type: 'filtersSaved', ok: true });
} catch (err) {
this.postMessage({
type: 'filtersSaved',
ok: false,
error: err instanceof Error ? err.message : String(err),
});
}
break;
}
case 'decodeCrash': {
Expand Down Expand Up @@ -1309,6 +1318,16 @@ export class EspDecoderWebviewPanel implements vscode.WebviewViewProvider {
border-color: var(--error-fg);
}
.filter-toolbar .filter-label { opacity: 0.6; }
button.feedback-saved {
background: var(--vscode-testing-iconPassed, #28a745) !important;
color: var(--vscode-button-foreground);
transition: background 0.2s ease;
}
button.feedback-error {
background: var(--error-fg, #d73a49) !important;
color: var(--vscode-button-foreground);
transition: background 0.2s ease;
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
.filter-toolbar button.log-active {
background: var(--success-fg);
color: #000;
Expand Down Expand Up @@ -2133,7 +2152,45 @@ export class EspDecoderWebviewPanel implements vscode.WebviewViewProvider {
filterState.dedupThreshold = (isNaN(v) || v < 1) ? 3 : v;
});

document.getElementById('filter-save').addEventListener('click', () => {
var filterSaveBtn = document.getElementById('filter-save');
var filterSaveOriginalLabel = filterSaveBtn.textContent;
var filterSaveFeedbackTimer = null;
var filterSaveTimeout = null;
function showFilterSaveFeedback(ok, errorText) {
if (filterSaveTimeout) {
clearTimeout(filterSaveTimeout);
filterSaveTimeout = null;
}
if (filterSaveFeedbackTimer) {
clearTimeout(filterSaveFeedbackTimer);
filterSaveFeedbackTimer = null;
}
filterSaveBtn.classList.remove('feedback-saved', 'feedback-error');
if (ok) {
filterSaveBtn.classList.add('feedback-saved');
filterSaveBtn.textContent = 'Saved \u2713';
} else {
filterSaveBtn.classList.add('feedback-error');
filterSaveBtn.textContent = 'Failed';
if (errorText) { filterSaveBtn.title = 'Save failed: ' + errorText; }
}
filterSaveFeedbackTimer = setTimeout(function() {
filterSaveBtn.classList.remove('feedback-saved', 'feedback-error');
filterSaveBtn.textContent = filterSaveOriginalLabel;
filterSaveBtn.title = 'Save current filter settings to VS Code settings';
filterSaveBtn.disabled = false;
filterSaveFeedbackTimer = null;
}, 1500);
}
filterSaveBtn.addEventListener('click', () => {
filterSaveBtn.disabled = true;
if (filterSaveTimeout) {
clearTimeout(filterSaveTimeout);
}
filterSaveTimeout = setTimeout(function() {
filterSaveTimeout = null;
showFilterSaveFeedback(false, 'No response from extension');
}, 5000);
vscode.postMessage({
type: 'saveFilters',
timestamp: filterState.timestamp,
Expand Down Expand Up @@ -2382,6 +2439,9 @@ export class EspDecoderWebviewPanel implements vscode.WebviewViewProvider {
case 'error':
appendError(msg.message);
break;
case 'filtersSaved':
showFilterSaveFeedback(msg.ok !== false, msg.error);
break;
}
});

Expand Down