mirror of
https://github.com/praktimarc/kst4contest.git
synced 2026-09-11 19:55:40 +02:00
Compare commits
19
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eaf611b203 | ||
|
|
e339b6fccf | ||
|
|
bd9b42d4a5 | ||
|
|
275ce48769 | ||
|
|
d201997587
|
||
|
|
250290a1eb | ||
|
|
052cfea7ad
|
||
|
|
d930b57196 | ||
|
|
eb29d56f4e | ||
|
|
eb2a7f88a4 | ||
|
|
8c3e4c15af | ||
|
|
c8b1f97872 | ||
|
|
b47fd21dd0 | ||
|
|
f009ed4b3d | ||
|
|
47126f4ae1
|
||
|
|
7d3177ba8a | ||
|
|
ff71623b90
|
||
|
|
ead985a741
|
||
|
|
ef1eeeed36
|
@@ -22,7 +22,7 @@ env:
|
||||
|
||||
concurrency:
|
||||
group: website-build-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
@@ -35,6 +35,8 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4.1.7
|
||||
with:
|
||||
ssh-key: ${{ secrets.WEBSITE_DEPLOY_KEY }}
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@v4
|
||||
@@ -50,10 +52,25 @@ jobs:
|
||||
- name: Build website
|
||||
working-directory: website
|
||||
run: npm run build
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Upload website artifact
|
||||
uses: actions/upload-artifact@v4.3.4
|
||||
with:
|
||||
name: kst4contest-website
|
||||
path: website/_site/
|
||||
retention-days: 7
|
||||
retention-days: 7
|
||||
|
||||
- name: Commit rebuilt site
|
||||
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
||||
run: |
|
||||
git config user.name "github-actions[bot]"
|
||||
git config user.email "github-actions[bot]@users.noreply.github.com"
|
||||
git add website/_site
|
||||
if git diff --cached --quiet; then
|
||||
echo "No changes to commit"
|
||||
else
|
||||
git commit -m "chore: rebuild website [skip ci]"
|
||||
git push
|
||||
fi
|
||||
@@ -0,0 +1,59 @@
|
||||
name: Rebuild Roadmap
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [opened, edited, closed, reopened, labeled, unlabeled, milestoned, demilestoned]
|
||||
|
||||
env:
|
||||
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
|
||||
|
||||
concurrency:
|
||||
group: website-build-${{ github.ref }}
|
||||
cancel-in-progress: false
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
rebuild-roadmap:
|
||||
name: Rebuild website roadmap
|
||||
runs-on: ubuntu-latest
|
||||
# Only worth a rebuild if the "enhancement" label is involved: either the
|
||||
# issue currently carries it, or this event just added/removed it.
|
||||
if: contains(github.event.issue.labels.*.name, 'enhancement') || github.event.label.name == 'enhancement'
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4.1.7
|
||||
with:
|
||||
ref: main
|
||||
ssh-key: ${{ secrets.WEBSITE_DEPLOY_KEY }}
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: "24"
|
||||
cache: npm
|
||||
cache-dependency-path: website/package-lock.json
|
||||
|
||||
- name: Install dependencies
|
||||
working-directory: website
|
||||
run: npm ci
|
||||
|
||||
- name: Build website
|
||||
working-directory: website
|
||||
run: npm run build
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Commit rebuilt site
|
||||
run: |
|
||||
git config user.name "github-actions[bot]"
|
||||
git config user.email "github-actions[bot]@users.noreply.github.com"
|
||||
git add website/_site
|
||||
if git diff --cached --quiet; then
|
||||
echo "No changes to commit"
|
||||
else
|
||||
git commit -m "chore: rebuild website roadmap [skip ci]"
|
||||
git push
|
||||
fi
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
<groupId>de.x08</groupId>
|
||||
<artifactId>praktiKST</artifactId>
|
||||
<version>1.41.1-nightly</version>
|
||||
<version>1.42.0-nightly</version>
|
||||
|
||||
<name>praktiKST</name>
|
||||
|
||||
|
||||
@@ -20,9 +20,9 @@ public class ApplicationConstants {
|
||||
/**
|
||||
* Name of file to store preferences in.
|
||||
*/
|
||||
public static final double APPLICATION_CURRENTVERSIONNUMBER = 1.411;
|
||||
public static final double APPLICATION_CURRENTVERSIONNUMBER = 1.42;
|
||||
|
||||
public static final String VERSIONINFOURLFORUPDATES_KST4CONTEST = "https://do5amf.funkerportal.de/kst4ContestVersionInfo.xml";
|
||||
public static final String VERSIONINFOURLFORUPDATES_KST4CONTEST = "https://kst4contest.hamradioonline.de/kst4ContestVersionInfo.xml";
|
||||
public static final String VERSIONINFDOWNLOADEDLOCALFILE = "kst4ContestVersionInfo.xml";
|
||||
|
||||
public static final String STYLECSSFILE_DEFAULT_DAYLIGHT = "KST4ContestDefaultDay.css";
|
||||
|
||||
@@ -64,6 +64,8 @@ import javafx.scene.shape.Polygon;
|
||||
import javafx.stage.Screen;
|
||||
|
||||
import kst4contest.utils.ApplicationFileUtils;
|
||||
import kst4contest.view.map.MapCallsignRawSnapshot;
|
||||
import kst4contest.view.map.MapCallsignRawSnapshotBuilder;
|
||||
import kst4contest.view.map.StationMapBridge;
|
||||
import kst4contest.view.map.StationMapView;
|
||||
import kst4contest.view.map.OfflineDemImportService;
|
||||
@@ -116,6 +118,8 @@ public class Kst4ContestApplication extends Application implements StatusUpdateL
|
||||
private final Tooltip tipSkedWarnIndicator = new Tooltip();
|
||||
private Timeline skedWarnBlinkTimeline;
|
||||
|
||||
private final MapCallsignRawSnapshotBuilder mainViewBandMarkerSnapshotBuilder = new MapCallsignRawSnapshotBuilder();
|
||||
|
||||
|
||||
// Timeline: show at most N priority markers per minute bucket (minute 0/1 often has many planes)
|
||||
private static final int TIMELINE_PRIORITY_MARKERS_PER_MINUTE = 2;
|
||||
@@ -414,6 +418,55 @@ public class Kst4ContestApplication extends Application implements StatusUpdateL
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a station has known activity on the given band and that band is
|
||||
* one of my own currently enabled bands, i.e. a new-band opportunity worth flagging
|
||||
* with a star in that band's table cell.
|
||||
*
|
||||
* @param chatMember station row
|
||||
* @param band band to check
|
||||
* @return true if the band cell should show a star
|
||||
*/
|
||||
private boolean isBandOfferForMainView(ChatMember chatMember, Band band) {
|
||||
if (chatMember == null
|
||||
|| band == null
|
||||
|| chatcontroller == null
|
||||
|| chatcontroller.getReachabilityService() == null
|
||||
|| chatMember.getCallSignRaw() == null
|
||||
|| chatMember.getCallSignRaw().isBlank()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
EnumSet<Band> enabledBands = chatcontroller.getReachabilityService().getEnabledStationBands();
|
||||
if (enabledBands == null || !enabledBands.contains(band)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
List<ChatMember> variants = new ArrayList<>();
|
||||
synchronized (chatcontroller.getLst_chatMemberList()) {
|
||||
for (ChatMember variant : chatcontroller.getLst_chatMemberList()) {
|
||||
if (variant == null || variant.getCallSignRaw() == null) {
|
||||
continue;
|
||||
}
|
||||
if (variant.getCallSignRaw().equalsIgnoreCase(chatMember.getCallSignRaw())) {
|
||||
variants.add(variant);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (variants.isEmpty()) {
|
||||
variants = List.of(chatMember);
|
||||
}
|
||||
|
||||
List<MapCallsignRawSnapshot> snapshots = mainViewBandMarkerSnapshotBuilder.buildSnapshots(
|
||||
variants,
|
||||
null,
|
||||
EnumSet.of(band)
|
||||
);
|
||||
|
||||
return snapshots.stream().anyMatch(MapCallsignRawSnapshot::offersSelectedBand);
|
||||
}
|
||||
|
||||
private String bandToHumanLabel(kst4contest.model.Band b) {
|
||||
// Human-friendly labels for VHF/UHF/microwave contesting
|
||||
return switch (b) {
|
||||
@@ -1204,14 +1257,18 @@ public class Kst4ContestApplication extends Application implements StatusUpdateL
|
||||
public ObservableValue<String> call(CellDataFeatures<ChatMember, String> cellDataFeatures) {
|
||||
SimpleStringProperty callsgn = new SimpleStringProperty();
|
||||
|
||||
if (cellDataFeatures.getValue().getState() == 1) {
|
||||
callsgn.setValue("(" + cellDataFeatures.getValue().getCallSign() + ")"); //away user
|
||||
} else {
|
||||
ChatMember member = cellDataFeatures.getValue();
|
||||
String baseCallsign;
|
||||
|
||||
callsgn.setValue(cellDataFeatures.getValue().getCallSign());
|
||||
if (member.getState() == 1) {
|
||||
baseCallsign = "(" + member.getCallSign() + ")"; //away user
|
||||
} else {
|
||||
baseCallsign = member.getCallSign();
|
||||
}
|
||||
|
||||
// System.out.println(cellDataFeatures.getValue().getCallSign() + " / " + cellDataFeatures.getValue().getState()+ " <<<<<<<<<<<<<<<<<< state ");
|
||||
callsgn.setValue(baseCallsign);
|
||||
|
||||
// System.out.println(member.getCallSign() + " / " + member.getState()+ " <<<<<<<<<<<<<<<<<< state ");
|
||||
|
||||
return callsgn;
|
||||
}
|
||||
@@ -1656,30 +1713,6 @@ public class Kst4ContestApplication extends Application implements StatusUpdateL
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Shows the compact worked/grid status and explains it by tooltip.
|
||||
*/
|
||||
wkdAny_subcol.setCellFactory(column -> new TableCell<ChatMember, String>() {
|
||||
@Override
|
||||
protected void updateItem(String item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
|
||||
if (empty) {
|
||||
setText(null);
|
||||
setTooltip(null);
|
||||
setStyle("");
|
||||
return;
|
||||
}
|
||||
|
||||
ChatMember member = getTableRow() == null ? null : getTableRow().getItem();
|
||||
|
||||
setText(item);
|
||||
setTooltip(new Tooltip(buildWorkedAnyGridStatusTooltip(member)));
|
||||
setAlignment(Pos.CENTER);
|
||||
setStyle("-fx-font-weight: bold;");
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
TableColumn<ChatMember, String> vhfCol_subcol = new TableColumn<ChatMember, String>("144");
|
||||
vhfCol_subcol
|
||||
@@ -1691,6 +1724,8 @@ public class Kst4ContestApplication extends Application implements StatusUpdateL
|
||||
|
||||
if (cellDataFeatures.getValue().isWorked144()) {
|
||||
wkd.setValue("X");
|
||||
} else if (isBandOfferForMainView(cellDataFeatures.getValue(), Band.B_144)) {
|
||||
wkd.setValue("B+");
|
||||
} else {
|
||||
wkd.setValue("");
|
||||
}
|
||||
@@ -1710,6 +1745,8 @@ public class Kst4ContestApplication extends Application implements StatusUpdateL
|
||||
|
||||
if (cellDataFeatures.getValue().isWorked432()) {
|
||||
wkd.setValue("X");
|
||||
} else if (isBandOfferForMainView(cellDataFeatures.getValue(), Band.B_432)) {
|
||||
wkd.setValue("B+");
|
||||
} else {
|
||||
wkd.setValue("");
|
||||
}
|
||||
@@ -1729,6 +1766,8 @@ public class Kst4ContestApplication extends Application implements StatusUpdateL
|
||||
|
||||
if (cellDataFeatures.getValue().isWorked1240()) {
|
||||
wkd.setValue("X");
|
||||
} else if (isBandOfferForMainView(cellDataFeatures.getValue(), Band.B_1296)) {
|
||||
wkd.setValue("B+");
|
||||
} else {
|
||||
wkd.setValue("");
|
||||
}
|
||||
@@ -1747,6 +1786,8 @@ public class Kst4ContestApplication extends Application implements StatusUpdateL
|
||||
|
||||
if (cellDataFeatures.getValue().isWorked2300()) {
|
||||
wkd.setValue("X");
|
||||
} else if (isBandOfferForMainView(cellDataFeatures.getValue(), Band.B_2320)) {
|
||||
wkd.setValue("B+");
|
||||
} else {
|
||||
wkd.setValue("");
|
||||
}
|
||||
@@ -1765,6 +1806,8 @@ public class Kst4ContestApplication extends Application implements StatusUpdateL
|
||||
|
||||
if (cellDataFeatures.getValue().isWorked3400()) {
|
||||
wkd.setValue("X");
|
||||
} else if (isBandOfferForMainView(cellDataFeatures.getValue(), Band.B_3400)) {
|
||||
wkd.setValue("B+");
|
||||
} else {
|
||||
wkd.setValue("");
|
||||
}
|
||||
@@ -1783,6 +1826,8 @@ public class Kst4ContestApplication extends Application implements StatusUpdateL
|
||||
|
||||
if (cellDataFeatures.getValue().isWorked5600()) {
|
||||
wkd.setValue("X");
|
||||
} else if (isBandOfferForMainView(cellDataFeatures.getValue(), Band.B_5760)) {
|
||||
wkd.setValue("B+");
|
||||
} else {
|
||||
wkd.setValue("");
|
||||
}
|
||||
@@ -1801,6 +1846,8 @@ public class Kst4ContestApplication extends Application implements StatusUpdateL
|
||||
|
||||
if (cellDataFeatures.getValue().isWorked10G()) {
|
||||
wkd.setValue("X");
|
||||
} else if (isBandOfferForMainView(cellDataFeatures.getValue(), Band.B_10G)) {
|
||||
wkd.setValue("B+");
|
||||
} else {
|
||||
wkd.setValue("");
|
||||
}
|
||||
@@ -5923,9 +5970,19 @@ public class Kst4ContestApplication extends Application implements StatusUpdateL
|
||||
txt_myQTF.getStyleClass().add("text-input");
|
||||
txt_myQTF.getStyleClass().add("text-input-MYQRG1");
|
||||
|
||||
txt_myQTF.textProperty().bind(Bindings.createStringBinding(
|
||||
() -> Double.toString(chatcontroller.getChatPreferences().getActualQTF().get()),
|
||||
chatcontroller.getChatPreferences().getActualQTF()));
|
||||
// Rotator sync on/off determines whether this field is bound (read-only, driven
|
||||
// by PSTRotator) or free for manual entry, mirroring the MYQRG sync behaviour above.
|
||||
if (chatcontroller.getChatPreferences().isStn_pstRotatorEnabled()) {
|
||||
txt_myQTF.textProperty().bind(Bindings.createStringBinding(
|
||||
() -> Double.toString(chatcontroller.getChatPreferences().getActualQTF().get()),
|
||||
chatcontroller.getChatPreferences().getActualQTF()));
|
||||
txt_myQTF.setTooltip(new Tooltip("This is your current QTF, read out at PSTRotator"));
|
||||
txt_myQTF.setFocusTraversable(false);
|
||||
} else {
|
||||
txt_myQTF.setText(Double.toString(chatcontroller.getChatPreferences().getActualQTF().get()));
|
||||
txt_myQTF.setTooltip(new Tooltip("Enter your antenna heading (QTF) by hand - no rotator sync active"));
|
||||
txt_myQTF.setFocusTraversable(true);
|
||||
}
|
||||
|
||||
txt_myQTF.focusedProperty().addListener(new ChangeListener<Boolean>() {
|
||||
@Override
|
||||
@@ -5935,13 +5992,16 @@ public class Kst4ContestApplication extends Application implements StatusUpdateL
|
||||
// System.out.println("Textfield on focus");
|
||||
// Do nothing until field loses focus, user will enter his frequency
|
||||
} else {
|
||||
if (txt_myQTF.textProperty().isBound()) {
|
||||
return; // rotator sync active, field is driven by PSTRotator
|
||||
}
|
||||
try {
|
||||
System.out.println(
|
||||
"[Main.java, Info]: Set the MYQTF property by hand to: " + txt_myQTF.getText());
|
||||
chatcontroller.getChatPreferences().getActualQTF().set(Integer.parseInt(txt_myQTF.getText()));}
|
||||
chatcontroller.getChatPreferences().getActualQTF().set(Double.parseDouble(txt_myQTF.getText()));}
|
||||
catch (Exception exception) {
|
||||
System.out.println("bullshit entered in myqtf");
|
||||
txt_myQTF.setText("0");
|
||||
txt_myQTF.setText("0.0");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5950,8 +6010,6 @@ public class Kst4ContestApplication extends Application implements StatusUpdateL
|
||||
txt_myQTF.setPrefSize(40, 0);
|
||||
// txt_ownqrg.setMinSize(40, 0);
|
||||
txt_myQTF.setAlignment(Pos.BASELINE_RIGHT);
|
||||
txt_myQTF.setTooltip(new Tooltip("This is your current QTF, read out at PSTRotator"));
|
||||
txt_myQTF.setFocusTraversable(false);
|
||||
|
||||
SplitPane mainWindowLeftSplitPane = new SplitPane();
|
||||
mainWindowLeftSplitPane.setOrientation(Orientation.HORIZONTAL);
|
||||
@@ -8590,9 +8648,21 @@ public class Kst4ContestApplication extends Application implements StatusUpdateL
|
||||
chkBx_station_pstRotatorEnabled.setTooltip(new Tooltip(
|
||||
"If disabled: no PSTRotator connection is started and antenna direction is ignored in priority scoring."
|
||||
));
|
||||
chkBx_station_pstRotatorEnabled.selectedProperty().addListener((obs, oldV, newV) ->
|
||||
chatcontroller.getChatPreferences().setStn_pstRotatorEnabled(newV)
|
||||
);
|
||||
chkBx_station_pstRotatorEnabled.selectedProperty().addListener((obs, oldV, newV) -> {
|
||||
chatcontroller.getChatPreferences().setStn_pstRotatorEnabled(newV);
|
||||
if (newV) {
|
||||
txt_myQTF.textProperty().bind(Bindings.createStringBinding(
|
||||
() -> Double.toString(chatcontroller.getChatPreferences().getActualQTF().get()),
|
||||
chatcontroller.getChatPreferences().getActualQTF()));
|
||||
txt_myQTF.setTooltip(new Tooltip("This is your current QTF, read out at PSTRotator"));
|
||||
txt_myQTF.setFocusTraversable(false);
|
||||
} else {
|
||||
txt_myQTF.textProperty().unbind();
|
||||
txt_myQTF.setText(Double.toString(chatcontroller.getChatPreferences().getActualQTF().get()));
|
||||
txt_myQTF.setTooltip(new Tooltip("Enter your antenna heading (QTF) by hand - no rotator sync active"));
|
||||
txt_myQTF.setFocusTraversable(true);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
grdPnlStation.add(lblCallSign, 0, 0);
|
||||
|
||||
@@ -20,6 +20,7 @@ public record MapCallsignRawSnapshot(
|
||||
double longitudeDeg,
|
||||
String bandSummary,
|
||||
Map<String, String> lastKnownFrequenciesByBand,
|
||||
boolean offersSelectedBand,
|
||||
boolean warningToMyDirection,
|
||||
boolean worked,
|
||||
boolean selected,
|
||||
@@ -59,9 +60,10 @@ public record MapCallsignRawSnapshot(
|
||||
}
|
||||
|
||||
public String markerLabel() {
|
||||
return bandSummary.isBlank()
|
||||
String baseLabel = bandSummary.isBlank()
|
||||
? displayCallSign
|
||||
: displayCallSign + " (" + bandSummary + ")";
|
||||
return offersSelectedBand ? baseLabel + " B+" : baseLabel;
|
||||
}
|
||||
|
||||
public String detailFrequencyText() {
|
||||
|
||||
@@ -8,11 +8,13 @@ import kst4contest.model.ChatMember;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Comparator;
|
||||
import java.util.EnumSet;
|
||||
import java.util.EnumMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Builds immutable map snapshots from the currently visible chat members.
|
||||
@@ -22,8 +24,11 @@ import java.util.Map;
|
||||
*/
|
||||
public final class MapCallsignRawSnapshotBuilder {
|
||||
|
||||
private static final Pattern TOKEN_SPLIT_PATTERN = Pattern.compile("[^A-Z0-9]+");
|
||||
|
||||
public List<MapCallsignRawSnapshot> buildSnapshots(Collection<ChatMember> visibleChatMembers,
|
||||
ChatMember selectedChatMember) {
|
||||
ChatMember selectedChatMember,
|
||||
EnumSet<Band> selectedBands) {
|
||||
|
||||
if (visibleChatMembers == null || visibleChatMembers.isEmpty()) {
|
||||
return List.of();
|
||||
@@ -69,7 +74,9 @@ public final class MapCallsignRawSnapshotBuilder {
|
||||
Location location = new Location(locator6);
|
||||
|
||||
LinkedHashMap<String, String> frequenciesByBand = collectLastKnownFrequenciesByBand(variants);
|
||||
String bandSummary = String.join(", ", frequenciesByBand.keySet());
|
||||
EnumSet<Band> sureBands = collectSureBands(variants, frequenciesByBand);
|
||||
String bandSummary = buildBandSummary(sureBands);
|
||||
boolean offersSelectedBand = hasAnySelectedBand(sureBands, selectedBands);
|
||||
|
||||
boolean warningToMyDirection = variants.stream().anyMatch(ChatMember::isInAngleAndRange);
|
||||
boolean worked = variants.stream().anyMatch(this::isWorkedAtAnyBand);
|
||||
@@ -92,6 +99,7 @@ public final class MapCallsignRawSnapshotBuilder {
|
||||
location.getLongitude().toDegrees(),
|
||||
bandSummary,
|
||||
frequenciesByBand,
|
||||
offersSelectedBand,
|
||||
warningToMyDirection,
|
||||
worked,
|
||||
selected,
|
||||
@@ -182,6 +190,101 @@ public final class MapCallsignRawSnapshotBuilder {
|
||||
return ordered;
|
||||
}
|
||||
|
||||
private EnumSet<Band> collectSureBands(List<ChatMember> variants,
|
||||
LinkedHashMap<String, String> frequenciesByBand) {
|
||||
EnumSet<Band> sureBands = EnumSet.noneOf(Band.class);
|
||||
|
||||
if (frequenciesByBand != null) {
|
||||
for (String label : frequenciesByBand.keySet()) {
|
||||
Band mappedBand = bandFromDisplayLabel(label);
|
||||
if (mappedBand != null) {
|
||||
sureBands.add(mappedBand);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (ChatMember variant : variants) {
|
||||
if (variant == null || variant.getName() == null || variant.getName().isBlank()) {
|
||||
continue;
|
||||
}
|
||||
sureBands.addAll(detectBandsFromStationName(variant.getName()));
|
||||
}
|
||||
|
||||
return sureBands;
|
||||
}
|
||||
|
||||
private EnumSet<Band> detectBandsFromStationName(String stationName) {
|
||||
EnumSet<Band> detectedBands = EnumSet.noneOf(Band.class);
|
||||
if (stationName == null || stationName.isBlank()) {
|
||||
return detectedBands;
|
||||
}
|
||||
|
||||
String normalized = stationName.toUpperCase(Locale.ROOT);
|
||||
String[] tokens = TOKEN_SPLIT_PATTERN.split(normalized);
|
||||
for (String token : tokens) {
|
||||
if (token == null || token.isBlank()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (token) {
|
||||
case "2", "2M", "144", "144MHZ" -> detectedBands.add(Band.B_144);
|
||||
case "70", "70CM", "432", "432MHZ" -> detectedBands.add(Band.B_432);
|
||||
case "23", "23CM", "1296", "1296MHZ" -> detectedBands.add(Band.B_1296);
|
||||
case "13", "13CM", "2300", "2320", "2320MHZ" -> detectedBands.add(Band.B_2320);
|
||||
case "9", "9CM", "3400", "3400MHZ" -> detectedBands.add(Band.B_3400);
|
||||
case "6", "6CM", "5600", "5760", "5760MHZ" -> detectedBands.add(Band.B_5760);
|
||||
case "3", "3CM", "10G", "10GHZ", "10368", "10368MHZ" -> detectedBands.add(Band.B_10G);
|
||||
case "24G", "24GHZ", "24048", "24048MHZ" -> detectedBands.add(Band.B_24G);
|
||||
default -> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return detectedBands;
|
||||
}
|
||||
|
||||
private String buildBandSummary(EnumSet<Band> sureBands) {
|
||||
if (sureBands == null || sureBands.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
List<String> labels = sureBands.stream()
|
||||
.sorted()
|
||||
.map(this::toBandDisplayLabel)
|
||||
.toList();
|
||||
return String.join(", ", labels);
|
||||
}
|
||||
|
||||
private boolean hasAnySelectedBand(EnumSet<Band> sureBands, EnumSet<Band> selectedBands) {
|
||||
if (sureBands == null || sureBands.isEmpty() || selectedBands == null || selectedBands.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
for (Band band : selectedBands) {
|
||||
if (sureBands.contains(band)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private Band bandFromDisplayLabel(String label) {
|
||||
if (label == null || label.isBlank()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return switch (label) {
|
||||
case "144" -> Band.B_144;
|
||||
case "432" -> Band.B_432;
|
||||
case "1296" -> Band.B_1296;
|
||||
case "2320" -> Band.B_2320;
|
||||
case "3400" -> Band.B_3400;
|
||||
case "5760" -> Band.B_5760;
|
||||
case "10368" -> Band.B_10G;
|
||||
case "24048" -> Band.B_24G;
|
||||
default -> null;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Fallback for stations where the current displayed QRG exists but the
|
||||
* knownActiveBands history has not yet been filled.
|
||||
|
||||
@@ -11,6 +11,7 @@ import kst4contest.model.ChatPreferences;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
@@ -142,8 +143,13 @@ public final class StationMapBridge {
|
||||
private void refreshNow() {
|
||||
List<ChatMember> visibleChatMembers = new ArrayList<>(chatController.getLst_chatMemberSortedFilteredList());
|
||||
ChatMember selectedChatMember = chatController.getScoreService().getSelectedChatMember();
|
||||
EnumSet<Band> selectedBands = chatController.getReachabilityService().getEnabledStationBands();
|
||||
|
||||
List<MapCallsignRawSnapshot> snapshots = snapshotBuilder.buildSnapshots(visibleChatMembers, selectedChatMember);
|
||||
List<MapCallsignRawSnapshot> snapshots = snapshotBuilder.buildSnapshots(
|
||||
visibleChatMembers,
|
||||
selectedChatMember,
|
||||
selectedBands
|
||||
);
|
||||
|
||||
MapCallsignRawSnapshot selectedSnapshot = null;
|
||||
if (selectedChatMember != null && selectedChatMember.getCallSignRaw() != null) {
|
||||
|
||||
@@ -855,7 +855,11 @@ public final class StationMapView {
|
||||
detailLocatorValue.setText(selectedSnapshot.locator6());
|
||||
detailQrbValue.setText(String.format(Locale.US, "%.0f km", selectedSnapshot.qrbKm()));
|
||||
detailQtfValue.setText(String.format(Locale.US, "%.0f°", selectedSnapshot.qtfDeg()));
|
||||
detailBandsValue.setText(selectedSnapshot.bandSummary().isBlank() ? "-" : selectedSnapshot.bandSummary());
|
||||
String bandText = selectedSnapshot.bandSummary().isBlank() ? "-" : selectedSnapshot.bandSummary();
|
||||
if (selectedSnapshot.offersSelectedBand()) {
|
||||
bandText += " B+";
|
||||
}
|
||||
detailBandsValue.setText(bandText);
|
||||
detailFrequenciesArea.setText(selectedSnapshot.detailFrequencyText());
|
||||
detailAirplanesValue.setText(String.valueOf(selectedSnapshot.reachableAirplanes()));
|
||||
triggerClusterSpotButton.setDisable(false);
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
package kst4contest.test;
|
||||
|
||||
import kst4contest.model.Band;
|
||||
import kst4contest.model.ChatMember;
|
||||
import kst4contest.view.map.MapCallsignRawSnapshot;
|
||||
import kst4contest.view.map.MapCallsignRawSnapshotBuilder;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
class MapCallsignRawSnapshotBuilderTest {
|
||||
|
||||
@Test
|
||||
void marksSnapshotWhenNameAdvertisesSelectedBand() {
|
||||
ChatMember station = buildStation("DL1ABC", "QRV 2-70-23", "JN58TD", 1_000L);
|
||||
|
||||
MapCallsignRawSnapshotBuilder builder = new MapCallsignRawSnapshotBuilder();
|
||||
List<MapCallsignRawSnapshot> snapshots = builder.buildSnapshots(
|
||||
List.of(station),
|
||||
null,
|
||||
EnumSet.of(Band.B_1296)
|
||||
);
|
||||
|
||||
assertEquals(1, snapshots.size());
|
||||
assertTrue(snapshots.get(0).offersSelectedBand());
|
||||
}
|
||||
|
||||
@Test
|
||||
void keepsSnapshotUnmarkedWhenNoSelectedBandMatches() {
|
||||
ChatMember station = buildStation("DL1ABC", "QRV 2m only", "JN58TD", 1_000L);
|
||||
|
||||
MapCallsignRawSnapshotBuilder builder = new MapCallsignRawSnapshotBuilder();
|
||||
List<MapCallsignRawSnapshot> snapshots = builder.buildSnapshots(
|
||||
List.of(station),
|
||||
null,
|
||||
EnumSet.of(Band.B_2320)
|
||||
);
|
||||
|
||||
assertEquals(1, snapshots.size());
|
||||
assertFalse(snapshots.get(0).offersSelectedBand());
|
||||
}
|
||||
|
||||
private ChatMember buildStation(String callSign, String name, String locator, long activityEpoch) {
|
||||
ChatMember chatMember = new ChatMember();
|
||||
chatMember.setCallSign(callSign);
|
||||
chatMember.setName(name);
|
||||
chatMember.setQra(locator);
|
||||
chatMember.setActivityTimeLastInEpoch(activityEpoch);
|
||||
return chatMember;
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,7 @@
|
||||
<meta name="twitter:title" content="About KST4Contest">
|
||||
<meta name="twitter:description" content="About KST4Contest and its contest-oriented ON4KST workflow.">
|
||||
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783615687631">
|
||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||
|
||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||
@@ -47,12 +47,12 @@
|
||||
|
||||
<a href="/screenshots/">Screenshots</a>
|
||||
|
||||
<a href="/download/">Download</a>
|
||||
|
||||
<a href="/manual/">Manual</a>
|
||||
|
||||
<a href="/news/">News</a>
|
||||
|
||||
<a href="/roadmap/">Roadmap</a>
|
||||
|
||||
<a href="/about/">About</a>
|
||||
|
||||
<a href="/faq/">FAQ</a>
|
||||
|
||||
@@ -415,6 +415,23 @@ a:hover {
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.roadmap-version + .roadmap-version {
|
||||
margin-top: 24px;
|
||||
}
|
||||
|
||||
.roadmap-version ul {
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
.roadmap-version li {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.roadmap-done a {
|
||||
color: var(--muted);
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
.feature-icon {
|
||||
font-size: 2rem;
|
||||
margin-bottom: 14px;
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<meta name="twitter:title" content="Contact | KST4Contest">
|
||||
<meta name="twitter:description" content="Contact options for KST4Contest.">
|
||||
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783615687631">
|
||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||
|
||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||
@@ -47,12 +47,12 @@
|
||||
|
||||
<a href="/screenshots/">Screenshots</a>
|
||||
|
||||
<a href="/download/">Download</a>
|
||||
|
||||
<a href="/manual/">Manual</a>
|
||||
|
||||
<a href="/news/">News</a>
|
||||
|
||||
<a href="/roadmap/">Roadmap</a>
|
||||
|
||||
<a href="/about/">About</a>
|
||||
|
||||
<a href="/faq/">FAQ</a>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<meta name="twitter:title" content="Download KST4Contest">
|
||||
<meta name="twitter:description" content="Download KST4Contest releases for Windows, Linux and macOS.">
|
||||
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783615687631">
|
||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||
|
||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||
@@ -47,12 +47,12 @@
|
||||
|
||||
<a href="/screenshots/">Screenshots</a>
|
||||
|
||||
<a href="/download/">Download</a>
|
||||
|
||||
<a href="/manual/">Manual</a>
|
||||
|
||||
<a href="/news/">News</a>
|
||||
|
||||
<a href="/roadmap/">Roadmap</a>
|
||||
|
||||
<a href="/about/">About</a>
|
||||
|
||||
<a href="/faq/">FAQ</a>
|
||||
@@ -95,7 +95,7 @@
|
||||
<p><strong>ZIP x64</strong></p>
|
||||
<p>Best choice for most Windows users.</p>
|
||||
|
||||
<a class="button secondary" href="https://github.com/praktimarc/kst4contest/releases/download/v1.41.0/praktiKST-v1.41.0-windows-x64.zip">Download →</a>
|
||||
<a class="button secondary" href="https://github.com/praktimarc/kst4contest/releases/download/v1.41.1/praktiKST-v1.41.1-windows-x64.zip">Download →</a>
|
||||
</article>
|
||||
|
||||
<article class="card download-card">
|
||||
@@ -109,7 +109,7 @@
|
||||
<p><strong>Flatpak (.flatpakref)</strong></p>
|
||||
<p>Recommended for most Linux users. Open the file with GNOME Software / Discover, or run: flatpak install de.x08.KST4Contest.flatpakref</p>
|
||||
|
||||
<a class="button secondary" href="https://github.com/praktimarc/kst4contest/releases/download/v1.41.0/de.x08.KST4Contest.flatpakref">Download →</a>
|
||||
<a class="button secondary" href="https://github.com/praktimarc/kst4contest/releases/download/v1.41.1/de.x08.KST4Contest.flatpakref">Download →</a>
|
||||
</article>
|
||||
|
||||
<article class="card download-card">
|
||||
@@ -121,7 +121,7 @@
|
||||
<p><strong>AppImage x86_64</strong></p>
|
||||
<p>Portable Linux build without package installation.</p>
|
||||
|
||||
<a class="button secondary" href="https://github.com/praktimarc/kst4contest/releases/download/v1.41.0/KST4Contest-v1.41.0-linux-x86_64.AppImage">Download →</a>
|
||||
<a class="button secondary" href="https://github.com/praktimarc/kst4contest/releases/download/v1.41.1/KST4Contest-v1.41.1-linux-x86_64.AppImage">Download →</a>
|
||||
</article>
|
||||
|
||||
<article class="card download-card">
|
||||
@@ -133,7 +133,7 @@
|
||||
<p><strong>DEB amd64</strong></p>
|
||||
<p>Native package for Debian and Ubuntu based systems.</p>
|
||||
|
||||
<a class="button secondary" href="https://github.com/praktimarc/kst4contest/releases/download/v1.41.0/KST4Contest-v1.41.0-debian-amd64.deb">Download →</a>
|
||||
<a class="button secondary" href="https://github.com/praktimarc/kst4contest/releases/download/v1.41.1/KST4Contest-v1.41.1-debian-amd64.deb">Download →</a>
|
||||
</article>
|
||||
|
||||
<article class="card download-card">
|
||||
@@ -145,7 +145,7 @@
|
||||
<p><strong>RPM x86_64</strong></p>
|
||||
<p>Native package for Fedora/RPM based systems.</p>
|
||||
|
||||
<a class="button secondary" href="https://github.com/praktimarc/kst4contest/releases/download/v1.41.0/KST4Contest-v1.41.0-fedora-x86_64.rpm">Download →</a>
|
||||
<a class="button secondary" href="https://github.com/praktimarc/kst4contest/releases/download/v1.41.1/KST4Contest-v1.41.1-fedora-x86_64.rpm">Download →</a>
|
||||
</article>
|
||||
|
||||
<article class="card download-card">
|
||||
@@ -157,7 +157,7 @@
|
||||
<p><strong>pkg.tar.zst</strong></p>
|
||||
<p>Package build for Arch Linux users.</p>
|
||||
|
||||
<a class="button secondary" href="https://github.com/praktimarc/kst4contest/releases/download/v1.41.0/KST4Contest-v1.41.0-archlinux-x86_64.pkg.tar.zst">Download →</a>
|
||||
<a class="button secondary" href="https://github.com/praktimarc/kst4contest/releases/download/v1.41.1/KST4Contest-v1.41.1-archlinux-x86_64.pkg.tar.zst">Download →</a>
|
||||
</article>
|
||||
|
||||
<article class="card download-card">
|
||||
@@ -169,7 +169,7 @@
|
||||
<p><strong>DMG arm64</strong></p>
|
||||
<p>For Apple Silicon Macs.</p>
|
||||
|
||||
<a class="button secondary" href="https://github.com/praktimarc/kst4contest/releases/download/v1.41.0/KST4Contest-v1.41.0-macos-arm64.dmg">Download →</a>
|
||||
<a class="button secondary" href="https://github.com/praktimarc/kst4contest/releases/download/v1.41.1/KST4Contest-v1.41.1-macos-arm64.dmg">Download →</a>
|
||||
</article>
|
||||
|
||||
<article class="card download-card">
|
||||
@@ -181,7 +181,7 @@
|
||||
<p><strong>DMG x86_64</strong></p>
|
||||
<p>For Intel-based Macs.</p>
|
||||
|
||||
<a class="button secondary" href="https://github.com/praktimarc/kst4contest/releases/download/v1.41.0/KST4Contest-v1.41.0-macos-x86_64.dmg">Download →</a>
|
||||
<a class="button secondary" href="https://github.com/praktimarc/kst4contest/releases/download/v1.41.1/KST4Contest-v1.41.1-macos-x86_64.dmg">Download →</a>
|
||||
</article>
|
||||
|
||||
<article class="card download-card">
|
||||
@@ -193,7 +193,7 @@
|
||||
<p><strong>PDF</strong></p>
|
||||
<p>English PDF manual.</p>
|
||||
|
||||
<a class="button secondary" href="https://github.com/praktimarc/kst4contest/releases/download/v1.41.0/KST4Contest-v1.41.0-manual-en.pdf">Download →</a>
|
||||
<a class="button secondary" href="https://github.com/praktimarc/kst4contest/releases/download/v1.41.1/KST4Contest-v1.41.1-manual-en.pdf">Download →</a>
|
||||
</article>
|
||||
|
||||
<article class="card download-card">
|
||||
@@ -205,7 +205,7 @@
|
||||
<p><strong>PDF</strong></p>
|
||||
<p>German PDF manual.</p>
|
||||
|
||||
<a class="button secondary" href="https://github.com/praktimarc/kst4contest/releases/download/v1.41.0/KST4Contest-v1.41.0-manual-de.pdf">Download →</a>
|
||||
<a class="button secondary" href="https://github.com/praktimarc/kst4contest/releases/download/v1.41.1/KST4Contest-v1.41.1-manual-de.pdf">Download →</a>
|
||||
</article>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<meta name="twitter:title" content="KST4Contest FAQ">
|
||||
<meta name="twitter:description" content="Frequently asked questions about KST4Contest, ON4KST contest operation, AirScout integration and VHF/UHF/SHF contest workflow.">
|
||||
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783615687631">
|
||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||
|
||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||
@@ -47,12 +47,12 @@
|
||||
|
||||
<a href="/screenshots/">Screenshots</a>
|
||||
|
||||
<a href="/download/">Download</a>
|
||||
|
||||
<a href="/manual/">Manual</a>
|
||||
|
||||
<a href="/news/">News</a>
|
||||
|
||||
<a href="/roadmap/">Roadmap</a>
|
||||
|
||||
<a href="/about/">About</a>
|
||||
|
||||
<a href="/faq/">FAQ</a>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<meta name="twitter:title" content="AirScout Integration">
|
||||
<meta name="twitter:description" content="AirScout information helps operators evaluate AP windows, aircraft scatter timing and candidate stations during VHF/UHF/SHF contests.">
|
||||
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783615687631">
|
||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||
|
||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||
@@ -47,12 +47,12 @@
|
||||
|
||||
<a href="/screenshots/">Screenshots</a>
|
||||
|
||||
<a href="/download/">Download</a>
|
||||
|
||||
<a href="/manual/">Manual</a>
|
||||
|
||||
<a href="/news/">News</a>
|
||||
|
||||
<a href="/roadmap/">Roadmap</a>
|
||||
|
||||
<a href="/about/">About</a>
|
||||
|
||||
<a href="/faq/">FAQ</a>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<meta name="twitter:title" content="Dual Chat Categories">
|
||||
<meta name="twitter:description" content="Dual category support gives contest operators better overview when working across multiple ON4KST chat rooms.">
|
||||
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783615687631">
|
||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||
|
||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||
@@ -47,12 +47,12 @@
|
||||
|
||||
<a href="/screenshots/">Screenshots</a>
|
||||
|
||||
<a href="/download/">Download</a>
|
||||
|
||||
<a href="/manual/">Manual</a>
|
||||
|
||||
<a href="/news/">News</a>
|
||||
|
||||
<a href="/roadmap/">Roadmap</a>
|
||||
|
||||
<a href="/about/">About</a>
|
||||
|
||||
<a href="/faq/">FAQ</a>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<meta name="twitter:title" content="DXCluster Server">
|
||||
<meta name="twitter:description" content="KST4Contest includes DXCluster functionality to support situational awareness during contest operation.">
|
||||
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783615687631">
|
||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||
|
||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||
@@ -47,12 +47,12 @@
|
||||
|
||||
<a href="/screenshots/">Screenshots</a>
|
||||
|
||||
<a href="/download/">Download</a>
|
||||
|
||||
<a href="/manual/">Manual</a>
|
||||
|
||||
<a href="/news/">News</a>
|
||||
|
||||
<a href="/roadmap/">Roadmap</a>
|
||||
|
||||
<a href="/about/">About</a>
|
||||
|
||||
<a href="/faq/">FAQ</a>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<meta name="twitter:title" content="KST4Contest Features">
|
||||
<meta name="twitter:description" content="Contest-optimized ON4KST features for VHF, UHF and SHF operation.">
|
||||
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783615687631">
|
||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||
|
||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||
@@ -47,12 +47,12 @@
|
||||
|
||||
<a href="/screenshots/">Screenshots</a>
|
||||
|
||||
<a href="/download/">Download</a>
|
||||
|
||||
<a href="/manual/">Manual</a>
|
||||
|
||||
<a href="/news/">News</a>
|
||||
|
||||
<a href="/roadmap/">Roadmap</a>
|
||||
|
||||
<a href="/about/">About</a>
|
||||
|
||||
<a href="/faq/">FAQ</a>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<meta name="twitter:title" content="Log Synchronization">
|
||||
<meta name="twitter:description" content="Log synchronization helps KST4Contest understand worked stations, active bands and contest context.">
|
||||
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783615687631">
|
||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||
|
||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||
@@ -47,12 +47,12 @@
|
||||
|
||||
<a href="/screenshots/">Screenshots</a>
|
||||
|
||||
<a href="/download/">Download</a>
|
||||
|
||||
<a href="/manual/">Manual</a>
|
||||
|
||||
<a href="/news/">News</a>
|
||||
|
||||
<a href="/roadmap/">Roadmap</a>
|
||||
|
||||
<a href="/about/">About</a>
|
||||
|
||||
<a href="/faq/">FAQ</a>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<meta name="twitter:title" content="Macros and Variables">
|
||||
<meta name="twitter:description" content="Macros reduce repetitive typing and help operators respond quickly during active ON4KST contest sessions.">
|
||||
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783615687631">
|
||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||
|
||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||
@@ -47,12 +47,12 @@
|
||||
|
||||
<a href="/screenshots/">Screenshots</a>
|
||||
|
||||
<a href="/download/">Download</a>
|
||||
|
||||
<a href="/manual/">Manual</a>
|
||||
|
||||
<a href="/news/">News</a>
|
||||
|
||||
<a href="/roadmap/">Roadmap</a>
|
||||
|
||||
<a href="/about/">About</a>
|
||||
|
||||
<a href="/faq/">FAQ</a>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<meta name="twitter:title" content="Priority Score System">
|
||||
<meta name="twitter:description" content="KST4Contest ranks stations by activity, direction, sked context, band information, QRG hints and operator workflow signals.">
|
||||
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783615687631">
|
||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||
|
||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||
@@ -47,12 +47,12 @@
|
||||
|
||||
<a href="/screenshots/">Screenshots</a>
|
||||
|
||||
<a href="/download/">Download</a>
|
||||
|
||||
<a href="/manual/">Manual</a>
|
||||
|
||||
<a href="/news/">News</a>
|
||||
|
||||
<a href="/roadmap/">Roadmap</a>
|
||||
|
||||
<a href="/about/">About</a>
|
||||
|
||||
<a href="/faq/">FAQ</a>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<meta name="twitter:title" content="Sked Reminder">
|
||||
<meta name="twitter:description" content="KST4Contest keeps skeds in focus while the operator handles chat traffic, logging, bands and aircraft scatter timing.">
|
||||
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783615687631">
|
||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||
|
||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||
@@ -47,12 +47,12 @@
|
||||
|
||||
<a href="/screenshots/">Screenshots</a>
|
||||
|
||||
<a href="/download/">Download</a>
|
||||
|
||||
<a href="/manual/">Manual</a>
|
||||
|
||||
<a href="/news/">News</a>
|
||||
|
||||
<a href="/roadmap/">Roadmap</a>
|
||||
|
||||
<a href="/about/">About</a>
|
||||
|
||||
<a href="/faq/">FAQ</a>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<meta name="twitter:title" content="Timeline View">
|
||||
<meta name="twitter:description" content="The timeline view helps operators understand short propagation windows and candidate timing during active contest operation.">
|
||||
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783615687631">
|
||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||
|
||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||
@@ -47,12 +47,12 @@
|
||||
|
||||
<a href="/screenshots/">Screenshots</a>
|
||||
|
||||
<a href="/download/">Download</a>
|
||||
|
||||
<a href="/manual/">Manual</a>
|
||||
|
||||
<a href="/news/">News</a>
|
||||
|
||||
<a href="/roadmap/">Roadmap</a>
|
||||
|
||||
<a href="/about/">About</a>
|
||||
|
||||
<a href="/faq/">FAQ</a>
|
||||
|
||||
@@ -7,6 +7,14 @@
|
||||
<language>en</language>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Hotfix Version 1.41.1</title>
|
||||
<link>https://kst4contest.hamradioonline.de/news/2026-07-08-hotfix-version-1-41-1/</link>
|
||||
<guid>https://kst4contest.hamradioonline.de/news/2026-07-08-hotfix-version-1-41-1/</guid>
|
||||
<pubDate>Wed, 08 Jul 2026 00:00:00 GMT</pubDate>
|
||||
<description>Hotfix of a bug in Version 1.41</description>
|
||||
</item>
|
||||
|
||||
<item>
|
||||
<title>KST4Contest Website Launch</title>
|
||||
<link>https://kst4contest.hamradioonline.de/news/2026-07-website-launch/</link>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<meta name="twitter:title" content="KST4Contest – Contest-Optimized ON4KST Chat Client">
|
||||
<meta name="twitter:description" content="KST4Contest is a modern ON4KST chat client built for VHF, UHF and SHF contest operation.">
|
||||
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783615687631">
|
||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||
|
||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||
@@ -47,12 +47,12 @@
|
||||
|
||||
<a href="/screenshots/">Screenshots</a>
|
||||
|
||||
<a href="/download/">Download</a>
|
||||
|
||||
<a href="/manual/">Manual</a>
|
||||
|
||||
<a href="/news/">News</a>
|
||||
|
||||
<a href="/roadmap/">Roadmap</a>
|
||||
|
||||
<a href="/about/">About</a>
|
||||
|
||||
<a href="/faq/">FAQ</a>
|
||||
|
||||
@@ -0,0 +1,537 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<praktiKST>
|
||||
<latestVersion>
|
||||
<versionNumber>1.411</versionNumber>
|
||||
<adminMessage></adminMessage>
|
||||
<majorChanges>- Score of Top-Priority Candidates in the user section
|
||||
- Broadcast Messages (To ALL Station in Contest) in seperate Window</majorChanges>
|
||||
<latestVersionPathOnWebserver>https://github.com/praktimarc/kst4contest/releases/download/v1.41.1/praktiKST-v1.41.1-windows-x64.zip</latestVersionPathOnWebserver>
|
||||
</latestVersion>
|
||||
<needUpdateSinceLastVersion>
|
||||
<filename>nothing</filename>
|
||||
</needUpdateSinceLastVersion>
|
||||
<roadmap>
|
||||
<featurerequest>
|
||||
<featureDescription>Cyclic update of own name in chat to actual QRG</featureDescription>
|
||||
<requestDate>2024-02</requestDate>
|
||||
<state>open</state>
|
||||
</featurerequest>
|
||||
<featurerequest>
|
||||
<featureDescription>Acoustic warnings</featureDescription>
|
||||
<requestDate>2023-12</requestDate>
|
||||
<state>added</state>
|
||||
</featurerequest>
|
||||
<featurerequest>
|
||||
<featureDescription>Airscout support</featureDescription>
|
||||
<requestDate>2023-03</requestDate>
|
||||
<state>added</state>
|
||||
</featurerequest>
|
||||
<featurerequest>
|
||||
<featureDescription>cyclic beacon messages in public chat</featureDescription>
|
||||
<requestDate>2023-03</requestDate>
|
||||
<state>added</state>
|
||||
</featurerequest>
|
||||
</roadmap>
|
||||
<bugsReported>
|
||||
<bug>
|
||||
<bugdescription>
|
||||
stations like ol7c-7 and ol7c-2 will not be marked as worked if only "ol7c"
|
||||
is in the log. Need to interprete that. May ignore suffix starting with "-"</bugdescription>
|
||||
<state>solved</state>
|
||||
</bug>
|
||||
<bug>
|
||||
<bugdescription>
|
||||
worked callsigns table is updated only once after connected to chat
|
||||
Should be available directly after program started.
|
||||
But Reset works all time</bugdescription>
|
||||
<state>open</state>
|
||||
</bug>
|
||||
<bug>
|
||||
<bugdescription>feature request: language-specific strings, maybe based to an xml file
|
||||
</bugdescription>
|
||||
<state>open</state>
|
||||
</bug>
|
||||
<bug>
|
||||
<bugdescription>feature request: Macros
|
||||
</bugdescription>
|
||||
<state>added</state>
|
||||
</bug>
|
||||
<bug>
|
||||
<bugdescription>feature request:
|
||||
Automatic elimination of calls already connected from the log
|
||||
</bugdescription>
|
||||
<state>added</state>
|
||||
</bug>
|
||||
<bug>
|
||||
<bugdescription>feature request:
|
||||
Limitation of users beyond a certain QRB
|
||||
</bugdescription>
|
||||
<state>added</state>
|
||||
</bug>
|
||||
<bug>
|
||||
<bugdescription>feature request:
|
||||
User division for QTF perhaps settable based on the antenna lobe
|
||||
</bugdescription>
|
||||
<state>added</state>
|
||||
</bug>
|
||||
<bug>
|
||||
<bugdescription>feature request:
|
||||
Notification of new incoming users</bugdescription>
|
||||
<state>added</state>
|
||||
</bug>
|
||||
<bug>
|
||||
<bugdescription>feature request:
|
||||
Evidence of a call which was written but not responded to.
|
||||
</bugdescription>
|
||||
<state>added</state>
|
||||
</bug>
|
||||
<bug>
|
||||
<bugdescription>feature request:
|
||||
direction based reachable-warnings:
|
||||
if the chatclient detects a realised qso between two stations which both must have
|
||||
directed their beams to my station, there should be an instant warning to me for
|
||||
working at least one of the stations at the detected qrg</bugdescription>
|
||||
<state>open</state>
|
||||
</bug>
|
||||
<bug>
|
||||
<bugdescription>feature request:
|
||||
implement ASShowpath message to airacout;
|
||||
by doubleclicking a callsign in the chatmember list, the path and plane state should be
|
||||
provided by airscout </bugdescription>
|
||||
<state>open</state>
|
||||
</bug>
|
||||
<bug>
|
||||
<bugdescription>feature request:
|
||||
make chatlines copyable to the clipboard...</bugdescription>
|
||||
<state>open</state>
|
||||
</bug>
|
||||
<bug>
|
||||
<bugdescription>feature request:
|
||||
adding an activity detection for sensing if another chatmembers alive-state</bugdescription>
|
||||
<state>added</state>
|
||||
</bug>
|
||||
<bug>
|
||||
<bugdescription>On sql error close the connection to make a clean exit</bugdescription>
|
||||
<state>open</state>
|
||||
</bug>
|
||||
<bug>
|
||||
<bugdescription>SETNAME /MYQRG in options menu doesnt work</bugdescription>
|
||||
<state>solved</state>
|
||||
</bug>
|
||||
<bug>
|
||||
<bugdescription>Disconnect button does not work (DL5ZK)</bugdescription>
|
||||
<state>solved</state>
|
||||
</bug>
|
||||
<bug>
|
||||
<bugdescription>Password-wrong error not displayed (DO5SA)</bugdescription>
|
||||
<state>solved</state>
|
||||
</bug>
|
||||
<bug>
|
||||
<bugdescription>/CQ isnt written on own PMs</bugdescription>
|
||||
<state>solved</state>
|
||||
</bug>
|
||||
<bug>
|
||||
<bugdescription>rightclick-textsnippets arent available in cq-table</bugdescription>
|
||||
<state>solved</state>
|
||||
</bug>
|
||||
</bugsReported>
|
||||
<changeLog>
|
||||
<changedVersionNumber>1.411</changedVersionNumber>
|
||||
<date>2026-07-08</date>
|
||||
<description>Release v1.41.1</description>
|
||||
<added></added>
|
||||
<changed>Hotfix of Bug #56</changed>
|
||||
<fixed></fixed>
|
||||
<removed></removed>
|
||||
</changeLog>
|
||||
<changeLog>
|
||||
<changedVersionNumber>1.41</changedVersionNumber>
|
||||
<date>2026-07-01</date>
|
||||
<description>Release v1.41.0</description>
|
||||
<added>- Score of Top-Priority Candidates in the user section
|
||||
- Broadcast Messages (To ALL Station in Contest) in seperate Window</added>
|
||||
<changed>Migration to Github
|
||||
- Band and Frequency Detection per Chatmember — KST4Contest identifies which bands or frequencies a station appears active or reachable on based on chat data. This information is integrated into the display and prioritization.
|
||||
- Band Alert — If a logged station could be of interest on other locally active bands, KST14Contest can alert the user.
|
||||
- Sked Reminder ALERT — New reminder function for planned Skeds to ensure that agreed contacts are not forgotten during contest operation.
|
||||
- Skedfail Button — Failed Skeds can be marked; this allows the station to be handled differently in terms of score and workflow.
|
||||
- Win-Test SKED Push via UDP — Skeds can be passed to Win-Test via a LOCKSKED/ADDSKED/UNLOCKSKED sequence. This feature is configurable in the preferences and disabled by default.
|
||||
- Win-Test Broadcast Defaults and SKed Workflow — Improved broadcast addresses, frequency formats, mode selection, and notes including locator/azimuth.
|
||||
- PSTRotator Interface — KST4Contest received an interface to PSTRoter to better integrate antenna direction and rotator workflow.
|
||||
- QSO /-Callsign Sniffer — Callsigns or QSO-relevant information can be detected and utilized for further workflow.
|
||||
- Chat History at Startup — Historical chat data can be loaded upon startup, allowing the client to quickly gain relevant context for scoring, activity, and station identification.
|
||||
- Station Map / Map View — New map view with station markers, your own location, locator/Maidenhead reference, connection line, and antenna/beam representation.
|
||||
- Local Leaflet /-TileProxy Backend — The map function utilizes embedded Leaflet resources and a local TileProxy approach, making the map more portable and independent.
|
||||
- Maidenhead /-Grid Overlay — The map can display locator/grid information; recently added Grid-Square coloring.
|
||||
- Path /-Terrain /-Horizon Profile — Map documentation describes a path profile with terrain, Fresnel, and horizon information for the selected link.
|
||||
- Tropo /-AS Reachability Filters — New filters and sorting were added for Tropospheric reachability, AirScoop availability, large locator fields, and priority.
|
||||
- Reachability Band Selector — Added a band selection for range/Troposphere calculations.
|
||||
- 4-Char Locator Filter — Locator evaluations can be reduced to 4-character fields; this improves overview and performance.
|
||||
- KST Testserver Support — A KST server test server was added into the Source.
|
||||
@praktimarc and @Rsclub22</changed>
|
||||
<fixed>- [BUG]
|
||||
- [BUG] Programmstart kann ohne selektieren keine Nachrichten senden
|
||||
- KST4Contest crashes after to many messages or to much RAM Usage
|
||||
- Scaling Problem at 1280x800 screen resolution</fixed>
|
||||
<removed></removed>
|
||||
</changeLog>
|
||||
<changeLog>
|
||||
<changedVersionNumber>1.40</changedVersionNumber>
|
||||
<date>2026-02-16</date>
|
||||
<description>Much changes and fixes</description>
|
||||
<added>
|
||||
- win-test support (not deactivable yet, beta)
|
||||
- QSO sniffer which filters changable callsigns lists messages to your pm window
|
||||
- Chatmember Score system. Each chatmember gets a score depending to antenna direction, activity time,
|
||||
activity msgcount, positive signals, active bands, active frequencies, his sked direction (degrees),
|
||||
self handed rate, sked-made-rate and some others
|
||||
- Chatmember Band and frequency recognition: now we list all active bands of each other chatmember
|
||||
- Band alert for logged stations
|
||||
- Sked reminder ALERT with automatic messages in 2+1 / 5+2+1 / 10+5+2+1 minutes
|
||||
- PSTRotator interface
|
||||
- AirPlane Timeline
|
||||
- Skedfail button in furtherinfo panel
|
||||
- Wintest logsynch interface can now be activated and deactivated in the preferences
|
||||
- load chat history on startup
|
||||
</added>
|
||||
<changed>
|
||||
- added save option: ServerDNS / Port
|
||||
- added save option: activate/deactivate pstRotator interface
|
||||
- added save option: activate/deactivate wintest interface
|
||||
- added save option: callsign sniffer
|
||||
- added save option: boolean GUI_darkModeActiveByDefault = false
|
||||
- added AP notes at the internal DX cluster spots
|
||||
- Generic Autoanswer fires maximum once in 45 seconds per rx callsign
|
||||
</changed>
|
||||
<fixed>
|
||||
- Userlist sort automatically on new member signon
|
||||
- Posonpill-messages now kills only exactly one Client instance (bugreport 9A2HM)
|
||||
- Crash of wtkst by disconnection of kst4Contest
|
||||
- wtKST crashes when kst4contest is running (many reporters)
|
||||
- wintest: logged per band excludes pre worked band (bugreport SM6VTZ)
|
||||
- PSTRotator SOCKET Close on DISCONNECT BUTTON works now
|
||||
- AirScout Map had not been updated (bugreport SM0RJV)
|
||||
- QTFDefault had been not saved correctly (bugreport SM0RJV)
|
||||
- Show path in AS button worked only with fixed server Strings (bugreport 9A2HM)
|
||||
- Version number had been displayed wrong
|
||||
- suffixes like /p, -2, etc. problem now fixed everywhere
|
||||
- Dark mode: passing for qrg fields fix
|
||||
</fixed>
|
||||
<removed>
|
||||
- No more date display. Not needed. Saving space, only time is important
|
||||
</removed>
|
||||
</changeLog>
|
||||
<changeLog>
|
||||
<changedVersionNumber>1.31</changedVersionNumber>
|
||||
<date>2025-12-13</date>
|
||||
<description>Much changes and a hotfix</description>
|
||||
<added>
|
||||
- win-test support (not deactivable yet, beta)
|
||||
- pstRotator support (not deactivable yet, beta)
|
||||
- airScout fix (calculations depends to cpu load now)
|
||||
- QSO sniffer
|
||||
</added>
|
||||
<changed>
|
||||
- DNS from www.on4kst.info to www.on4kst.org (hotfix, now configurable in preferences)
|
||||
</changed>
|
||||
<fixed>
|
||||
- Endless loop in error case lets freeze the client
|
||||
- PSTRotator SOCKET Close on DISCONNECT BUTTON
|
||||
- Dark mode: passing for qrg fields fix
|
||||
</fixed>
|
||||
<removed></removed>
|
||||
</changeLog>
|
||||
<changeLog>
|
||||
<changedVersionNumber>1.266</changedVersionNumber>
|
||||
<date>2025-10-03</date>
|
||||
<description>Airscout interface did not work with multi-signons</description>
|
||||
<added>nothing</added>
|
||||
<changed>nothing</changed>
|
||||
<fixed>
|
||||
Fixed by using raw callsign (without -2 suffix etc.) when communicating with AirScout.
|
||||
Thank you very much for testing this, Kreso 9A2HM!
|
||||
</fixed>
|
||||
<removed></removed>
|
||||
</changeLog>
|
||||
<changeLog>
|
||||
<changedVersionNumber>1.265</changedVersionNumber>
|
||||
<date>2025-09-28</date>
|
||||
<description>Direction buttons stay now colored, if activated</description>
|
||||
<added>nothing</added>
|
||||
<changed>nothing</changed>
|
||||
<fixed>The buttons stay now colored, if activated</fixed>
|
||||
<removed></removed>
|
||||
</changeLog>
|
||||
<changeLog>
|
||||
<changedVersionNumber>1.264</changedVersionNumber>
|
||||
<date>2025-08-02</date>
|
||||
<description>Changed the callsign recognition pattern for Simplelogfile</description>
|
||||
<added>nothing</added>
|
||||
<changed>nothing</changed>
|
||||
<fixed>
|
||||
Callsigns like S53CC, S51A etc. are now correctly marked as worked in SimpleLogFile.txt.
|
||||
(bugreport Boris, S53CC)
|
||||
</fixed>
|
||||
<removed></removed>
|
||||
</changeLog>
|
||||
<changeLog>
|
||||
<changedVersionNumber>1.263</changedVersionNumber>
|
||||
<date>2025-06-08</date>
|
||||
<description>Airscout communication and Loginname</description>
|
||||
<added>nothing</added>
|
||||
<changed>
|
||||
Only entries with QRB lower than max-QRB are sent to AirScout in 60s intervals (was 12s for all).
|
||||
</changed>
|
||||
<fixed>
|
||||
- AS communication message count hugely reduced
|
||||
- Name in chat is now saveable
|
||||
- Fixed AS client name (was hard-wired to "KST")
|
||||
73 / DO5AMF
|
||||
</fixed>
|
||||
<removed></removed>
|
||||
</changeLog>
|
||||
<changeLog>
|
||||
<changedVersionNumber>1.262</changedVersionNumber>
|
||||
<date>2025-05-21</date>
|
||||
<description>Freezes caused by getting messages before user login should be fixed now</description>
|
||||
<added>nothing</added>
|
||||
<changed>nothing</changed>
|
||||
<fixed>
|
||||
ON4KST delivers messages of stations not yet logged in. That caused a freeze at the message
|
||||
processing engine which is now fixed.
|
||||
</fixed>
|
||||
<removed></removed>
|
||||
</changeLog>
|
||||
<changeLog>
|
||||
<changedVersionNumber>1.26</changedVersionNumber>
|
||||
<date>2025-05</date>
|
||||
<description>Login to multiple Channels via single signon / spend some colors</description>
|
||||
<added>
|
||||
1. UI: Dark mode. Switch in "Window -> use dark mode"
|
||||
2. Usage of two Chatcategories at the same time
|
||||
3. opposite station multi-callsign login-tagging
|
||||
73 / DO5AMF
|
||||
</added>
|
||||
<changed>
|
||||
- Coloring mechanic of the software. Modify colors via css by yourself...
|
||||
</changed>
|
||||
<fixed>
|
||||
- Station tagging fixed completely
|
||||
</fixed>
|
||||
<removed></removed>
|
||||
</changeLog>
|
||||
<changeLog>
|
||||
<changedVersionNumber>1.251</changedVersionNumber>
|
||||
<date>2025-02</date>
|
||||
<description>BUGFIX of 1.25, tnx Steve Clements!</description>
|
||||
<added>
|
||||
- Steve spotted a problem in udp broadcast spot info reading, its now fixed!
|
||||
73 / DO5AMF
|
||||
</added>
|
||||
<changed></changed>
|
||||
<fixed>- Station tagging</fixed>
|
||||
<removed></removed>
|
||||
</changeLog>
|
||||
<changeLog>
|
||||
<changedVersionNumber>1.25</changedVersionNumber>
|
||||
<date>2025-02</date>
|
||||
<description>Wishlist-time</description>
|
||||
<added>
|
||||
- New configuration Tab: Messagehandling (auto-answering, CQ qrg auto-answer)
|
||||
- Coloured lines: new pm rows appear in red, fade rainbow-like to white over 30s (tnx Gianluca)
|
||||
73 / DO5AMF
|
||||
</added>
|
||||
<changed></changed>
|
||||
<fixed>
|
||||
- Users with suffixes like "-2 and -70" are now correctly marked as worked
|
||||
</fixed>
|
||||
<removed></removed>
|
||||
</changeLog>
|
||||
<changeLog>
|
||||
<changedVersionNumber>1.24</changedVersionNumber>
|
||||
<date>2024-11</date>
|
||||
<description>Wishlist-time</description>
|
||||
<added>
|
||||
- Button to show qrz.com profile of a selected station
|
||||
- Button to show qrzcq.com profile of a selected station
|
||||
</added>
|
||||
<changed></changed>
|
||||
<fixed></fixed>
|
||||
<removed></removed>
|
||||
</changeLog>
|
||||
<changeLog>
|
||||
<changedVersionNumber>1.23</changedVersionNumber>
|
||||
<date>2024-10</date>
|
||||
<description>DXCluster Server is now implemented</description>
|
||||
<added>
|
||||
- DXCluster Server (tnx OMAAO): KST4Contest now provides a DXCluster server to feed
|
||||
your log client with station-reachable warnings.
|
||||
</added>
|
||||
<changed></changed>
|
||||
<fixed></fixed>
|
||||
<removed></removed>
|
||||
</changeLog>
|
||||
<changeLog>
|
||||
<changedVersionNumber>1.22</changedVersionNumber>
|
||||
<date>2024-05</date>
|
||||
<description>Increase usability, fixed AS button</description>
|
||||
<added>- Variables (tnx OMAAO): MYLOCATORSHORT, MYQRGSHORT, QRZNAME</added>
|
||||
<changed>- Sendtext-field focus on callsign click</changed>
|
||||
<fixed>
|
||||
- Worked-station-filter (tnx Gianluca): filter is now live
|
||||
- Chatters list sorting by QRB (tnx Alessandro): fixed to numeric sort
|
||||
- Airscout showpath button now maximizes AS and shows the path
|
||||
</fixed>
|
||||
<removed></removed>
|
||||
</changeLog>
|
||||
<changeLog>
|
||||
<changedVersionNumber>1.21</changedVersionNumber>
|
||||
<date>2024-04</date>
|
||||
<description>Increase usability</description>
|
||||
<added></added>
|
||||
<changed>
|
||||
- Window sizes and divider positions are now stored and restored on next startup
|
||||
- Filters section is now a flowpane for lower resolutions
|
||||
</changed>
|
||||
<fixed></fixed>
|
||||
<removed></removed>
|
||||
</changeLog>
|
||||
<changeLog>
|
||||
<changedVersionNumber>1.2</changedVersionNumber>
|
||||
<date>2024-04</date>
|
||||
<description>Increase usability</description>
|
||||
<added>
|
||||
- Selectable bands
|
||||
- Unworkable tags for each callsign per band
|
||||
- QTF-Arrow on the "show path in AS" button
|
||||
</added>
|
||||
<changed></changed>
|
||||
<fixed></fixed>
|
||||
<removed></removed>
|
||||
</changeLog>
|
||||
<changeLog>
|
||||
<changedVersionNumber>1.1</changedVersionNumber>
|
||||
<date>2024-03</date>
|
||||
<description>Increased workflow</description>
|
||||
<added>
|
||||
- Reachable warning function
|
||||
- Variables FIRSTAP and SECONDAP for predefined texts
|
||||
- Marking new connected stations (bold) and away-state (brackets)
|
||||
- Activity-timer since last message of a chatter
|
||||
</added>
|
||||
<changed>- QRB/QTF info in pm-window</changed>
|
||||
<fixed>
|
||||
- Behaviour of messagefilter-radiobutton corrected (tnx Gian)
|
||||
- Error sending macros on selected stations in pm window (tnx Gian)
|
||||
</fixed>
|
||||
<removed>- boot sound</removed>
|
||||
</changeLog>
|
||||
<changeLog>
|
||||
<changedVersionNumber>1.0</changedVersionNumber>
|
||||
<date>2024-02</date>
|
||||
<description>First stable release</description>
|
||||
<added>
|
||||
- audio notification support
|
||||
- update-available warning
|
||||
- changelog displaying
|
||||
- known-bugs displaying
|
||||
- message filters for selected station
|
||||
- stationlist-filters (show by qtf / textstring, hide by qrb, qtf, workedstate)
|
||||
- 10 macros (textsnippets available by hitting strg+numberkey)
|
||||
</added>
|
||||
<changed></changed>
|
||||
<fixed></fixed>
|
||||
<removed></removed>
|
||||
</changeLog>
|
||||
<changeLog>
|
||||
<changedVersionNumber>0.9</changedVersionNumber>
|
||||
<date>2024-02</date>
|
||||
<description>Now the chat is disconnectable without closing it</description>
|
||||
<added></added>
|
||||
<changed></changed>
|
||||
<fixed>disconnect-button, Textsnippets in CQ Window, "/CQ" at click on own sendtexts,
|
||||
setname "qrg" works now</fixed>
|
||||
<removed></removed>
|
||||
</changeLog>
|
||||
<changeLog>
|
||||
<changedVersionNumber>0.8</changedVersionNumber>
|
||||
<date>2023-10</date>
|
||||
<description>savesettings function and disconnect function added. MYCALL-Highlighting fixed</description>
|
||||
<added>savesettings function, disconnect function</added>
|
||||
<changed></changed>
|
||||
<fixed>MYCALL-Highlighting</fixed>
|
||||
<removed></removed>
|
||||
</changeLog>
|
||||
<changeLog>
|
||||
<changedVersionNumber>0.7</changedVersionNumber>
|
||||
<date>2023-07</date>
|
||||
<description>Internal database for worked stations, shortcut and textsnippet editor</description>
|
||||
<added>database, shortcut-editor, textsnipped-editor</added>
|
||||
<changed></changed>
|
||||
<fixed></fixed>
|
||||
<removed></removed>
|
||||
</changeLog>
|
||||
<changeLog>
|
||||
<changedVersionNumber>0.6</changedVersionNumber>
|
||||
<date>2023-07</date>
|
||||
<description>Added periodically sent beacon function</description>
|
||||
<added>beacon to public channel</added>
|
||||
<changed></changed>
|
||||
<fixed></fixed>
|
||||
<removed></removed>
|
||||
</changeLog>
|
||||
<changeLog>
|
||||
<changedVersionNumber>0.5</changedVersionNumber>
|
||||
<date>2023-02</date>
|
||||
<description>Airscout interface, UDP interfaces for worked-station data and TRX info, shortcuts</description>
|
||||
<added>Airscout-interface, packetreceiver for ucxlog, n1mm, qartest</added>
|
||||
<changed></changed>
|
||||
<fixed></fixed>
|
||||
<removed></removed>
|
||||
</changeLog>
|
||||
<changeLog>
|
||||
<changedVersionNumber>0.4</changedVersionNumber>
|
||||
<date>2022-12</date>
|
||||
<description>Worked info by logfile via universal pattern matching logfile interpreter</description>
|
||||
<added>simple-logfile</added>
|
||||
<changed></changed>
|
||||
<fixed></fixed>
|
||||
<removed></removed>
|
||||
</changeLog>
|
||||
<changeLog>
|
||||
<changedVersionNumber>0.3</changedVersionNumber>
|
||||
<date>2022-10</date>
|
||||
<description>Added a GUI, chat was text based only</description>
|
||||
<added>Graphical user interface</added>
|
||||
<changed></changed>
|
||||
<fixed></fixed>
|
||||
<removed></removed>
|
||||
</changeLog>
|
||||
<changeLog>
|
||||
<changedVersionNumber>0.2</changedVersionNumber>
|
||||
<date>2022-10</date>
|
||||
<description>Pattern matching system for frequency information, frequency collection per chatmember</description>
|
||||
<added>frequency-extraction for every callsign</added>
|
||||
<changed></changed>
|
||||
<fixed></fixed>
|
||||
<removed></removed>
|
||||
</changeLog>
|
||||
<changeLog>
|
||||
<changedVersionNumber>0.15</changedVersionNumber>
|
||||
<date>2022-09</date>
|
||||
<description>Researched the Chatprotocol and developed the base communication with the chatserver</description>
|
||||
<added></added>
|
||||
<changed></changed>
|
||||
<fixed></fixed>
|
||||
<removed></removed>
|
||||
</changeLog>
|
||||
<changeLog>
|
||||
<changedVersionNumber>0.1</changedVersionNumber>
|
||||
<date>2022-09</date>
|
||||
<description>Primary architecture of the chat, message bus system for handling the message queues</description>
|
||||
<added></added>
|
||||
<changed></changed>
|
||||
<fixed></fixed>
|
||||
<removed></removed>
|
||||
</changeLog>
|
||||
</praktiKST>
|
||||
@@ -17,7 +17,7 @@
|
||||
<meta name="twitter:title" content="Legal Notice | KST4Contest">
|
||||
<meta name="twitter:description" content="Legal notice for the KST4Contest website.">
|
||||
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783615687631">
|
||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||
|
||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||
@@ -47,12 +47,12 @@
|
||||
|
||||
<a href="/screenshots/">Screenshots</a>
|
||||
|
||||
<a href="/download/">Download</a>
|
||||
|
||||
<a href="/manual/">Manual</a>
|
||||
|
||||
<a href="/news/">News</a>
|
||||
|
||||
<a href="/roadmap/">Roadmap</a>
|
||||
|
||||
<a href="/about/">About</a>
|
||||
|
||||
<a href="/faq/">FAQ</a>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
|
||||
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
|
||||
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783615687631">
|
||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||
|
||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||
@@ -47,12 +47,12 @@
|
||||
|
||||
<a href="/screenshots/">Screenshots</a>
|
||||
|
||||
<a href="/download/">Download</a>
|
||||
|
||||
<a href="/manual/">Manual</a>
|
||||
|
||||
<a href="/news/">News</a>
|
||||
|
||||
<a href="/roadmap/">Roadmap</a>
|
||||
|
||||
<a href="/about/">About</a>
|
||||
|
||||
<a href="/faq/">FAQ</a>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
|
||||
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
|
||||
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783615687631">
|
||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||
|
||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||
@@ -47,12 +47,12 @@
|
||||
|
||||
<a href="/screenshots/">Screenshots</a>
|
||||
|
||||
<a href="/download/">Download</a>
|
||||
|
||||
<a href="/manual/">Manual</a>
|
||||
|
||||
<a href="/news/">News</a>
|
||||
|
||||
<a href="/roadmap/">Roadmap</a>
|
||||
|
||||
<a href="/about/">About</a>
|
||||
|
||||
<a href="/faq/">FAQ</a>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
|
||||
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
|
||||
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783615687631">
|
||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||
|
||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||
@@ -47,12 +47,12 @@
|
||||
|
||||
<a href="/screenshots/">Screenshots</a>
|
||||
|
||||
<a href="/download/">Download</a>
|
||||
|
||||
<a href="/manual/">Manual</a>
|
||||
|
||||
<a href="/news/">News</a>
|
||||
|
||||
<a href="/roadmap/">Roadmap</a>
|
||||
|
||||
<a href="/about/">About</a>
|
||||
|
||||
<a href="/faq/">FAQ</a>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
|
||||
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
|
||||
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783615687631">
|
||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||
|
||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||
@@ -47,12 +47,12 @@
|
||||
|
||||
<a href="/screenshots/">Screenshots</a>
|
||||
|
||||
<a href="/download/">Download</a>
|
||||
|
||||
<a href="/manual/">Manual</a>
|
||||
|
||||
<a href="/news/">News</a>
|
||||
|
||||
<a href="/roadmap/">Roadmap</a>
|
||||
|
||||
<a href="/about/">About</a>
|
||||
|
||||
<a href="/faq/">FAQ</a>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
|
||||
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
|
||||
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783615687631">
|
||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||
|
||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||
@@ -47,12 +47,12 @@
|
||||
|
||||
<a href="/screenshots/">Screenshots</a>
|
||||
|
||||
<a href="/download/">Download</a>
|
||||
|
||||
<a href="/manual/">Manual</a>
|
||||
|
||||
<a href="/news/">News</a>
|
||||
|
||||
<a href="/roadmap/">Roadmap</a>
|
||||
|
||||
<a href="/about/">About</a>
|
||||
|
||||
<a href="/faq/">FAQ</a>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
|
||||
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
|
||||
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783615687631">
|
||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||
|
||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||
@@ -47,12 +47,12 @@
|
||||
|
||||
<a href="/screenshots/">Screenshots</a>
|
||||
|
||||
<a href="/download/">Download</a>
|
||||
|
||||
<a href="/manual/">Manual</a>
|
||||
|
||||
<a href="/news/">News</a>
|
||||
|
||||
<a href="/roadmap/">Roadmap</a>
|
||||
|
||||
<a href="/about/">About</a>
|
||||
|
||||
<a href="/faq/">FAQ</a>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<meta name="twitter:title" content="KST4Contest Deutsches Handbuch">
|
||||
<meta name="twitter:description" content="Deutsches Benutzerhandbuch für KST4Contest.">
|
||||
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783615687631">
|
||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||
|
||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||
@@ -47,12 +47,12 @@
|
||||
|
||||
<a href="/screenshots/">Screenshots</a>
|
||||
|
||||
<a href="/download/">Download</a>
|
||||
|
||||
<a href="/manual/">Manual</a>
|
||||
|
||||
<a href="/news/">News</a>
|
||||
|
||||
<a href="/roadmap/">Roadmap</a>
|
||||
|
||||
<a href="/about/">About</a>
|
||||
|
||||
<a href="/faq/">FAQ</a>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
|
||||
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
|
||||
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783615687631">
|
||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||
|
||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||
@@ -47,12 +47,12 @@
|
||||
|
||||
<a href="/screenshots/">Screenshots</a>
|
||||
|
||||
<a href="/download/">Download</a>
|
||||
|
||||
<a href="/manual/">Manual</a>
|
||||
|
||||
<a href="/news/">News</a>
|
||||
|
||||
<a href="/roadmap/">Roadmap</a>
|
||||
|
||||
<a href="/about/">About</a>
|
||||
|
||||
<a href="/faq/">FAQ</a>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
|
||||
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
|
||||
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783615687631">
|
||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||
|
||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||
@@ -47,12 +47,12 @@
|
||||
|
||||
<a href="/screenshots/">Screenshots</a>
|
||||
|
||||
<a href="/download/">Download</a>
|
||||
|
||||
<a href="/manual/">Manual</a>
|
||||
|
||||
<a href="/news/">News</a>
|
||||
|
||||
<a href="/roadmap/">Roadmap</a>
|
||||
|
||||
<a href="/about/">About</a>
|
||||
|
||||
<a href="/faq/">FAQ</a>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
|
||||
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
|
||||
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783615687631">
|
||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||
|
||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||
@@ -47,12 +47,12 @@
|
||||
|
||||
<a href="/screenshots/">Screenshots</a>
|
||||
|
||||
<a href="/download/">Download</a>
|
||||
|
||||
<a href="/manual/">Manual</a>
|
||||
|
||||
<a href="/news/">News</a>
|
||||
|
||||
<a href="/roadmap/">Roadmap</a>
|
||||
|
||||
<a href="/about/">About</a>
|
||||
|
||||
<a href="/faq/">FAQ</a>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
|
||||
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
|
||||
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783615687631">
|
||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||
|
||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||
@@ -47,12 +47,12 @@
|
||||
|
||||
<a href="/screenshots/">Screenshots</a>
|
||||
|
||||
<a href="/download/">Download</a>
|
||||
|
||||
<a href="/manual/">Manual</a>
|
||||
|
||||
<a href="/news/">News</a>
|
||||
|
||||
<a href="/roadmap/">Roadmap</a>
|
||||
|
||||
<a href="/about/">About</a>
|
||||
|
||||
<a href="/faq/">FAQ</a>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
|
||||
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
|
||||
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783615687631">
|
||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||
|
||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||
@@ -47,12 +47,12 @@
|
||||
|
||||
<a href="/screenshots/">Screenshots</a>
|
||||
|
||||
<a href="/download/">Download</a>
|
||||
|
||||
<a href="/manual/">Manual</a>
|
||||
|
||||
<a href="/news/">News</a>
|
||||
|
||||
<a href="/roadmap/">Roadmap</a>
|
||||
|
||||
<a href="/about/">About</a>
|
||||
|
||||
<a href="/faq/">FAQ</a>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
|
||||
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
|
||||
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783615687631">
|
||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||
|
||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||
@@ -47,12 +47,12 @@
|
||||
|
||||
<a href="/screenshots/">Screenshots</a>
|
||||
|
||||
<a href="/download/">Download</a>
|
||||
|
||||
<a href="/manual/">Manual</a>
|
||||
|
||||
<a href="/news/">News</a>
|
||||
|
||||
<a href="/roadmap/">Roadmap</a>
|
||||
|
||||
<a href="/about/">About</a>
|
||||
|
||||
<a href="/faq/">FAQ</a>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
|
||||
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
|
||||
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783615687631">
|
||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||
|
||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||
@@ -47,12 +47,12 @@
|
||||
|
||||
<a href="/screenshots/">Screenshots</a>
|
||||
|
||||
<a href="/download/">Download</a>
|
||||
|
||||
<a href="/manual/">Manual</a>
|
||||
|
||||
<a href="/news/">News</a>
|
||||
|
||||
<a href="/roadmap/">Roadmap</a>
|
||||
|
||||
<a href="/about/">About</a>
|
||||
|
||||
<a href="/faq/">FAQ</a>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
|
||||
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
|
||||
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783615687631">
|
||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||
|
||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||
@@ -47,12 +47,12 @@
|
||||
|
||||
<a href="/screenshots/">Screenshots</a>
|
||||
|
||||
<a href="/download/">Download</a>
|
||||
|
||||
<a href="/manual/">Manual</a>
|
||||
|
||||
<a href="/news/">News</a>
|
||||
|
||||
<a href="/roadmap/">Roadmap</a>
|
||||
|
||||
<a href="/about/">About</a>
|
||||
|
||||
<a href="/faq/">FAQ</a>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
|
||||
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
|
||||
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783615687631">
|
||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||
|
||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||
@@ -47,12 +47,12 @@
|
||||
|
||||
<a href="/screenshots/">Screenshots</a>
|
||||
|
||||
<a href="/download/">Download</a>
|
||||
|
||||
<a href="/manual/">Manual</a>
|
||||
|
||||
<a href="/news/">News</a>
|
||||
|
||||
<a href="/roadmap/">Roadmap</a>
|
||||
|
||||
<a href="/about/">About</a>
|
||||
|
||||
<a href="/faq/">FAQ</a>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
|
||||
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
|
||||
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783615687631">
|
||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||
|
||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||
@@ -47,12 +47,12 @@
|
||||
|
||||
<a href="/screenshots/">Screenshots</a>
|
||||
|
||||
<a href="/download/">Download</a>
|
||||
|
||||
<a href="/manual/">Manual</a>
|
||||
|
||||
<a href="/news/">News</a>
|
||||
|
||||
<a href="/roadmap/">Roadmap</a>
|
||||
|
||||
<a href="/about/">About</a>
|
||||
|
||||
<a href="/faq/">FAQ</a>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<meta name="twitter:title" content="KST4Contest English Manual">
|
||||
<meta name="twitter:description" content="English user manual for KST4Contest.">
|
||||
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783615687631">
|
||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||
|
||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||
@@ -47,12 +47,12 @@
|
||||
|
||||
<a href="/screenshots/">Screenshots</a>
|
||||
|
||||
<a href="/download/">Download</a>
|
||||
|
||||
<a href="/manual/">Manual</a>
|
||||
|
||||
<a href="/news/">News</a>
|
||||
|
||||
<a href="/roadmap/">Roadmap</a>
|
||||
|
||||
<a href="/about/">About</a>
|
||||
|
||||
<a href="/faq/">FAQ</a>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
|
||||
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
|
||||
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783615687631">
|
||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||
|
||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||
@@ -47,12 +47,12 @@
|
||||
|
||||
<a href="/screenshots/">Screenshots</a>
|
||||
|
||||
<a href="/download/">Download</a>
|
||||
|
||||
<a href="/manual/">Manual</a>
|
||||
|
||||
<a href="/news/">News</a>
|
||||
|
||||
<a href="/roadmap/">Roadmap</a>
|
||||
|
||||
<a href="/about/">About</a>
|
||||
|
||||
<a href="/faq/">FAQ</a>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
|
||||
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
|
||||
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783615687631">
|
||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||
|
||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||
@@ -47,12 +47,12 @@
|
||||
|
||||
<a href="/screenshots/">Screenshots</a>
|
||||
|
||||
<a href="/download/">Download</a>
|
||||
|
||||
<a href="/manual/">Manual</a>
|
||||
|
||||
<a href="/news/">News</a>
|
||||
|
||||
<a href="/roadmap/">Roadmap</a>
|
||||
|
||||
<a href="/about/">About</a>
|
||||
|
||||
<a href="/faq/">FAQ</a>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
|
||||
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
|
||||
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783615687631">
|
||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||
|
||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||
@@ -47,12 +47,12 @@
|
||||
|
||||
<a href="/screenshots/">Screenshots</a>
|
||||
|
||||
<a href="/download/">Download</a>
|
||||
|
||||
<a href="/manual/">Manual</a>
|
||||
|
||||
<a href="/news/">News</a>
|
||||
|
||||
<a href="/roadmap/">Roadmap</a>
|
||||
|
||||
<a href="/about/">About</a>
|
||||
|
||||
<a href="/faq/">FAQ</a>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
|
||||
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
|
||||
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783615687631">
|
||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||
|
||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||
@@ -47,12 +47,12 @@
|
||||
|
||||
<a href="/screenshots/">Screenshots</a>
|
||||
|
||||
<a href="/download/">Download</a>
|
||||
|
||||
<a href="/manual/">Manual</a>
|
||||
|
||||
<a href="/news/">News</a>
|
||||
|
||||
<a href="/roadmap/">Roadmap</a>
|
||||
|
||||
<a href="/about/">About</a>
|
||||
|
||||
<a href="/faq/">FAQ</a>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<meta name="twitter:title" content="KST4Contest Manual">
|
||||
<meta name="twitter:description" content="Online manual for KST4Contest, the contest-optimized ON4KST chat client.">
|
||||
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783615687631">
|
||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||
|
||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||
@@ -47,12 +47,12 @@
|
||||
|
||||
<a href="/screenshots/">Screenshots</a>
|
||||
|
||||
<a href="/download/">Download</a>
|
||||
|
||||
<a href="/manual/">Manual</a>
|
||||
|
||||
<a href="/news/">News</a>
|
||||
|
||||
<a href="/roadmap/">Roadmap</a>
|
||||
|
||||
<a href="/about/">About</a>
|
||||
|
||||
<a href="/faq/">FAQ</a>
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Hotfix Version 1.41.1</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="description" content="KST4Contest is a contest-optimized ON4KST chat client for VHF, UHF and SHF ham radio contests.">
|
||||
<link rel="canonical" href="https://kst4contest.hamradioonline.de/news/2026-07-08-hotfix-version-1-41-1/">
|
||||
|
||||
<meta property="og:type" content="website">
|
||||
<meta property="og:title" content="Hotfix Version 1.41.1">
|
||||
<meta property="og:description" content="Contest-optimized ON4KST chat client for VHF, UHF and SHF ham radio contests.">
|
||||
<meta property="og:url" content="https://kst4contest.hamradioonline.de/news/2026-07-08-hotfix-version-1-41-1/">
|
||||
<meta property="og:site_name" content="KST4Contest">
|
||||
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
<meta name="twitter:title" content="Hotfix Version 1.41.1">
|
||||
<meta name="twitter:description" content="Contest-optimized ON4KST chat client for VHF, UHF and SHF ham radio contests.">
|
||||
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783615687631">
|
||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||
|
||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||
<meta property="og:image:width" content="1200">
|
||||
<meta property="og:image:height" content="630">
|
||||
<meta name="twitter:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="site-bg"></div>
|
||||
|
||||
<header class="site-header">
|
||||
<a class="brand" href="/">
|
||||
<span class="brand-mark">◎</span>
|
||||
<span>
|
||||
<strong>KST4Contest</strong>
|
||||
<small>ON4KST Contest Client</small>
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<nav class="site-nav">
|
||||
|
||||
<a href="/">Home</a>
|
||||
|
||||
<a href="/features/">Features</a>
|
||||
|
||||
<a href="/screenshots/">Screenshots</a>
|
||||
|
||||
<a href="/manual/">Manual</a>
|
||||
|
||||
<a href="/news/">News</a>
|
||||
|
||||
<a href="/roadmap/">Roadmap</a>
|
||||
|
||||
<a href="/about/">About</a>
|
||||
|
||||
<a href="/faq/">FAQ</a>
|
||||
|
||||
<a class="nav-cta" href="/download/">Download</a>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
|
||||
<section class="hero">
|
||||
<p class="badge">News · July 8, 2026</p>
|
||||
<h1>Hotfix Version 1.41.1</h1>
|
||||
<p class="lead">Hotfix of a bug in Version 1.41</p>
|
||||
</section>
|
||||
|
||||
<section class="section narrow">
|
||||
<article class="card content-card">
|
||||
<h2>Version 1.41.1</h2>
|
||||
<p>We had a bug, where KST4Contest would clear out the text field, where you would send your messages after a period. It also happend to set your Cursor back to the Sending Field, when you were filtering for a station. We fixed this bug today. The new release is <a href="https://github.com/praktimarc/kst4contest/releases/tag/v1.41.1">here</a>. You can also download the artifacts as always via the <a href="/download/">Downloads-Page</a>.</p>
|
||||
|
||||
</article>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<footer class="site-footer">
|
||||
<div class="footer-grid">
|
||||
<div>
|
||||
<strong>KST4Contest</strong>
|
||||
<p>Contest-optimized ON4KST workflow for VHF/UHF/SHF operators.</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<strong>Project</strong>
|
||||
<p><a href="/features/">Features</a></p>
|
||||
<p><a href="/download/">Download</a></p>
|
||||
<p><a href="/manual/">Manual</a></p>
|
||||
<p><a href="/roadmap/">Roadmap</a></p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<strong>Community</strong>
|
||||
<p><a href="https://github.com/praktimarc/kst4contest">GitHub Repository</a></p>
|
||||
<p><a href="https://github.com/praktimarc/kst4contest/issues">Issues</a></p>
|
||||
<p><a href="/contact/">Contact</a></p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<strong>Legal</strong>
|
||||
<p><a href="/legal-notice/">Legal Notice</a></p>
|
||||
<p><a href="/privacy/">Privacy Policy</a></p>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -17,7 +17,7 @@
|
||||
<meta name="twitter:title" content="KST4Contest Website Launch">
|
||||
<meta name="twitter:description" content="Contest-optimized ON4KST chat client for VHF, UHF and SHF ham radio contests.">
|
||||
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783615687631">
|
||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||
|
||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||
@@ -47,12 +47,12 @@
|
||||
|
||||
<a href="/screenshots/">Screenshots</a>
|
||||
|
||||
<a href="/download/">Download</a>
|
||||
|
||||
<a href="/manual/">Manual</a>
|
||||
|
||||
<a href="/news/">News</a>
|
||||
|
||||
<a href="/roadmap/">Roadmap</a>
|
||||
|
||||
<a href="/about/">About</a>
|
||||
|
||||
<a href="/faq/">FAQ</a>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<meta name="twitter:title" content="KST4Contest News">
|
||||
<meta name="twitter:description" content="News, release updates and development notes for KST4Contest.">
|
||||
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783615687631">
|
||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||
|
||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||
@@ -47,12 +47,12 @@
|
||||
|
||||
<a href="/screenshots/">Screenshots</a>
|
||||
|
||||
<a href="/download/">Download</a>
|
||||
|
||||
<a href="/manual/">Manual</a>
|
||||
|
||||
<a href="/news/">News</a>
|
||||
|
||||
<a href="/roadmap/">Roadmap</a>
|
||||
|
||||
<a href="/about/">About</a>
|
||||
|
||||
<a href="/faq/">FAQ</a>
|
||||
@@ -74,6 +74,13 @@
|
||||
<section class="section">
|
||||
<div class="grid">
|
||||
|
||||
<article class="card">
|
||||
<p class="eyebrow">July 8, 2026</p>
|
||||
<h3><a href="/news/2026-07-08-hotfix-version-1-41-1/">Hotfix Version 1.41.1</a></h3>
|
||||
<p>Hotfix of a bug in Version 1.41</p>
|
||||
<a href="/news/2026-07-08-hotfix-version-1-41-1/">Read more →</a>
|
||||
</article>
|
||||
|
||||
<article class="card">
|
||||
<p class="eyebrow">July 7, 2026</p>
|
||||
<h3><a href="/news/2026-07-website-launch/">KST4Contest Website Launch</a></h3>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<meta name="twitter:title" content="Privacy Policy | KST4Contest">
|
||||
<meta name="twitter:description" content="Privacy policy for the KST4Contest website.">
|
||||
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783615687631">
|
||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||
|
||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||
@@ -47,12 +47,12 @@
|
||||
|
||||
<a href="/screenshots/">Screenshots</a>
|
||||
|
||||
<a href="/download/">Download</a>
|
||||
|
||||
<a href="/manual/">Manual</a>
|
||||
|
||||
<a href="/news/">News</a>
|
||||
|
||||
<a href="/roadmap/">Roadmap</a>
|
||||
|
||||
<a href="/about/">About</a>
|
||||
|
||||
<a href="/faq/">FAQ</a>
|
||||
|
||||
@@ -0,0 +1,204 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>KST4Contest Roadmap</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="description" content="Planned enhancements for upcoming KST4Contest versions, generated from GitHub milestones and issues.">
|
||||
<link rel="canonical" href="https://kst4contest.hamradioonline.de/roadmap/">
|
||||
|
||||
<meta property="og:type" content="website">
|
||||
<meta property="og:title" content="KST4Contest Roadmap">
|
||||
<meta property="og:description" content="Planned enhancements for upcoming KST4Contest versions, generated from GitHub milestones and issues.">
|
||||
<meta property="og:url" content="https://kst4contest.hamradioonline.de/roadmap/">
|
||||
<meta property="og:site_name" content="KST4Contest">
|
||||
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
<meta name="twitter:title" content="KST4Contest Roadmap">
|
||||
<meta name="twitter:description" content="Planned enhancements for upcoming KST4Contest versions, generated from GitHub milestones and issues.">
|
||||
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783615687631">
|
||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||
|
||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||
<meta property="og:image:width" content="1200">
|
||||
<meta property="og:image:height" content="630">
|
||||
<meta name="twitter:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="site-bg"></div>
|
||||
|
||||
<header class="site-header">
|
||||
<a class="brand" href="/">
|
||||
<span class="brand-mark">◎</span>
|
||||
<span>
|
||||
<strong>KST4Contest</strong>
|
||||
<small>ON4KST Contest Client</small>
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<nav class="site-nav">
|
||||
|
||||
<a href="/">Home</a>
|
||||
|
||||
<a href="/features/">Features</a>
|
||||
|
||||
<a href="/screenshots/">Screenshots</a>
|
||||
|
||||
<a href="/manual/">Manual</a>
|
||||
|
||||
<a href="/news/">News</a>
|
||||
|
||||
<a href="/roadmap/">Roadmap</a>
|
||||
|
||||
<a href="/about/">About</a>
|
||||
|
||||
<a href="/faq/">FAQ</a>
|
||||
|
||||
<a class="nav-cta" href="/download/">Download</a>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
|
||||
<section class="hero">
|
||||
<p class="badge">Roadmap</p>
|
||||
<h1>What's planned next.</h1>
|
||||
<p class="lead">
|
||||
Generated automatically from the "enhancement" issues in our
|
||||
<a href="https://github.com/praktimarc/kst4contest">GitHub repository</a>,
|
||||
grouped by their target version milestone.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section class="section narrow">
|
||||
|
||||
|
||||
|
||||
<article class="card content-card roadmap-version">
|
||||
|
||||
<h2><a href="https://github.com/praktimarc/kst4contest/milestone/2">v1.42</a></h2>
|
||||
|
||||
<p>next Version</p>
|
||||
|
||||
<ul>
|
||||
|
||||
<li>
|
||||
<a href="https://github.com/praktimarc/kst4contest/issues/52">[FEATURE] center horizontal slider</a>
|
||||
</li>
|
||||
|
||||
<li class="roadmap-done">
|
||||
<a href="https://github.com/praktimarc/kst4contest/issues/49">[FEATURE] QTF degree, manual change</a> ✓
|
||||
</li>
|
||||
|
||||
<li class="roadmap-done">
|
||||
<a href="https://github.com/praktimarc/kst4contest/issues/22">Displaying where an Station is active.</a> ✓
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</article>
|
||||
|
||||
<article class="card content-card roadmap-version">
|
||||
|
||||
<h2><a href="https://github.com/praktimarc/kst4contest/milestone/3">v1.50</a></h2>
|
||||
|
||||
<p>Greater Overhaul</p>
|
||||
|
||||
<ul>
|
||||
|
||||
<li>
|
||||
<a href="https://github.com/praktimarc/kst4contest/issues/57">[FEATURE] User Config</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="https://github.com/praktimarc/kst4contest/issues/21">QRB greater than Distance Button in the Userfield</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="https://github.com/praktimarc/kst4contest/issues/20">i18n - Possible Translations?</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</article>
|
||||
|
||||
<article class="card content-card roadmap-version">
|
||||
|
||||
<h2><a href="https://github.com/praktimarc/kst4contest/milestone/1">v1.41</a></h2>
|
||||
|
||||
<p>Latest Version</p>
|
||||
|
||||
<p class="eyebrow">Released July 5, 2026</p>
|
||||
|
||||
<ul>
|
||||
|
||||
<li class="roadmap-done">
|
||||
<a href="https://github.com/praktimarc/kst4contest/issues/23">Score of Top-Priority Candidates in the user section</a> ✓
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</article>
|
||||
|
||||
<article class="card content-card roadmap-version">
|
||||
|
||||
<h2>Planned, no version yet</h2>
|
||||
|
||||
|
||||
|
||||
<ul>
|
||||
|
||||
<li>
|
||||
<a href="https://github.com/praktimarc/kst4contest/issues/55">[FEATURE] Reset-Button for the map</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="https://github.com/praktimarc/kst4contest/issues/47">[FEATURE] Sked push for UCXLOG</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="https://github.com/praktimarc/kst4contest/issues/46">[FEATURE] SO2R Operation</a>
|
||||
</li>
|
||||
|
||||
<li class="roadmap-done">
|
||||
<a href="https://github.com/praktimarc/kst4contest/issues/19">Broadcast Messages (To ALL Station in Contest) in seperate Window</a> (not planned)
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</article>
|
||||
|
||||
</section>
|
||||
|
||||
</main>
|
||||
|
||||
<footer class="site-footer">
|
||||
<div class="footer-grid">
|
||||
<div>
|
||||
<strong>KST4Contest</strong>
|
||||
<p>Contest-optimized ON4KST workflow for VHF/UHF/SHF operators.</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<strong>Project</strong>
|
||||
<p><a href="/features/">Features</a></p>
|
||||
<p><a href="/download/">Download</a></p>
|
||||
<p><a href="/manual/">Manual</a></p>
|
||||
<p><a href="/roadmap/">Roadmap</a></p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<strong>Community</strong>
|
||||
<p><a href="https://github.com/praktimarc/kst4contest">GitHub Repository</a></p>
|
||||
<p><a href="https://github.com/praktimarc/kst4contest/issues">Issues</a></p>
|
||||
<p><a href="/contact/">Contact</a></p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<strong>Legal</strong>
|
||||
<p><a href="/legal-notice/">Legal Notice</a></p>
|
||||
<p><a href="/privacy/">Privacy Policy</a></p>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -17,7 +17,7 @@
|
||||
<meta name="twitter:title" content="KST4Contest Screenshots">
|
||||
<meta name="twitter:description" content="Screenshots of KST4Contest, the contest-optimized ON4KST chat client for VHF, UHF and SHF operators.">
|
||||
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783615687631">
|
||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||
|
||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||
@@ -47,12 +47,12 @@
|
||||
|
||||
<a href="/screenshots/">Screenshots</a>
|
||||
|
||||
<a href="/download/">Download</a>
|
||||
|
||||
<a href="/manual/">Manual</a>
|
||||
|
||||
<a href="/news/">News</a>
|
||||
|
||||
<a href="/roadmap/">Roadmap</a>
|
||||
|
||||
<a href="/about/">About</a>
|
||||
|
||||
<a href="/faq/">FAQ</a>
|
||||
|
||||
+83
-75
@@ -1,91 +1,99 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||
<url>
|
||||
<loc>https://kst4contest.hamradioonline.de/faq/</loc>
|
||||
<lastmod>2026-07-06</lastmod>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://kst4contest.hamradioonline.de/manual/de/airscout-integration/</loc>
|
||||
<lastmod>2026-07-06</lastmod>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://kst4contest.hamradioonline.de/manual/de/</loc>
|
||||
<lastmod>2026-07-06</lastmod>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://kst4contest.hamradioonline.de/manual/en/</loc>
|
||||
<lastmod>2026-07-06</lastmod>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://kst4contest.hamradioonline.de/manual/</loc>
|
||||
<lastmod>2026-07-06</lastmod>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://kst4contest.hamradioonline.de/features/airscout/</loc>
|
||||
<lastmod>2026-07-06</lastmod>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://kst4contest.hamradioonline.de/features/dual-chat/</loc>
|
||||
<lastmod>2026-07-06</lastmod>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://kst4contest.hamradioonline.de/features/dx-cluster/</loc>
|
||||
<lastmod>2026-07-06</lastmod>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://kst4contest.hamradioonline.de/features/</loc>
|
||||
<lastmod>2026-07-06</lastmod>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://kst4contest.hamradioonline.de/features/log-sync/</loc>
|
||||
<lastmod>2026-07-06</lastmod>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://kst4contest.hamradioonline.de/features/macros/</loc>
|
||||
<lastmod>2026-07-06</lastmod>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://kst4contest.hamradioonline.de/features/priority-score/</loc>
|
||||
<lastmod>2026-07-06</lastmod>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://kst4contest.hamradioonline.de/features/sked-reminder/</loc>
|
||||
<lastmod>2026-07-06</lastmod>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://kst4contest.hamradioonline.de/features/timeline/</loc>
|
||||
<lastmod>2026-07-06</lastmod>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://kst4contest.hamradioonline.de/screenshots/</loc>
|
||||
<lastmod>2026-07-06</lastmod>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://kst4contest.hamradioonline.de/news/2026-07-website-launch/</loc>
|
||||
<lastmod>2026-07-07</lastmod>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://kst4contest.hamradioonline.de/news/2026-07-08-hotfix-version-1-41-1/</loc>
|
||||
<lastmod>2026-07-08</lastmod>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://kst4contest.hamradioonline.de/about/</loc>
|
||||
<lastmod>2026-07-07</lastmod>
|
||||
<lastmod>2026-07-09</lastmod>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://kst4contest.hamradioonline.de/contact/</loc>
|
||||
<lastmod>2026-07-07</lastmod>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://kst4contest.hamradioonline.de/legal-notice/</loc>
|
||||
<lastmod>2026-07-07</lastmod>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://kst4contest.hamradioonline.de/privacy/</loc>
|
||||
<lastmod>2026-07-07</lastmod>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://kst4contest.hamradioonline.de/</loc>
|
||||
<lastmod>2026-07-07</lastmod>
|
||||
<lastmod>2026-07-09</lastmod>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://kst4contest.hamradioonline.de/download/</loc>
|
||||
<lastmod>2026-07-07</lastmod>
|
||||
<lastmod>2026-07-09</lastmod>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://kst4contest.hamradioonline.de/faq/</loc>
|
||||
<lastmod>2026-07-09</lastmod>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://kst4contest.hamradioonline.de/features/airscout/</loc>
|
||||
<lastmod>2026-07-09</lastmod>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://kst4contest.hamradioonline.de/features/dual-chat/</loc>
|
||||
<lastmod>2026-07-09</lastmod>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://kst4contest.hamradioonline.de/features/dx-cluster/</loc>
|
||||
<lastmod>2026-07-09</lastmod>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://kst4contest.hamradioonline.de/features/</loc>
|
||||
<lastmod>2026-07-09</lastmod>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://kst4contest.hamradioonline.de/features/log-sync/</loc>
|
||||
<lastmod>2026-07-09</lastmod>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://kst4contest.hamradioonline.de/features/macros/</loc>
|
||||
<lastmod>2026-07-09</lastmod>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://kst4contest.hamradioonline.de/features/priority-score/</loc>
|
||||
<lastmod>2026-07-09</lastmod>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://kst4contest.hamradioonline.de/features/sked-reminder/</loc>
|
||||
<lastmod>2026-07-09</lastmod>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://kst4contest.hamradioonline.de/features/timeline/</loc>
|
||||
<lastmod>2026-07-09</lastmod>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://kst4contest.hamradioonline.de/</loc>
|
||||
<lastmod>2026-07-09</lastmod>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://kst4contest.hamradioonline.de/legal-notice/</loc>
|
||||
<lastmod>2026-07-09</lastmod>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://kst4contest.hamradioonline.de/manual/de/airscout-integration/</loc>
|
||||
<lastmod>2026-07-09</lastmod>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://kst4contest.hamradioonline.de/manual/de/</loc>
|
||||
<lastmod>2026-07-09</lastmod>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://kst4contest.hamradioonline.de/manual/en/</loc>
|
||||
<lastmod>2026-07-09</lastmod>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://kst4contest.hamradioonline.de/manual/</loc>
|
||||
<lastmod>2026-07-09</lastmod>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://kst4contest.hamradioonline.de/privacy/</loc>
|
||||
<lastmod>2026-07-09</lastmod>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://kst4contest.hamradioonline.de/roadmap/</loc>
|
||||
<lastmod>2026-07-09</lastmod>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://kst4contest.hamradioonline.de/screenshots/</loc>
|
||||
<lastmod>2026-07-09</lastmod>
|
||||
</url>
|
||||
</urlset>
|
||||
+110
-83
@@ -1,85 +1,112 @@
|
||||
const latestTag = "v1.41.0";
|
||||
const base = `https://github.com/praktimarc/kst4contest/releases/download/${latestTag}`;
|
||||
const REPO = "praktimarc/kst4contest";
|
||||
const API = `https://api.github.com/repos/${REPO}`;
|
||||
const FALLBACK_TAG = "v1.41.1";
|
||||
|
||||
module.exports = [
|
||||
{
|
||||
os: "Windows",
|
||||
format: "ZIP x64",
|
||||
icon: "🪟",
|
||||
recommended: true,
|
||||
note: "Best choice for most Windows users.",
|
||||
url: `${base}/praktiKST-${latestTag}-windows-x64.zip`
|
||||
},
|
||||
{
|
||||
os: "Linux",
|
||||
format: "Flatpak (.flatpakref)",
|
||||
icon: "🐧",
|
||||
recommended: true,
|
||||
note: "Recommended for most Linux users. Open the file with GNOME Software / Discover, or run: flatpak install de.x08.KST4Contest.flatpakref",
|
||||
url: `${base}/de.x08.KST4Contest.flatpakref`
|
||||
},
|
||||
{
|
||||
os: "Linux",
|
||||
format: "AppImage x86_64",
|
||||
icon: "🐧",
|
||||
recommended: false,
|
||||
note: "Portable Linux build without package installation.",
|
||||
url: `${base}/KST4Contest-${latestTag}-linux-x86_64.AppImage`
|
||||
},
|
||||
{
|
||||
os: "Debian / Ubuntu",
|
||||
format: "DEB amd64",
|
||||
icon: "📦",
|
||||
recommended: false,
|
||||
note: "Native package for Debian and Ubuntu based systems.",
|
||||
url: `${base}/KST4Contest-${latestTag}-debian-amd64.deb`
|
||||
},
|
||||
{
|
||||
os: "Fedora",
|
||||
format: "RPM x86_64",
|
||||
icon: "📦",
|
||||
recommended: false,
|
||||
note: "Native package for Fedora/RPM based systems.",
|
||||
url: `${base}/KST4Contest-${latestTag}-fedora-x86_64.rpm`
|
||||
},
|
||||
{
|
||||
os: "Arch Linux",
|
||||
format: "pkg.tar.zst",
|
||||
icon: "📦",
|
||||
recommended: false,
|
||||
note: "Package build for Arch Linux users.",
|
||||
url: `${base}/KST4Contest-${latestTag}-archlinux-x86_64.pkg.tar.zst`
|
||||
},
|
||||
{
|
||||
os: "macOS Apple Silicon",
|
||||
format: "DMG arm64",
|
||||
icon: "🍎",
|
||||
recommended: false,
|
||||
note: "For Apple Silicon Macs.",
|
||||
url: `${base}/KST4Contest-${latestTag}-macos-arm64.dmg`
|
||||
},
|
||||
{
|
||||
os: "macOS Intel",
|
||||
format: "DMG x86_64",
|
||||
icon: "🍎",
|
||||
recommended: false,
|
||||
note: "For Intel-based Macs.",
|
||||
url: `${base}/KST4Contest-${latestTag}-macos-x86_64.dmg`
|
||||
},
|
||||
{
|
||||
os: "Manual English",
|
||||
format: "PDF",
|
||||
icon: "📘",
|
||||
recommended: false,
|
||||
note: "English PDF manual.",
|
||||
url: `${base}/KST4Contest-${latestTag}-manual-en.pdf`
|
||||
},
|
||||
{
|
||||
os: "Manual German",
|
||||
format: "PDF",
|
||||
icon: "📘",
|
||||
recommended: false,
|
||||
note: "German PDF manual.",
|
||||
url: `${base}/KST4Contest-${latestTag}-manual-de.pdf`
|
||||
async function fetchLatestReleaseTag() {
|
||||
const headers = { Accept: "application/vnd.github+json" };
|
||||
if (process.env.GITHUB_TOKEN) {
|
||||
headers.Authorization = `Bearer ${process.env.GITHUB_TOKEN}`;
|
||||
}
|
||||
];
|
||||
|
||||
try {
|
||||
const res = await fetch(`${API}/releases/latest`, { headers });
|
||||
if (!res.ok) {
|
||||
throw new Error(`GitHub API /releases/latest failed: ${res.status}`);
|
||||
}
|
||||
const release = await res.json();
|
||||
return release.tag_name || FALLBACK_TAG;
|
||||
} catch (err) {
|
||||
console.warn(`[downloads] Could not load latest release tag, falling back to ${FALLBACK_TAG}: ${err.message}`);
|
||||
return FALLBACK_TAG;
|
||||
}
|
||||
}
|
||||
|
||||
// Builds the download list from the latest GitHub release tag so it never
|
||||
// drifts out of sync with what tagged-release.yml actually published.
|
||||
module.exports = async function () {
|
||||
const latestTag = await fetchLatestReleaseTag();
|
||||
const base = `https://github.com/${REPO}/releases/download/${latestTag}`;
|
||||
|
||||
return [
|
||||
{
|
||||
os: "Windows",
|
||||
format: "ZIP x64",
|
||||
icon: "🪟",
|
||||
recommended: true,
|
||||
note: "Best choice for most Windows users.",
|
||||
url: `${base}/praktiKST-${latestTag}-windows-x64.zip`
|
||||
},
|
||||
{
|
||||
os: "Linux",
|
||||
format: "Flatpak (.flatpakref)",
|
||||
icon: "🐧",
|
||||
recommended: true,
|
||||
note: "Recommended for most Linux users. Open the file with GNOME Software / Discover, or run: flatpak install de.x08.KST4Contest.flatpakref",
|
||||
url: `${base}/de.x08.KST4Contest.flatpakref`
|
||||
},
|
||||
{
|
||||
os: "Linux",
|
||||
format: "AppImage x86_64",
|
||||
icon: "🐧",
|
||||
recommended: false,
|
||||
note: "Portable Linux build without package installation.",
|
||||
url: `${base}/KST4Contest-${latestTag}-linux-x86_64.AppImage`
|
||||
},
|
||||
{
|
||||
os: "Debian / Ubuntu",
|
||||
format: "DEB amd64",
|
||||
icon: "📦",
|
||||
recommended: false,
|
||||
note: "Native package for Debian and Ubuntu based systems.",
|
||||
url: `${base}/KST4Contest-${latestTag}-debian-amd64.deb`
|
||||
},
|
||||
{
|
||||
os: "Fedora",
|
||||
format: "RPM x86_64",
|
||||
icon: "📦",
|
||||
recommended: false,
|
||||
note: "Native package for Fedora/RPM based systems.",
|
||||
url: `${base}/KST4Contest-${latestTag}-fedora-x86_64.rpm`
|
||||
},
|
||||
{
|
||||
os: "Arch Linux",
|
||||
format: "pkg.tar.zst",
|
||||
icon: "📦",
|
||||
recommended: false,
|
||||
note: "Package build for Arch Linux users.",
|
||||
url: `${base}/KST4Contest-${latestTag}-archlinux-x86_64.pkg.tar.zst`
|
||||
},
|
||||
{
|
||||
os: "macOS Apple Silicon",
|
||||
format: "DMG arm64",
|
||||
icon: "🍎",
|
||||
recommended: false,
|
||||
note: "For Apple Silicon Macs.",
|
||||
url: `${base}/KST4Contest-${latestTag}-macos-arm64.dmg`
|
||||
},
|
||||
{
|
||||
os: "macOS Intel",
|
||||
format: "DMG x86_64",
|
||||
icon: "🍎",
|
||||
recommended: false,
|
||||
note: "For Intel-based Macs.",
|
||||
url: `${base}/KST4Contest-${latestTag}-macos-x86_64.dmg`
|
||||
},
|
||||
{
|
||||
os: "Manual English",
|
||||
format: "PDF",
|
||||
icon: "📘",
|
||||
recommended: false,
|
||||
note: "English PDF manual.",
|
||||
url: `${base}/KST4Contest-${latestTag}-manual-en.pdf`
|
||||
},
|
||||
{
|
||||
os: "Manual German",
|
||||
format: "PDF",
|
||||
icon: "📘",
|
||||
recommended: false,
|
||||
note: "German PDF manual.",
|
||||
url: `${base}/KST4Contest-${latestTag}-manual-de.pdf`
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
@@ -4,6 +4,7 @@ module.exports = [
|
||||
{ title: "Screenshots", url: "/screenshots/" },
|
||||
{ title: "Manual", url: "/manual/" },
|
||||
{ title: "News", url: "/news/" },
|
||||
{ title: "Roadmap", url: "/roadmap/" },
|
||||
{ title: "About", url: "/about/" },
|
||||
{ title: "FAQ", url: "/faq/" }
|
||||
];
|
||||
@@ -0,0 +1,84 @@
|
||||
const REPO = "praktimarc/kst4contest";
|
||||
const API = `https://api.github.com/repos/${REPO}`;
|
||||
|
||||
async function githubGet(path) {
|
||||
const headers = { Accept: "application/vnd.github+json" };
|
||||
if (process.env.GITHUB_TOKEN) {
|
||||
headers.Authorization = `Bearer ${process.env.GITHUB_TOKEN}`;
|
||||
}
|
||||
const res = await fetch(`${API}${path}`, { headers });
|
||||
if (!res.ok) {
|
||||
throw new Error(`GitHub API ${path} failed: ${res.status}`);
|
||||
}
|
||||
return res.json();
|
||||
}
|
||||
|
||||
// Builds the roadmap from all GitHub issues tagged "enhancement", grouped by
|
||||
// their version milestone (open or already released). Issues without a
|
||||
// milestone are shown as planned but with no assigned version yet. Issues
|
||||
// closed as "not planned" are kept, struck through and labeled accordingly.
|
||||
// Falls back to an empty list if the API is unreachable (e.g. offline build)
|
||||
// so the site build never fails.
|
||||
module.exports = async function () {
|
||||
try {
|
||||
const issues = await githubGet(
|
||||
"/issues?labels=enhancement&state=all&per_page=100"
|
||||
);
|
||||
|
||||
const groups = new Map();
|
||||
|
||||
for (const issue of issues) {
|
||||
if (issue.pull_request) continue;
|
||||
|
||||
const milestone = issue.milestone;
|
||||
const key = milestone ? milestone.number : "unscheduled";
|
||||
|
||||
if (!groups.has(key)) {
|
||||
groups.set(key, {
|
||||
version: milestone ? milestone.title : null,
|
||||
description: milestone ? milestone.description : null,
|
||||
url: milestone ? milestone.html_url : null,
|
||||
released: milestone ? milestone.state === "closed" : false,
|
||||
dueOn: milestone && milestone.due_on ? new Date(milestone.due_on) : null,
|
||||
releasedOn: milestone && milestone.closed_at ? new Date(milestone.closed_at) : null,
|
||||
enhancements: []
|
||||
});
|
||||
}
|
||||
|
||||
const notPlanned = issue.state === "closed" && issue.state_reason === "not_planned";
|
||||
|
||||
groups.get(key).enhancements.push({
|
||||
title: issue.title,
|
||||
url: issue.html_url,
|
||||
done: issue.state === "closed" && !notPlanned,
|
||||
notPlanned
|
||||
});
|
||||
}
|
||||
|
||||
const versions = [...groups.values()].filter((v) => v.enhancements.length > 0);
|
||||
|
||||
// Order: upcoming dated versions first (soonest due date), then
|
||||
// upcoming undated versions, then already released versions (newest
|
||||
// first), unscheduled enhancements at the very end.
|
||||
versions.sort((a, b) => {
|
||||
if (!a.version) return 1;
|
||||
if (!b.version) return -1;
|
||||
if (a.released !== b.released) return a.released ? 1 : -1;
|
||||
|
||||
if (!a.released) {
|
||||
if (a.dueOn && b.dueOn) return a.dueOn - b.dueOn;
|
||||
if (a.dueOn) return -1;
|
||||
if (b.dueOn) return 1;
|
||||
return a.version.localeCompare(b.version);
|
||||
}
|
||||
|
||||
if (a.releasedOn && b.releasedOn) return b.releasedOn - a.releasedOn;
|
||||
return b.version.localeCompare(a.version);
|
||||
});
|
||||
|
||||
return versions;
|
||||
} catch (err) {
|
||||
console.warn(`[roadmap] Could not load GitHub issues: ${err.message}`);
|
||||
return [];
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,382 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Historical changelog entries for releases not published as GitHub Releases.
|
||||
The CI pipeline prepends new entries from GitHub Releases on top of these. -->
|
||||
<history>
|
||||
<changeLog>
|
||||
<changedVersionNumber>1.41</changedVersionNumber>
|
||||
<date>2026-07-01</date>
|
||||
<description>Map view and path calculations</description>
|
||||
<added>
|
||||
Band and Frequency Detection per Chatmember, Band alert, Win-Test SKED Push via UDP,
|
||||
Win-Test Broadcast Defaults and SKed Workflow, Chat History at Startup, Station Map / Map View
|
||||
Local Leaflet /-TileProxy Backend, Maidenhead /-Grid Overlay, Path calculation, path profile,
|
||||
Reachability filters, NAC filters (grid sqaure marking)
|
||||
</added>
|
||||
<changed>
|
||||
button housing, it works now on smaller screens / plus: detecting maximum screen size
|
||||
</changed>
|
||||
<fixed>
|
||||
9A2HM reported that 23cm qsos with N1MM are not marked correctly, ist fixed
|
||||
</fixed>
|
||||
<removed></removed>
|
||||
</changeLog>
|
||||
<changeLog>
|
||||
<changedVersionNumber>1.40</changedVersionNumber>
|
||||
<date>2026-02-16</date>
|
||||
<description>Much changes and fixes</description>
|
||||
<added>
|
||||
- win-test support (not deactivable yet, beta)
|
||||
- QSO sniffer which filters changable callsigns lists messages to your pm window
|
||||
- Chatmember Score system. Each chatmember gets a score depending to antenna direction, activity time,
|
||||
activity msgcount, positive signals, active bands, active frequencies, his sked direction (degrees),
|
||||
self handed rate, sked-made-rate and some others
|
||||
- Chatmember Band and frequency recognition: now we list all active bands of each other chatmember
|
||||
- Band alert for logged stations
|
||||
- Sked reminder ALERT with automatic messages in 2+1 / 5+2+1 / 10+5+2+1 minutes
|
||||
- PSTRotator interface
|
||||
- AirPlane Timeline
|
||||
- Skedfail button in furtherinfo panel
|
||||
- Wintest logsynch interface can now be activated and deactivated in the preferences
|
||||
- load chat history on startup
|
||||
</added>
|
||||
<changed>
|
||||
- added save option: ServerDNS / Port
|
||||
- added save option: activate/deactivate pstRotator interface
|
||||
- added save option: activate/deactivate wintest interface
|
||||
- added save option: callsign sniffer
|
||||
- added save option: boolean GUI_darkModeActiveByDefault = false
|
||||
- added AP notes at the internal DX cluster spots
|
||||
- Generic Autoanswer fires maximum once in 45 seconds per rx callsign
|
||||
</changed>
|
||||
<fixed>
|
||||
- Userlist sort automatically on new member signon
|
||||
- Posonpill-messages now kills only exactly one Client instance (bugreport 9A2HM)
|
||||
- Crash of wtkst by disconnection of kst4Contest
|
||||
- wtKST crashes when kst4contest is running (many reporters)
|
||||
- wintest: logged per band excludes pre worked band (bugreport SM6VTZ)
|
||||
- PSTRotator SOCKET Close on DISCONNECT BUTTON works now
|
||||
- AirScout Map had not been updated (bugreport SM0RJV)
|
||||
- QTFDefault had been not saved correctly (bugreport SM0RJV)
|
||||
- Show path in AS button worked only with fixed server Strings (bugreport 9A2HM)
|
||||
- Version number had been displayed wrong
|
||||
- suffixes like /p, -2, etc. problem now fixed everywhere
|
||||
- Dark mode: passing for qrg fields fix
|
||||
</fixed>
|
||||
<removed>
|
||||
- No more date display. Not needed. Saving space, only time is important
|
||||
</removed>
|
||||
</changeLog>
|
||||
<changeLog>
|
||||
<changedVersionNumber>1.31</changedVersionNumber>
|
||||
<date>2025-12-13</date>
|
||||
<description>Much changes and a hotfix</description>
|
||||
<added>
|
||||
- win-test support (not deactivable yet, beta)
|
||||
- pstRotator support (not deactivable yet, beta)
|
||||
- airScout fix (calculations depends to cpu load now)
|
||||
- QSO sniffer
|
||||
</added>
|
||||
<changed>
|
||||
- DNS from www.on4kst.info to www.on4kst.org (hotfix, now configurable in preferences)
|
||||
</changed>
|
||||
<fixed>
|
||||
- Endless loop in error case lets freeze the client
|
||||
- PSTRotator SOCKET Close on DISCONNECT BUTTON
|
||||
- Dark mode: passing for qrg fields fix
|
||||
</fixed>
|
||||
<removed></removed>
|
||||
</changeLog>
|
||||
<changeLog>
|
||||
<changedVersionNumber>1.266</changedVersionNumber>
|
||||
<date>2025-10-03</date>
|
||||
<description>Airscout interface did not work with multi-signons</description>
|
||||
<added>nothing</added>
|
||||
<changed>nothing</changed>
|
||||
<fixed>
|
||||
Fixed by using raw callsign (without -2 suffix etc.) when communicating with AirScout.
|
||||
Thank you very much for testing this, Kreso 9A2HM!
|
||||
</fixed>
|
||||
<removed></removed>
|
||||
</changeLog>
|
||||
<changeLog>
|
||||
<changedVersionNumber>1.265</changedVersionNumber>
|
||||
<date>2025-09-28</date>
|
||||
<description>Direction buttons stay now colored, if activated</description>
|
||||
<added>nothing</added>
|
||||
<changed>nothing</changed>
|
||||
<fixed>The buttons stay now colored, if activated</fixed>
|
||||
<removed></removed>
|
||||
</changeLog>
|
||||
<changeLog>
|
||||
<changedVersionNumber>1.264</changedVersionNumber>
|
||||
<date>2025-08-02</date>
|
||||
<description>Changed the callsign recognition pattern for Simplelogfile</description>
|
||||
<added>nothing</added>
|
||||
<changed>nothing</changed>
|
||||
<fixed>
|
||||
Callsigns like S53CC, S51A etc. are now correctly marked as worked in SimpleLogFile.txt.
|
||||
(bugreport Boris, S53CC)
|
||||
</fixed>
|
||||
<removed></removed>
|
||||
</changeLog>
|
||||
<changeLog>
|
||||
<changedVersionNumber>1.263</changedVersionNumber>
|
||||
<date>2025-06-08</date>
|
||||
<description>Airscout communication and Loginname</description>
|
||||
<added>nothing</added>
|
||||
<changed>
|
||||
Only entries with QRB lower than max-QRB are sent to AirScout in 60s intervals (was 12s for all).
|
||||
</changed>
|
||||
<fixed>
|
||||
- AS communication message count hugely reduced
|
||||
- Name in chat is now saveable
|
||||
- Fixed AS client name (was hard-wired to "KST")
|
||||
73 / DO5AMF
|
||||
</fixed>
|
||||
<removed></removed>
|
||||
</changeLog>
|
||||
<changeLog>
|
||||
<changedVersionNumber>1.262</changedVersionNumber>
|
||||
<date>2025-05-21</date>
|
||||
<description>Freezes caused by getting messages before user login should be fixed now</description>
|
||||
<added>nothing</added>
|
||||
<changed>nothing</changed>
|
||||
<fixed>
|
||||
ON4KST delivers messages of stations not yet logged in. That caused a freeze at the message
|
||||
processing engine which is now fixed.
|
||||
</fixed>
|
||||
<removed></removed>
|
||||
</changeLog>
|
||||
<changeLog>
|
||||
<changedVersionNumber>1.26</changedVersionNumber>
|
||||
<date>2025-05</date>
|
||||
<description>Login to multiple Channels via single signon / spend some colors</description>
|
||||
<added>
|
||||
1. UI: Dark mode. Switch in "Window -> use dark mode"
|
||||
2. Usage of two Chatcategories at the same time
|
||||
3. opposite station multi-callsign login-tagging
|
||||
73 / DO5AMF
|
||||
</added>
|
||||
<changed>
|
||||
- Coloring mechanic of the software. Modify colors via css by yourself...
|
||||
</changed>
|
||||
<fixed>
|
||||
- Station tagging fixed completely
|
||||
</fixed>
|
||||
<removed></removed>
|
||||
</changeLog>
|
||||
<changeLog>
|
||||
<changedVersionNumber>1.251</changedVersionNumber>
|
||||
<date>2025-02</date>
|
||||
<description>BUGFIX of 1.25, tnx Steve Clements!</description>
|
||||
<added>
|
||||
- Steve spotted a problem in udp broadcast spot info reading, its now fixed!
|
||||
73 / DO5AMF
|
||||
</added>
|
||||
<changed></changed>
|
||||
<fixed>- Station tagging</fixed>
|
||||
<removed></removed>
|
||||
</changeLog>
|
||||
<changeLog>
|
||||
<changedVersionNumber>1.25</changedVersionNumber>
|
||||
<date>2025-02</date>
|
||||
<description>Wishlist-time</description>
|
||||
<added>
|
||||
- New configuration Tab: Messagehandling (auto-answering, CQ qrg auto-answer)
|
||||
- Coloured lines: new pm rows appear in red, fade rainbow-like to white over 30s (tnx Gianluca)
|
||||
73 / DO5AMF
|
||||
</added>
|
||||
<changed></changed>
|
||||
<fixed>
|
||||
- Users with suffixes like "-2 and -70" are now correctly marked as worked
|
||||
</fixed>
|
||||
<removed></removed>
|
||||
</changeLog>
|
||||
<changeLog>
|
||||
<changedVersionNumber>1.24</changedVersionNumber>
|
||||
<date>2024-11</date>
|
||||
<description>Wishlist-time</description>
|
||||
<added>
|
||||
- Button to show qrz.com profile of a selected station
|
||||
- Button to show qrzcq.com profile of a selected station
|
||||
</added>
|
||||
<changed></changed>
|
||||
<fixed></fixed>
|
||||
<removed></removed>
|
||||
</changeLog>
|
||||
<changeLog>
|
||||
<changedVersionNumber>1.23</changedVersionNumber>
|
||||
<date>2024-10</date>
|
||||
<description>DXCluster Server is now implemented</description>
|
||||
<added>
|
||||
- DXCluster Server (tnx OMAAO): KST4Contest now provides a DXCluster server to feed
|
||||
your log client with station-reachable warnings.
|
||||
</added>
|
||||
<changed></changed>
|
||||
<fixed></fixed>
|
||||
<removed></removed>
|
||||
</changeLog>
|
||||
<changeLog>
|
||||
<changedVersionNumber>1.22</changedVersionNumber>
|
||||
<date>2024-05</date>
|
||||
<description>Increase usability, fixed AS button</description>
|
||||
<added>- Variables (tnx OMAAO): MYLOCATORSHORT, MYQRGSHORT, QRZNAME</added>
|
||||
<changed>- Sendtext-field focus on callsign click</changed>
|
||||
<fixed>
|
||||
- Worked-station-filter (tnx Gianluca): filter is now live
|
||||
- Chatters list sorting by QRB (tnx Alessandro): fixed to numeric sort
|
||||
- Airscout showpath button now maximizes AS and shows the path
|
||||
</fixed>
|
||||
<removed></removed>
|
||||
</changeLog>
|
||||
<changeLog>
|
||||
<changedVersionNumber>1.21</changedVersionNumber>
|
||||
<date>2024-04</date>
|
||||
<description>Increase usability</description>
|
||||
<added></added>
|
||||
<changed>
|
||||
- Window sizes and divider positions are now stored and restored on next startup
|
||||
- Filters section is now a flowpane for lower resolutions
|
||||
</changed>
|
||||
<fixed></fixed>
|
||||
<removed></removed>
|
||||
</changeLog>
|
||||
<changeLog>
|
||||
<changedVersionNumber>1.2</changedVersionNumber>
|
||||
<date>2024-04</date>
|
||||
<description>Increase usability</description>
|
||||
<added>
|
||||
- Selectable bands
|
||||
- Unworkable tags for each callsign per band
|
||||
- QTF-Arrow on the "show path in AS" button
|
||||
</added>
|
||||
<changed></changed>
|
||||
<fixed></fixed>
|
||||
<removed></removed>
|
||||
</changeLog>
|
||||
<changeLog>
|
||||
<changedVersionNumber>1.1</changedVersionNumber>
|
||||
<date>2024-03</date>
|
||||
<description>Increased workflow</description>
|
||||
<added>
|
||||
- Reachable warning function
|
||||
- Variables FIRSTAP and SECONDAP for predefined texts
|
||||
- Marking new connected stations (bold) and away-state (brackets)
|
||||
- Activity-timer since last message of a chatter
|
||||
</added>
|
||||
<changed>- QRB/QTF info in pm-window</changed>
|
||||
<fixed>
|
||||
- Behaviour of messagefilter-radiobutton corrected (tnx Gian)
|
||||
- Error sending macros on selected stations in pm window (tnx Gian)
|
||||
</fixed>
|
||||
<removed>- boot sound</removed>
|
||||
</changeLog>
|
||||
<changeLog>
|
||||
<changedVersionNumber>1.0</changedVersionNumber>
|
||||
<date>2024-02</date>
|
||||
<description>First stable release</description>
|
||||
<added>
|
||||
- audio notification support
|
||||
- update-available warning
|
||||
- changelog displaying
|
||||
- known-bugs displaying
|
||||
- message filters for selected station
|
||||
- stationlist-filters (show by qtf / textstring, hide by qrb, qtf, workedstate)
|
||||
- 10 macros (textsnippets available by hitting strg+numberkey)
|
||||
</added>
|
||||
<changed></changed>
|
||||
<fixed></fixed>
|
||||
<removed></removed>
|
||||
</changeLog>
|
||||
<changeLog>
|
||||
<changedVersionNumber>0.9</changedVersionNumber>
|
||||
<date>2024-02</date>
|
||||
<description>Now the chat is disconnectable without closing it</description>
|
||||
<added></added>
|
||||
<changed></changed>
|
||||
<fixed>disconnect-button, Textsnippets in CQ Window, "/CQ" at click on own sendtexts,
|
||||
setname "qrg" works now</fixed>
|
||||
<removed></removed>
|
||||
</changeLog>
|
||||
<changeLog>
|
||||
<changedVersionNumber>0.8</changedVersionNumber>
|
||||
<date>2023-10</date>
|
||||
<description>savesettings function and disconnect function added. MYCALL-Highlighting fixed</description>
|
||||
<added>savesettings function, disconnect function</added>
|
||||
<changed></changed>
|
||||
<fixed>MYCALL-Highlighting</fixed>
|
||||
<removed></removed>
|
||||
</changeLog>
|
||||
<changeLog>
|
||||
<changedVersionNumber>0.7</changedVersionNumber>
|
||||
<date>2023-07</date>
|
||||
<description>Internal database for worked stations, shortcut and textsnippet editor</description>
|
||||
<added>database, shortcut-editor, textsnipped-editor</added>
|
||||
<changed></changed>
|
||||
<fixed></fixed>
|
||||
<removed></removed>
|
||||
</changeLog>
|
||||
<changeLog>
|
||||
<changedVersionNumber>0.6</changedVersionNumber>
|
||||
<date>2023-07</date>
|
||||
<description>Added periodically sent beacon function</description>
|
||||
<added>beacon to public channel</added>
|
||||
<changed></changed>
|
||||
<fixed></fixed>
|
||||
<removed></removed>
|
||||
</changeLog>
|
||||
<changeLog>
|
||||
<changedVersionNumber>0.5</changedVersionNumber>
|
||||
<date>2023-02</date>
|
||||
<description>Airscout interface, UDP interfaces for worked-station data and TRX info, shortcuts</description>
|
||||
<added>Airscout-interface, packetreceiver for ucxlog, n1mm, qartest</added>
|
||||
<changed></changed>
|
||||
<fixed></fixed>
|
||||
<removed></removed>
|
||||
</changeLog>
|
||||
<changeLog>
|
||||
<changedVersionNumber>0.4</changedVersionNumber>
|
||||
<date>2022-12</date>
|
||||
<description>Worked info by logfile via universal pattern matching logfile interpreter</description>
|
||||
<added>simple-logfile</added>
|
||||
<changed></changed>
|
||||
<fixed></fixed>
|
||||
<removed></removed>
|
||||
</changeLog>
|
||||
<changeLog>
|
||||
<changedVersionNumber>0.3</changedVersionNumber>
|
||||
<date>2022-10</date>
|
||||
<description>Added a GUI, chat was text based only</description>
|
||||
<added>Graphical user interface</added>
|
||||
<changed></changed>
|
||||
<fixed></fixed>
|
||||
<removed></removed>
|
||||
</changeLog>
|
||||
<changeLog>
|
||||
<changedVersionNumber>0.2</changedVersionNumber>
|
||||
<date>2022-10</date>
|
||||
<description>Pattern matching system for frequency information, frequency collection per chatmember</description>
|
||||
<added>frequency-extraction for every callsign</added>
|
||||
<changed></changed>
|
||||
<fixed></fixed>
|
||||
<removed></removed>
|
||||
</changeLog>
|
||||
<changeLog>
|
||||
<changedVersionNumber>0.15</changedVersionNumber>
|
||||
<date>2022-09</date>
|
||||
<description>Researched the Chatprotocol and developed the base communication with the chatserver</description>
|
||||
<added></added>
|
||||
<changed></changed>
|
||||
<fixed></fixed>
|
||||
<removed></removed>
|
||||
</changeLog>
|
||||
<changeLog>
|
||||
<changedVersionNumber>0.1</changedVersionNumber>
|
||||
<date>2022-09</date>
|
||||
<description>Primary architecture of the chat, message bus system for handling the message queues</description>
|
||||
<added></added>
|
||||
<changed></changed>
|
||||
<fixed></fixed>
|
||||
<removed></removed>
|
||||
</changeLog>
|
||||
</history>
|
||||
@@ -0,0 +1,131 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Static roadmap/bugsReported sections carried over from the previously
|
||||
hand-maintained kst4ContestVersionInfo.xml on do5amf.funkerportal.de.
|
||||
UpdateChecker.java does not parse these today; kept for parity/history. -->
|
||||
<legacy>
|
||||
<roadmap>
|
||||
<featurerequest>
|
||||
<featureDescription>Cyclic update of own name in chat to actual QRG</featureDescription>
|
||||
<requestDate>2024-02</requestDate>
|
||||
<state>open</state>
|
||||
</featurerequest>
|
||||
<featurerequest>
|
||||
<featureDescription>Acoustic warnings</featureDescription>
|
||||
<requestDate>2023-12</requestDate>
|
||||
<state>added</state>
|
||||
</featurerequest>
|
||||
<featurerequest>
|
||||
<featureDescription>Airscout support</featureDescription>
|
||||
<requestDate>2023-03</requestDate>
|
||||
<state>added</state>
|
||||
</featurerequest>
|
||||
<featurerequest>
|
||||
<featureDescription>cyclic beacon messages in public chat</featureDescription>
|
||||
<requestDate>2023-03</requestDate>
|
||||
<state>added</state>
|
||||
</featurerequest>
|
||||
</roadmap>
|
||||
<bugsReported>
|
||||
<bug>
|
||||
<bugdescription>
|
||||
stations like ol7c-7 and ol7c-2 will not be marked as worked if only "ol7c"
|
||||
is in the log. Need to interprete that. May ignore suffix starting with "-"</bugdescription>
|
||||
<state>solved</state>
|
||||
</bug>
|
||||
<bug>
|
||||
<bugdescription>
|
||||
worked callsigns table is updated only once after connected to chat
|
||||
Should be available directly after program started.
|
||||
But Reset works all time</bugdescription>
|
||||
<state>open</state>
|
||||
</bug>
|
||||
<bug>
|
||||
<bugdescription>feature request: language-specific strings, maybe based to an xml file
|
||||
</bugdescription>
|
||||
<state>open</state>
|
||||
</bug>
|
||||
<bug>
|
||||
<bugdescription>feature request: Macros
|
||||
</bugdescription>
|
||||
<state>added</state>
|
||||
</bug>
|
||||
<bug>
|
||||
<bugdescription>feature request:
|
||||
Automatic elimination of calls already connected from the log
|
||||
</bugdescription>
|
||||
<state>added</state>
|
||||
</bug>
|
||||
<bug>
|
||||
<bugdescription>feature request:
|
||||
Limitation of users beyond a certain QRB
|
||||
</bugdescription>
|
||||
<state>added</state>
|
||||
</bug>
|
||||
<bug>
|
||||
<bugdescription>feature request:
|
||||
User division for QTF perhaps settable based on the antenna lobe
|
||||
</bugdescription>
|
||||
<state>added</state>
|
||||
</bug>
|
||||
<bug>
|
||||
<bugdescription>feature request:
|
||||
Notification of new incoming users</bugdescription>
|
||||
<state>added</state>
|
||||
</bug>
|
||||
<bug>
|
||||
<bugdescription>feature request:
|
||||
Evidence of a call which was written but not responded to.
|
||||
</bugdescription>
|
||||
<state>added</state>
|
||||
</bug>
|
||||
<bug>
|
||||
<bugdescription>feature request:
|
||||
direction based reachable-warnings:
|
||||
if the chatclient detects a realised qso between two stations which both must have
|
||||
directed their beams to my station, there should be an instant warning to me for
|
||||
working at least one of the stations at the detected qrg</bugdescription>
|
||||
<state>open</state>
|
||||
</bug>
|
||||
<bug>
|
||||
<bugdescription>feature request:
|
||||
implement ASShowpath message to airacout;
|
||||
by doubleclicking a callsign in the chatmember list, the path and plane state should be
|
||||
provided by airscout </bugdescription>
|
||||
<state>open</state>
|
||||
</bug>
|
||||
<bug>
|
||||
<bugdescription>feature request:
|
||||
make chatlines copyable to the clipboard...</bugdescription>
|
||||
<state>open</state>
|
||||
</bug>
|
||||
<bug>
|
||||
<bugdescription>feature request:
|
||||
adding an activity detection for sensing if another chatmembers alive-state</bugdescription>
|
||||
<state>added</state>
|
||||
</bug>
|
||||
<bug>
|
||||
<bugdescription>On sql error close the connection to make a clean exit</bugdescription>
|
||||
<state>open</state>
|
||||
</bug>
|
||||
<bug>
|
||||
<bugdescription>SETNAME /MYQRG in options menu doesnt work</bugdescription>
|
||||
<state>solved</state>
|
||||
</bug>
|
||||
<bug>
|
||||
<bugdescription>Disconnect button does not work (DL5ZK)</bugdescription>
|
||||
<state>solved</state>
|
||||
</bug>
|
||||
<bug>
|
||||
<bugdescription>Password-wrong error not displayed (DO5SA)</bugdescription>
|
||||
<state>solved</state>
|
||||
</bug>
|
||||
<bug>
|
||||
<bugdescription>/CQ isnt written on own PMs</bugdescription>
|
||||
<state>solved</state>
|
||||
</bug>
|
||||
<bug>
|
||||
<bugdescription>rightclick-textsnippets arent available in cq-table</bugdescription>
|
||||
<state>solved</state>
|
||||
</bug>
|
||||
</bugsReported>
|
||||
</legacy>
|
||||
@@ -0,0 +1,183 @@
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
|
||||
const REPO = "praktimarc/kst4contest";
|
||||
const API = `https://api.github.com/repos/${REPO}`;
|
||||
const LABEL_MAP = { enhancement: "added", bug: "fixed" };
|
||||
|
||||
async function githubGet(urlPath) {
|
||||
const headers = { Accept: "application/vnd.github+json" };
|
||||
if (process.env.GITHUB_TOKEN) {
|
||||
headers.Authorization = `Bearer ${process.env.GITHUB_TOKEN}`;
|
||||
}
|
||||
const res = await fetch(`${API}${urlPath}`, { headers });
|
||||
if (!res.ok) {
|
||||
throw new Error(`GitHub API ${urlPath} failed: ${res.status}`);
|
||||
}
|
||||
return res.json();
|
||||
}
|
||||
|
||||
// UpdateChecker.java parses <versionNumber> with Double.parseDouble() and
|
||||
// compares it against ApplicationConstants.APPLICATION_CURRENTVERSIONNUMBER,
|
||||
// which encodes patch releases by appending the patch digit(s) instead of a
|
||||
// third dot (e.g. tag v1.41.1 -> app version 1.411, v1.41.0 -> 1.41). See
|
||||
// commit 38ef50c ("...set to 1.41.1 for upcoming hotfix" -> 1.411).
|
||||
function toAppVersionNumber(tag) {
|
||||
const cleaned = tag.replace(/^v/, "");
|
||||
const [major, minor, ...rest] = cleaned.split(".");
|
||||
if (rest.length === 0) return cleaned;
|
||||
const patch = rest.join("");
|
||||
return /^0*$/.test(patch) ? `${major}.${minor}` : `${major}.${minor}${patch}`;
|
||||
}
|
||||
|
||||
function escapeXml(value) {
|
||||
return String(value ?? "")
|
||||
.replace(/&/g, "&")
|
||||
.replace(/</g, "<")
|
||||
.replace(/>/g, ">");
|
||||
}
|
||||
|
||||
// Strips GitHub's auto-generated release-notes markdown noise (headings,
|
||||
// "Full Changelog" links, PR author attributions) down to plain text.
|
||||
function cleanReleaseBody(body) {
|
||||
const lines = [];
|
||||
for (let line of (body || "").split("\n")) {
|
||||
if (/^#{1,3}\s/.test(line)) continue;
|
||||
if (line.trim().startsWith("**Full Changelog**")) continue;
|
||||
line = line.replace(/\s+by @\S+ in https:\/\/\S+/, "");
|
||||
line = line.replace(/^\* /, "- ");
|
||||
if (line.trim()) lines.push(line);
|
||||
}
|
||||
return lines.join("\n").replace(/\n{3,}/g, "\n\n").trim();
|
||||
}
|
||||
|
||||
// Groups closed issues (excluding PRs) in the (since, until] window by
|
||||
// label into "added" (enhancement) / "fixed" (bug) bullet lists.
|
||||
async function getIssuesForRelease(since, until) {
|
||||
const buckets = { added: [], fixed: [] };
|
||||
let page = 1;
|
||||
for (;;) {
|
||||
const items = await githubGet(`/issues?state=closed&per_page=100&page=${page}`);
|
||||
if (!items.length) break;
|
||||
for (const issue of items) {
|
||||
if (issue.pull_request) continue;
|
||||
const closed = issue.closed_at || "";
|
||||
if (!(closed > since && closed <= until)) continue;
|
||||
const labels = issue.labels.map((l) => l.name);
|
||||
const bucket = Object.keys(LABEL_MAP).find((l) => labels.includes(l));
|
||||
if (bucket) buckets[LABEL_MAP[bucket]].push(`- ${issue.title}`);
|
||||
}
|
||||
if (items.length < 100) break;
|
||||
page++;
|
||||
}
|
||||
return { added: buckets.added.join("\n"), fixed: buckets.fixed.join("\n") };
|
||||
}
|
||||
|
||||
// version-history.xml holds hand-written <changeLog> entries for releases
|
||||
// published before GitHub Releases existed; re-emitted verbatim here.
|
||||
function loadHistoryEntries() {
|
||||
const historyPath = path.join(__dirname, "version-history.xml");
|
||||
const xml = fs.readFileSync(historyPath, "utf-8");
|
||||
return [...xml.matchAll(/<changeLog>[\s\S]*?<\/changeLog>/g)].map((m) => m[0]);
|
||||
}
|
||||
|
||||
function historyEntryVersion(entryXml) {
|
||||
const m = entryXml.match(/<changedVersionNumber>([\s\S]*?)<\/changedVersionNumber>/);
|
||||
return m ? m[1].trim() : null;
|
||||
}
|
||||
|
||||
// Static <roadmap>/<bugsReported> sections carried over from the previous
|
||||
// hand-maintained XML on do5amf.funkerportal.de. UpdateChecker.java doesn't
|
||||
// parse these, kept only so the migration doesn't drop existing content.
|
||||
function loadLegacySections() {
|
||||
const legacyPath = path.join(__dirname, "version-legacy-sections.xml");
|
||||
const xml = fs.readFileSync(legacyPath, "utf-8");
|
||||
const roadmap = xml.match(/<roadmap>[\s\S]*?<\/roadmap>/);
|
||||
const bugsReported = xml.match(/<bugsReported>[\s\S]*?<\/bugsReported>/);
|
||||
return [roadmap ? roadmap[0] : null, bugsReported ? bugsReported[0] : null].filter(Boolean);
|
||||
}
|
||||
|
||||
// Builds kst4ContestVersionInfo.xml (the update-checker feed read by
|
||||
// UpdateChecker.java) from GitHub releases + closed issues, falling back to
|
||||
// version-history.xml for releases that predate GitHub Releases.
|
||||
module.exports = async function () {
|
||||
const fallback = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>\n<praktiKST></praktiKST>';
|
||||
|
||||
try {
|
||||
const historyEntries = loadHistoryEntries();
|
||||
|
||||
const rawReleases = await githubGet("/releases?per_page=100");
|
||||
const releases = rawReleases
|
||||
.map((r) => ({
|
||||
tagName: r.tag_name,
|
||||
publishedAt: r.published_at || "",
|
||||
name: r.name || r.tag_name,
|
||||
body: r.body || "",
|
||||
isPrerelease: r.prerelease
|
||||
}))
|
||||
.sort((a, b) => (a.publishedAt < b.publishedAt ? 1 : -1));
|
||||
|
||||
const stableReleases = releases.filter((r) => !r.isPrerelease);
|
||||
const stable = stableReleases[0];
|
||||
const ghVersions = new Set(stableReleases.map((r) => toAppVersionNumber(r.tagName)));
|
||||
|
||||
const parts = [];
|
||||
parts.push('<?xml version="1.0" encoding="UTF-8" standalone="no"?>');
|
||||
parts.push("<praktiKST>");
|
||||
|
||||
const latestTag = stable ? stable.tagName : null;
|
||||
const winFilename = latestTag ? `praktiKST-${latestTag}-windows-x64.zip` : "";
|
||||
|
||||
parts.push(" <latestVersion>");
|
||||
if (stable) {
|
||||
const latestIssues = await getIssuesForRelease("1970-01-01T00:00:00Z", stable.publishedAt);
|
||||
parts.push(` <versionNumber>${escapeXml(toAppVersionNumber(latestTag))}</versionNumber>`);
|
||||
parts.push(" <adminMessage></adminMessage>");
|
||||
parts.push(` <majorChanges>${escapeXml(latestIssues.added.slice(0, 300))}</majorChanges>`);
|
||||
parts.push(
|
||||
` <latestVersionPathOnWebserver>https://github.com/${REPO}/releases/download/${latestTag}/${winFilename}</latestVersionPathOnWebserver>`
|
||||
);
|
||||
}
|
||||
parts.push(" </latestVersion>");
|
||||
|
||||
// UpdateChecker.parseUpdateXMLFile() never actually reads this field
|
||||
// (setNeedUpdateResourcesSinceLastVersion is never called); the
|
||||
// previous server always hardcoded "nothing" here, so we match that.
|
||||
parts.push(" <needUpdateSinceLastVersion>");
|
||||
parts.push(" <filename>nothing</filename>");
|
||||
parts.push(" </needUpdateSinceLastVersion>");
|
||||
|
||||
for (const section of loadLegacySections()) {
|
||||
parts.push(section);
|
||||
}
|
||||
|
||||
for (let i = 0; i < stableReleases.length; i++) {
|
||||
const rel = stableReleases[i];
|
||||
const until = rel.publishedAt;
|
||||
const since = stableReleases[i + 1] ? stableReleases[i + 1].publishedAt : "1970-01-01T00:00:00Z";
|
||||
const issues = await getIssuesForRelease(since, until);
|
||||
|
||||
parts.push(" <changeLog>");
|
||||
parts.push(` <changedVersionNumber>${escapeXml(toAppVersionNumber(rel.tagName))}</changedVersionNumber>`);
|
||||
parts.push(` <date>${escapeXml(until.slice(0, 10))}</date>`);
|
||||
parts.push(` <description>${escapeXml(rel.name)}</description>`);
|
||||
parts.push(` <added>${escapeXml(issues.added)}</added>`);
|
||||
parts.push(` <changed>${escapeXml(cleanReleaseBody(rel.body))}</changed>`);
|
||||
parts.push(` <fixed>${escapeXml(issues.fixed)}</fixed>`);
|
||||
parts.push(" <removed></removed>");
|
||||
parts.push(" </changeLog>");
|
||||
}
|
||||
|
||||
for (const entry of historyEntries) {
|
||||
const version = historyEntryVersion(entry);
|
||||
if (version && ghVersions.has(version)) continue;
|
||||
parts.push(entry);
|
||||
}
|
||||
|
||||
parts.push("</praktiKST>");
|
||||
return parts.join("\n");
|
||||
} catch (err) {
|
||||
console.warn(`[versionInfo] Could not generate version info XML, using empty fallback: ${err.message}`);
|
||||
return fallback;
|
||||
}
|
||||
};
|
||||
@@ -415,6 +415,23 @@ a:hover {
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.roadmap-version + .roadmap-version {
|
||||
margin-top: 24px;
|
||||
}
|
||||
|
||||
.roadmap-version ul {
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
.roadmap-version li {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.roadmap-done a {
|
||||
color: var(--muted);
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
.feature-icon {
|
||||
font-size: 2rem;
|
||||
margin-bottom: 14px;
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
title: Hotfix Version 1.41.1
|
||||
summary: Hotfix of a bug in Version 1.41
|
||||
date: 2026-07-08
|
||||
---
|
||||
|
||||
## Version 1.41.1
|
||||
We had a bug, where KST4Contest would clear out the text field, where you would send your messages after a period. It also happend to set your Cursor back to the Sending Field, when you were filtering for a station. We fixed this bug today. The new release is [here](https://github.com/praktimarc/kst4contest/releases/tag/v1.41.1). You can also download the artifacts as always via the [Downloads-Page](/download/).
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
---
|
||||
layout: base.njk
|
||||
title: KST4Contest Roadmap
|
||||
description: Planned enhancements for upcoming KST4Contest versions, generated from GitHub milestones and issues.
|
||||
---
|
||||
|
||||
<section class="hero">
|
||||
<p class="badge">Roadmap</p>
|
||||
<h1>What's planned next.</h1>
|
||||
<p class="lead">
|
||||
Generated automatically from the "enhancement" issues in our
|
||||
<a href="https://github.com/praktimarc/kst4contest">GitHub repository</a>,
|
||||
grouped by their target version milestone.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section class="section narrow">
|
||||
{% if roadmap.length == 0 %}
|
||||
<article class="card content-card roadmap-version">
|
||||
<p>No planned enhancements are currently assigned to a version milestone.</p>
|
||||
<p>
|
||||
See all open feature requests on
|
||||
<a href="https://github.com/praktimarc/kst4contest/issues?q=is%3Aissue+is%3Aopen+label%3Aenhancement">GitHub</a>.
|
||||
</p>
|
||||
</article>
|
||||
{% endif %}
|
||||
|
||||
{% for version in roadmap %}
|
||||
<article class="card content-card roadmap-version">
|
||||
{% if version.version %}
|
||||
<h2><a href="{{ version.url }}">{{ version.version }}</a></h2>
|
||||
{% else %}
|
||||
<h2>Planned, no version yet</h2>
|
||||
{% endif %}
|
||||
{% if version.description %}<p>{{ version.description }}</p>{% endif %}
|
||||
{% if version.released %}
|
||||
<p class="eyebrow">Released{% if version.releasedOn %} {{ version.releasedOn | readableDate }}{% endif %}</p>
|
||||
{% elif version.dueOn %}
|
||||
<p class="eyebrow">Due {{ version.dueOn | readableDate }}</p>
|
||||
{% endif %}
|
||||
<ul>
|
||||
{% for item in version.enhancements %}
|
||||
<li{% if item.done or item.notPlanned %} class="roadmap-done"{% endif %}>
|
||||
<a href="{{ item.url }}">{{ item.title }}</a>{% if item.done %} ✓{% endif %}{% if item.notPlanned %} (not planned){% endif %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</article>
|
||||
{% endfor %}
|
||||
</section>
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
permalink: /kst4ContestVersionInfo.xml
|
||||
eleventyExcludeFromCollections: true
|
||||
---
|
||||
{{ versionInfo | safe }}
|
||||
Reference in New Issue
Block a user