Both band maps were pinned to a hardcoded width — 300px docked beside the tables, 260px per card in the Band map tab. On a busy band the map could not be given more room, and on a quiet one the log could not take it back. The docked map becomes a resizable grid column with the grip in the gap between the panes, so the handle costs no space; the tab cards share one width with the grip on their right edge. Side-by-side columns of different widths read as a mistake rather than a choice, which is why the tab has one width and not one per card. Double-click either grip to return to the default. The drag measures from the pointer's START position rather than the container, so the same helper serves both edges — the docked map sits on the left or the right depending on the operator's setting, and the grip is on its inner edge either way. Pointer capture, like the main splitter: without it the map or the grid under the cursor swallows the moves. Both widths are persisted through writeUiPref and registered as portable, so they travel with the data folder like the main splitter and the rest of the layout.
81 lines
4.8 KiB
TypeScript
81 lines
4.8 KiB
TypeScript
// Portable UI preferences.
|
|
//
|
|
// A handful of small UI prefs historically lived only in the WebView's
|
|
// localStorage, so they did NOT travel when the operator copied the OpsLog
|
|
// folder (data/) to another machine. These helpers mirror them into the DB
|
|
// settings table (ui.* keys, like the grid columns) so the whole setup is
|
|
// identical after a copy.
|
|
import { GetUIPref, SetUIPref, LogUIError } from '../../wailsjs/go/main/App';
|
|
|
|
// Keys that must travel with data/ (DB is the portable source of truth; the
|
|
// localStorage copy is just a fast, synchronous cache).
|
|
const PORTABLE_KEYS = [
|
|
'opslog.theme', // UI colour theme (light-warm / dark-warm / graphite / high-contrast / auto)
|
|
'hamlog.qsoLimit', // QSO list page size
|
|
'bandmap.side', // band map docked left / right
|
|
'bandmap.show', // band map open / closed
|
|
'opslog.autofocusWB', // auto-focus Worked-before
|
|
'hamlog.filterPresets', // Filter Builder saved presets
|
|
'opslog.showRotor', // rotor compass shown next to the keyers
|
|
'opslog.showAmpWidget', // amplifier widget shown next to the keyers
|
|
'opslog.ampSel.widget', // which amplifier that widget shows ("all" or an amp id)
|
|
'opslog.showBeamOnMap', // antenna beam lobe drawn on the Main map
|
|
'opslog.startEqualsEnd',// log TIME_ON = TIME_OFF (QSO time = completion time)
|
|
'opslog.showQsoRate', // QSO-rate meter (10/60 min) shown in the header
|
|
'opslog.catModeBeforeFreq', // send CAT mode before frequency (older rigs)
|
|
'opslog.bandMapBands', // bands shown side-by-side in the Band Map tab
|
|
'opslog.mapAutoZoomDX', // Main map: auto-zoom to the DX (vs free pan/zoom)
|
|
'opslog.mapView', // Main map: remembered free-pan view (lat/lon/zoom)
|
|
'opslog.lookupOnBlur', // run the callsign lookup on blur instead of while typing
|
|
'opslog.groupDigitalSlots', // matrix + cluster: all digital modes count as ONE (DXCC-style) instead of per-mode slots
|
|
'opslog.clusterShowFilters', // cluster filter sidebar shown (tab + Main pane)
|
|
'opslog.mapBasemap', // world map basemap (light / street / satellite)
|
|
'opslog.dateFormat', // how dates are DISPLAYED (iso / fr / us); storage stays ISO
|
|
'opslog.mapGreyline', // world map: grey line (day/night terminator) shown
|
|
'opslog.awardRefSort', 'opslog.awardRefSortDir', // award reference table: sort column and direction
|
|
// Cluster filter selections — restored on reopen.
|
|
'opslog.clusterFilterSource', 'opslog.clusterGroup', 'opslog.clusterBands',
|
|
'opslog.clusterLockBand', 'opslog.clusterLockMode', 'opslog.clusterStatusFilter',
|
|
'opslog.clusterModeFilter', 'opslog.clusterSearch', 'opslog.clusterHideWorked',
|
|
'opslog.activeTab', // last selected tab
|
|
'opslog.mainSplit', // Main tab: width share of the left pane (percent)
|
|
'opslog.bandMapWidth', // docked band map: column width (px)
|
|
'opslog.bandMapTabWidth', // Band map tab: shared card width (px)
|
|
// NOTE: 'hamlog.awardColsShown' and the grid column layouts are NOT listed here.
|
|
// They are handled by lib/gridPrefs, which scopes the localStorage cache PER
|
|
// PROFILE and mirrors to the DB (already per-profile) itself — mirroring them
|
|
// through this global path would fight that per-profile scoping.
|
|
];
|
|
|
|
// syncPortablePrefs reconciles the DB with the local cache at startup:
|
|
// • DB has a value → copy it into localStorage (a copied folder restores it);
|
|
// • DB empty, local set → seed the DB from local (migrates the current value).
|
|
// Call it BEFORE the first render so the app's synchronous localStorage reads
|
|
// already see the portable values — no per-component hydration needed.
|
|
export async function syncPortablePrefs(): Promise<void> {
|
|
await Promise.all(PORTABLE_KEYS.map(async (key) => {
|
|
try {
|
|
const db = await GetUIPref(key);
|
|
const local = localStorage.getItem(key);
|
|
if (db != null && db !== '') {
|
|
if (db !== local) { try { localStorage.setItem(key, db); } catch { /* quota */ } }
|
|
} else if (local != null && local !== '') {
|
|
await SetUIPref(key, local);
|
|
}
|
|
} catch { /* backend not ready / no DB — keep whatever is in localStorage */ }
|
|
}));
|
|
}
|
|
|
|
// writeUiPref write-throughs a value to the local cache AND the portable DB.
|
|
// Use it everywhere these keys are written instead of localStorage.setItem.
|
|
export function writeUiPref(key: string, value: string): void {
|
|
try { localStorage.setItem(key, value); } catch { /* quota / private mode */ }
|
|
SetUIPref(key, value).catch((e: any) => {
|
|
// The cache still holds it, so the interface behaves — but the BACKEND
|
|
// reads some of these keys too (digital-mode grouping decides how the
|
|
// cluster judges a slot). A write that reaches localStorage and not the
|
|
// database makes the two disagree, and used to do so in silence.
|
|
try { LogUIError("ui pref", "could not store " + key + ": " + String(e?.message ?? e), ""); } catch {}
|
|
});
|
|
}
|