Dropdown cleanup + bounce marker polish + auto popup title (v1.10.2)

- Removed "Test connection" item from the browse settings dropdown
  (chrome+firefox HTML + JS handler). Available in Advanced Options.

- Model column "*" bounce marker:
  - Color now matches the badge per family (sonnet/opus/haiku/default)
    instead of always rendering var(--badge-default) at 0.7 opacity.
  - Tooltip on the bounced cell now fires when hovering EITHER the
    badge or the asterisk: wrapped both in a .model-cell span that
    carries the title + cursor: help.

- Popup header (#header-title) is now populated from manifest.name in
  popup.js — testing branch's "Claude Exporter Beta" surfaces in the
  popup automatically without a separate HTML edit per branch.

- src/CLAUDE.md extended the existing manifest-name rule to note that
  popup.js reads manifest.name into #header-title. (Workspace-root
  CLAUDE.md was mirrored locally but isn't tracked in git.)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
tux tucker 2026-05-18 18:52:17 -04:00
parent 02ade4b896
commit 85da733d62
10 changed files with 44 additions and 61 deletions

View file

@ -89,6 +89,8 @@ Any export producing more than one file should always create a ZIP — never tri
- `"Claude Exporter"` on the `main` branch (released version)
- `"Claude Exporter Beta"` on the `testing` branch (so the user can tell at a glance which build is loaded)
The popup header title is populated from `manifest.name` in `popup.js` (`#header-title`), so the popup automatically reads "Claude Exporter Beta" on the testing branch — no separate HTML edit needed.
When merging `testing``main` for a release, flip both manifest names to drop "Beta" as part of the merge.
## Testing

View file

@ -577,7 +577,15 @@
margin-left: 4px;
font-size: 12px;
color: var(--badge-default);
opacity: 0.7;
}
.model-bounced.sonnet { color: var(--badge-sonnet); }
.model-bounced.haiku { color: var(--badge-haiku); }
.model-bounced.opus { color: var(--badge-opus); }
/* Wrapper that carries the tooltip + cursor so hover works on the badge or asterisk */
.model-cell {
display: inline-block;
cursor: help;
}
@ -779,11 +787,6 @@
<span class="settings-label">Advanced Options</span>
<span class="settings-value">&#8594;</span>
</div>
<div class="settings-divider"></div>
<div class="settings-item" id="testConnection">
<span class="settings-label">Test connection</span>
<span class="settings-value" id="connectionStatus"></span>
</div>
<input type="file" id="restoreFileBrowse" accept="application/json,.json" style="display: none;">
</div>
</div>

View file

@ -89,7 +89,7 @@ function getDisplayModel(conv) {
return {
model: useCurrent ? current : original,
other: useCurrent ? original : current,
otherLabel: useCurrent ? 'Originally' : 'Now using',
otherLabel: useCurrent ? 'Originally' : 'Currently',
bounced
};
}
@ -472,9 +472,10 @@ function displayConversations() {
<td class="date">${escapeHtml(updatedDate)}<br><span class="time">${escapeHtml(updatedTime)}</span></td>
<td class="date">${escapeHtml(createdDate)}<br><span class="time">${escapeHtml(createdTime)}</span></td>
<td>
<span class="model-badge ${modelBadgeClass}">
${escapeHtml(formatModelName(modelInfo.model))}
</span>${modelInfo.bounced ? `<span class="model-bounced" title="${modelInfo.otherLabel} ${escapeHtml(formatModelName(modelInfo.other))}">*</span>` : ''}
${modelInfo.bounced
? `<span class="model-cell" title="${modelInfo.otherLabel} ${escapeHtml(formatModelName(modelInfo.other))}"><span class="model-badge ${modelBadgeClass}">${escapeHtml(formatModelName(modelInfo.model))}</span><span class="model-bounced ${modelBadgeClass}">*</span></span>`
: `<span class="model-badge ${modelBadgeClass}">${escapeHtml(formatModelName(modelInfo.model))}</span>`
}
</td>
<td>
<div class="actions">
@ -1213,25 +1214,6 @@ function setupEventListeners() {
settingsDropdown.classList.remove('open');
});
// Test connection
document.getElementById('testConnection').addEventListener('click', async () => {
const statusEl = document.getElementById('connectionStatus');
statusEl.textContent = 'Testing...';
try {
const response = await sendMessageToClaudeTab('loadConversations', { orgId });
if (response && response.success) {
statusEl.textContent = `OK (${response.conversations.length})`;
statusEl.style.color = '#22c55e';
} else {
statusEl.textContent = 'Failed';
statusEl.style.color = '#ef4444';
}
} catch (e) {
statusEl.textContent = 'Error';
statusEl.style.color = '#ef4444';
}
});
// Search input
const searchInput = document.getElementById('searchInput');
searchInput.addEventListener('input', (e) => {

View file

@ -1,7 +1,7 @@
{
"manifest_version": 3,
"name": "Claude Exporter Beta",
"version": "1.10.1",
"version": "1.10.2",
"description": "Export conversations and artifacts from Claude.ai",
"permissions": [
"activeTab",

View file

@ -35,8 +35,10 @@ async function getOrgId() {
}
document.addEventListener('DOMContentLoaded', async () => {
// Display version from manifest
// Pull the popup title + version from the manifest so the testing branch
// shows "Claude Exporter Beta" without a separate HTML edit.
const manifest = chrome.runtime.getManifest();
document.getElementById('header-title').textContent = manifest.name;
document.getElementById('header-version').textContent = `v${manifest.version}`;
// Handle checkbox dependencies

View file

@ -1,5 +1,12 @@
# Changelog
## [1.10.2]
- Removed "Test connection" from the browse settings dropdown — it's already available in Advanced Options (next to Save Settings)
- Model column "*" bounce marker now matches the badge color per family (Sonnet/Opus/Haiku/default), full opacity
- Tooltip on bounced model cells now fires when hovering the badge or the asterisk (wrapped in a `.model-cell` with the `title` attribute)
- Popup header title is now read from `manifest.name`, so the testing branch's "Claude Exporter Beta" appears in the popup automatically. CLAUDE.md updated.
## [1.10.1]
- Browse page funnel menu: new "Search projects" option (below the existing status filters, separated by a divider). When selected, the search bar matches against project names (placeholder updates to "Search projects by name...") and the table shows conversations whose project name matches. Status filters do not apply in this mode.

View file

@ -577,7 +577,15 @@
margin-left: 4px;
font-size: 12px;
color: var(--badge-default);
opacity: 0.7;
}
.model-bounced.sonnet { color: var(--badge-sonnet); }
.model-bounced.haiku { color: var(--badge-haiku); }
.model-bounced.opus { color: var(--badge-opus); }
/* Wrapper that carries the tooltip + cursor so hover works on the badge or asterisk */
.model-cell {
display: inline-block;
cursor: help;
}
@ -780,11 +788,6 @@
<span class="settings-label">Advanced Options</span>
<span class="settings-value">&#8594;</span>
</div>
<div class="settings-divider"></div>
<div class="settings-item" id="testConnection">
<span class="settings-label">Test connection</span>
<span class="settings-value" id="connectionStatus"></span>
</div>
<input type="file" id="restoreFileBrowse" accept="application/json,.json" style="display: none;">
</div>
</div>

View file

@ -472,9 +472,10 @@ function displayConversations() {
<td class="date">${escapeHtml(updatedDate)}<br><span class="time">${escapeHtml(updatedTime)}</span></td>
<td class="date">${escapeHtml(createdDate)}<br><span class="time">${escapeHtml(createdTime)}</span></td>
<td>
<span class="model-badge ${modelBadgeClass}">
${escapeHtml(formatModelName(modelInfo.model))}
</span>${modelInfo.bounced ? `<span class="model-bounced" title="${modelInfo.otherLabel} ${escapeHtml(formatModelName(modelInfo.other))}">*</span>` : ''}
${modelInfo.bounced
? `<span class="model-cell" title="${modelInfo.otherLabel} ${escapeHtml(formatModelName(modelInfo.other))}"><span class="model-badge ${modelBadgeClass}">${escapeHtml(formatModelName(modelInfo.model))}</span><span class="model-bounced ${modelBadgeClass}">*</span></span>`
: `<span class="model-badge ${modelBadgeClass}">${escapeHtml(formatModelName(modelInfo.model))}</span>`
}
</td>
<td>
<div class="actions">
@ -1212,25 +1213,6 @@ function setupEventListeners() {
settingsDropdown.classList.remove('open');
});
// Test connection
document.getElementById('testConnection').addEventListener('click', async () => {
const statusEl = document.getElementById('connectionStatus');
statusEl.textContent = 'Testing...';
try {
const response = await sendMessageToClaudeTab('loadConversations', { orgId });
if (response && response.success) {
statusEl.textContent = `OK (${response.conversations.length})`;
statusEl.style.color = '#22c55e';
} else {
statusEl.textContent = 'Failed';
statusEl.style.color = '#ef4444';
}
} catch (e) {
statusEl.textContent = 'Error';
statusEl.style.color = '#ef4444';
}
});
// Search input
const searchInput = document.getElementById('searchInput');
searchInput.addEventListener('input', (e) => {

View file

@ -1,7 +1,7 @@
{
"manifest_version": 2,
"name": "Claude Exporter Beta",
"version": "1.10.1",
"version": "1.10.2",
"description": "Export conversations and artifacts from Claude.ai",
"permissions": [
"activeTab",

View file

@ -35,8 +35,10 @@ async function getOrgId() {
}
document.addEventListener('DOMContentLoaded', async () => {
// Display version from manifest
// Pull the popup title + version from the manifest so the testing branch
// shows "Claude Exporter Beta" without a separate HTML edit.
const manifest = chrome.runtime.getManifest();
document.getElementById('header-title').textContent = manifest.name;
document.getElementById('header-version').textContent = `v${manifest.version}`;
// Handle checkbox dependencies