feat(cluster): single click fills the call, double click works the spot
Reading the cluster means running down dozens of lines, and a single click did the whole job — QSY, mode, callsign — so every line looked at dragged the radio with it. One stray click while reading took the operator off the station they were working. Looking and going are two different intentions, so they are two gestures now. The band map is unchanged: clicking a spot there is already a deliberate act, not a way of reading a list.
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import {
|
||||
AllCommunityModule, ModuleRegistry,
|
||||
type ColDef, type ColumnState, type GridReadyEvent, type RowClickedEvent,
|
||||
type ColDef, type ColumnState, type GridReadyEvent, type RowClickedEvent, type RowDoubleClickedEvent,
|
||||
} from 'ag-grid-community';
|
||||
import { hamlogGridTheme } from '@/lib/gridTheme';
|
||||
import { AgGridReact } from 'ag-grid-react';
|
||||
@@ -75,7 +75,13 @@ export type SpotStatusEntry = {
|
||||
type Props = {
|
||||
rows: ClusterSpot[];
|
||||
spotStatus: Record<string, SpotStatusEntry>;
|
||||
// A DOUBLE click works the spot: QSY, mode, callsign, the lot.
|
||||
onSpotClick?: (s: ClusterSpot) => void;
|
||||
// A SINGLE click only fills the callsign. Reading the cluster means passing
|
||||
// over dozens of lines, and every pass used to drag the radio with it — one
|
||||
// stray click while looking took the operator off the station they were
|
||||
// working. Looking and going are now two different gestures.
|
||||
onSpotSelect?: (s: ClusterSpot) => void;
|
||||
};
|
||||
|
||||
const COL_STATE_KEY = 'hamlog.clusterColState.v1';
|
||||
@@ -500,7 +506,7 @@ const GROUP_ORDER = ['Spot', 'Geo'];
|
||||
const CLG_GRP_KEYS: Record<string, string> = { Spot: 'clg2.grpSpot', Geo: 'clg2.grpGeo' };
|
||||
const groupLabel = (t: TFn, g: string): string => t(CLG_GRP_KEYS[g] ?? g);
|
||||
|
||||
export function ClusterGrid({ rows, spotStatus, onSpotClick }: Props) {
|
||||
export function ClusterGrid({ rows, spotStatus, onSpotClick, onSpotSelect }: Props) {
|
||||
const { t } = useI18n();
|
||||
const gridRef = useRef<any>(null);
|
||||
const [pickerOpen, setPickerOpen] = useState(false);
|
||||
@@ -583,6 +589,10 @@ export function ClusterGrid({ rows, spotStatus, onSpotClick }: Props) {
|
||||
}, []);
|
||||
|
||||
function handleRowClicked(e: RowClickedEvent<ClusterSpot>) {
|
||||
if (e.data && onSpotSelect) onSpotSelect(e.data);
|
||||
}
|
||||
|
||||
function handleRowDoubleClicked(e: RowDoubleClickedEvent<ClusterSpot>) {
|
||||
if (e.data && onSpotClick) onSpotClick(e.data);
|
||||
}
|
||||
|
||||
@@ -647,6 +657,7 @@ export function ClusterGrid({ rows, spotStatus, onSpotClick }: Props) {
|
||||
onColumnVisible={saveColumnState}
|
||||
onSortChanged={saveColumnState}
|
||||
onRowClicked={handleRowClicked}
|
||||
onRowDoubleClicked={handleRowDoubleClicked}
|
||||
animateRows={false}
|
||||
suppressCellFocus
|
||||
getRowId={(p) => `${(p.data as any).received_at}-${(p.data as any).dx_call}-${(p.data as any).source_id}`}
|
||||
|
||||
Reference in New Issue
Block a user