Skip to content

Commit b84cad7

Browse files
committed
feat(ui): add log level selector and dynamic version display
Users can now change log levels without navigating to the full settings page. The version number is injected at build time from package.json, ensuring the displayed version always matches the actual package version without manual updates. The __APP_VERSION__ constant is defined globally via Vite's define configuration and declared in TypeScript types.
1 parent 9084947 commit b84cad7

File tree

6 files changed

+67
-4
lines changed

6 files changed

+67
-4
lines changed

src/options/options.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ <h2>Advanced</h2>
203203
<button id="btn-save" class="primary-button">Save Changes</button>
204204
<span id="save-status" class="save-status"></span>
205205
</div>
206-
<p class="version">MDView v1.0.0</p>
206+
<p class="version" id="app-version">MDView v1.0.0</p>
207207
</footer>
208208
</div>
209209

src/options/options.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,24 @@ class OptionsManager {
3131
// Setup storage listener
3232
this.setupStorageListener();
3333

34+
// Set version
35+
this.setAppVersion();
36+
3437
debug.log('Options', 'Initialized');
3538
}
3639

40+
private setAppVersion(): void {
41+
const versionElement = document.getElementById('app-version');
42+
if (versionElement) {
43+
// __APP_VERSION__ is injected by Vite at build time
44+
try {
45+
versionElement.textContent = `MDView v${__APP_VERSION__}`;
46+
} catch (e) {
47+
debug.warn('Options', 'Failed to set app version:', e);
48+
}
49+
}
50+
}
51+
3752
private setupStorageListener(): void {
3853
chrome.storage.onChanged.addListener((changes, areaName) => {
3954
if (areaName === 'sync' && changes.preferences) {

src/popup/popup.html

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,18 @@ <h1>MDView</h1>
2929
</select>
3030
</section>
3131

32+
<!-- Log Level Selection -->
33+
<section class="setting-section">
34+
<label for="log-level-select" class="setting-label">Log Level</label>
35+
<select id="log-level-select" class="theme-select">
36+
<option value="none">None</option>
37+
<option value="error">Error</option>
38+
<option value="warn">Warning</option>
39+
<option value="info">Info</option>
40+
<option value="debug">Debug</option>
41+
</select>
42+
</section>
43+
3244
<!-- Quick Toggles -->
3345
<section class="setting-section">
3446
<div class="toggle-group">
@@ -78,7 +90,7 @@ <h1>MDView</h1>
7890
</main>
7991

8092
<footer class="popup-footer">
81-
<p class="version">Version 1.0.0</p>
93+
<p class="version" id="app-version">Version 1.0.0</p>
8294
</footer>
8395
</div>
8496

src/popup/popup.ts

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* Manages popup UI and interactions
44
*/
55

6-
import type { AppState, ThemeName } from '../types';
6+
import type { AppState, ThemeName, LogLevel } from '../types';
77
import { debug } from '../utils/debug-logger';
88

99
class PopupManager {
@@ -24,9 +24,25 @@ class PopupManager {
2424
// Setup storage listener
2525
this.setupStorageListener();
2626

27+
// Set version
28+
this.setAppVersion();
29+
2730
debug.log('Popup', 'Initialized');
2831
}
2932

33+
private setAppVersion(): void {
34+
const versionElement = document.getElementById('app-version');
35+
if (versionElement) {
36+
// __APP_VERSION__ is injected by Vite at build time
37+
try {
38+
versionElement.textContent = `Version ${__APP_VERSION__}`;
39+
} catch (e) {
40+
// Fallback if define replacement fails (e.g. in some dev environments)
41+
debug.warn('Popup', 'Failed to set app version:', e);
42+
}
43+
}
44+
}
45+
3046
private setupStorageListener(): void {
3147
chrome.storage.onChanged.addListener((changes, areaName) => {
3248
if (areaName === 'sync' && changes.preferences) {
@@ -87,6 +103,12 @@ class PopupManager {
87103
if (syncTabs) {
88104
syncTabs.checked = preferences.syncTabs;
89105
}
106+
107+
// Update log level select
108+
const logLevelSelect = document.getElementById('log-level-select') as HTMLSelectElement;
109+
if (logLevelSelect) {
110+
logLevelSelect.value = preferences.logLevel || 'error';
111+
}
90112
}
91113

92114
private setupEventListeners(): void {
@@ -156,6 +178,15 @@ class PopupManager {
156178
});
157179
}
158180

181+
// Log level select
182+
const logLevelSelect = document.getElementById('log-level-select');
183+
if (logLevelSelect) {
184+
logLevelSelect.addEventListener('change', (e) => {
185+
const target = e.target as HTMLSelectElement;
186+
void this.handlePreferenceChange({ logLevel: target.value as LogLevel });
187+
});
188+
}
189+
159190
// Settings button
160191
const btnSettings = document.getElementById('btn-settings');
161192
if (btnSettings) {

src/types/index.d.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
* Global window extensions
55
*/
66
declare global {
7+
const __APP_VERSION__: string;
8+
79
interface Window {
810
__MDVIEW_MERMAID_CODE__?: Map<string, string>;
911
}
@@ -281,4 +283,3 @@ export interface MermaidTaskResult {
281283
svg: string;
282284
id: string;
283285
}
284-

vite.config.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,12 @@ import { defineConfig } from 'vite';
22
import { crx } from '@crxjs/vite-plugin';
33
import { resolve } from 'path';
44
import manifest from './public/manifest.json';
5+
import packageJson from './package.json';
56

67
export default defineConfig({
8+
define: {
9+
__APP_VERSION__: JSON.stringify(packageJson.version),
10+
},
711
plugins: [crx({ manifest })],
812
base: './',
913
resolve: {

0 commit comments

Comments
 (0)