Fix Codex review findings on PR 89: station row key, map selection, sort after filter

- Station row key now includes the chat category, so the same callsign in two
  categories no longer collides.
- Map marker click and Reset view go through the central station selection.
- Sorting now operates on the filtered rows, so filters stay effective.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Rsclub2_2andClaude Opus 5.5 committed 2026-10-08 23:11:01 +02:00
1 parent c8ce0e985d
commit 2125137709
4 files changed
+33 -7

No files matched your search

@@ -3034,7 +3034,8 @@ public class Kst4ContestApplication implements StatusUpdateListener, SettingsHos
member -> parseTableDouble(formatPriorityScore(member)),
(member, band, worked) -> formatBandCellStatus(member, band, worked),
BandOpportunityResolver.getEnabledStationBands(chatcontroller.getChatPreferences())),
RowKeys.INSTANCE.byValue(ChatMember::getCallSign),
RowKeys.INSTANCE.byValue(member -> member.getCallSign() + "|"
+ (member.getChatCategory() == null ? "" : member.getChatCategory().getCategoryNumber())),
"compose-stations",
widths);
@@ -3222,6 +3223,11 @@ public class Kst4ContestApplication implements StatusUpdateListener, SettingsHos
composeMemberListener = rows -> uiDispatcher.runOnUi(() -> stations.replaceRows(rows));
chatcontroller.getLst_chatMemberList().addListener(composeMemberListener);
composeMainWindowState.setStationSelector(member -> {
selectStationInCompose(selectedStation, stations, member);
return kotlin.Unit.INSTANCE;
});
composeChatListener = rows -> uiDispatcher.runOnUi(() -> {
directed.replaceRows(chatcontroller.toMeMessages());
publicMessages.replaceRows(rows);
@@ -318,12 +318,12 @@ class DataTableState<T>(
* rows jump.
*/
val order = column.comparator
?: compareBy(currentRows.associateWith { column.value(it) }::getValue)
?: compareBy(filteredRows.associateWith { column.value(it) }::getValue)
if (ascending) {
currentRows.sortedWith(order)
filteredRows.sortedWith(order)
} else {
currentRows.sortedWith(order.reversed())
filteredRows.sortedWith(order.reversed())
}
}
@@ -62,6 +62,13 @@ class MainWindowState(
) {
/** The shortcut buttons above the send line. */
/**
* The one path that selects a station for the whole application (panel, table, score
* service, send line). Set by the host after construction; other windows, such as the
* map, go through it instead of touching [selectedStation] alone. Null clears.
*/
var stationSelector: ((ChatMember?) -> Unit)? = null
val shortcuts = RosterMirror(prefs.getLst_txtShortCutBtnList())
/** The snippets behind Ctrl+1..Ctrl+0 and the right-click menus. */
@@ -217,7 +217,8 @@ object StationMapWindow {
}
kst4contest.view.compose.Form.button(strings.mapResetView) {
mainWindowState.selectedStation.select(null)
mainWindowState.stationSelector?.invoke(null)
?: mainWindowState.selectedStation.select(null)
val home = runCatching {
kst4contest.locatorUtils.Location(ownLocator6)
}.getOrNull()
@@ -277,10 +278,22 @@ object StationMapWindow {
darkMode = isDarkTheme,
onMarkerClicked = { snapshot ->
val chatController = ApplicationRuntimeLauncher.getCurrent()?.chatController
val member = chatController?.lst_chatMemberList?.snapshot()?.find { it.callSignRaw == snapshot.callSignRaw() }
val variants = chatController?.lst_chatMemberList?.snapshot()
?.filter { it.callSignRaw == snapshot.callSignRaw() }
.orEmpty()
/*
* A marker stands for a raw callsign, not a category. Keep the
* category already selected when it is one of the variants.
*/
val member = variants.firstOrNull { it === mainWindowState.selectedStation.selected }
?: variants.firstOrNull()
if (member != null) {
val selector = mainWindowState.stationSelector
if (selector != null) {
selector(member)
} else {
mainWindowState.selectedStation.select(member)
}
// Mirror old JavaFX handleMapCallsignSelection logic: prefill /cq
mainWindowState.chatInput.prepareCq(member.callSign ?: "", forceOverwrite = true)
}