Add the Avalonia application and the station network
The entry window types contacts and colours them as they are typed; the log, check, bandmap, score and packet windows read the same session. Contacts are shared with the other stations of a multi-operator entry in N1MM's contact message, so an N1MM station on the same network sees them too. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
using Nonemm.Contests;
|
||||
using Nonemm.Core;
|
||||
using Nonemm.Core.Calls;
|
||||
using Nonemm.Spotting;
|
||||
|
||||
namespace Nonemm.Session;
|
||||
|
||||
/// Answers what the callsign being typed could be, a column per source.
|
||||
public sealed class CheckWindowSources
|
||||
{
|
||||
private readonly LoggingSession session;
|
||||
private readonly CallDatabase database;
|
||||
private readonly Bandmap bandmap;
|
||||
|
||||
public CheckWindowSources(LoggingSession session, CallDatabase database, Bandmap bandmap)
|
||||
{
|
||||
this.session = session;
|
||||
this.database = database;
|
||||
this.bandmap = bandmap;
|
||||
}
|
||||
|
||||
public IReadOnlyList<CheckColumn> Columns(string typed, int limit = 24)
|
||||
{
|
||||
string query = typed.Trim().ToUpperInvariant();
|
||||
return
|
||||
[
|
||||
Column(CheckSource.Log, LoggedCalls(), query, limit),
|
||||
new CheckColumn(
|
||||
CheckSource.Database,
|
||||
database.Count,
|
||||
query.Length < PartialMatching.ShortestUsefulQuery
|
||||
? []
|
||||
: database.Matches(query, limit).Select(Judged).ToList()),
|
||||
Column(CheckSource.Bandmap, SpottedCalls(), query, limit),
|
||||
];
|
||||
}
|
||||
|
||||
private CheckColumn Column(
|
||||
CheckSource source,
|
||||
IReadOnlyList<string> calls,
|
||||
string query,
|
||||
int limit)
|
||||
{
|
||||
if (query.Length < PartialMatching.ShortestUsefulQuery)
|
||||
{
|
||||
return new CheckColumn(source, calls.Count, []);
|
||||
}
|
||||
List<CheckCandidate> found = [];
|
||||
foreach (string call in calls)
|
||||
{
|
||||
PartialMatchQuality? quality = PartialMatching.Judge(query, call);
|
||||
if (quality is not null)
|
||||
{
|
||||
found.Add(Judged(new PartialMatch(call, quality.Value)));
|
||||
}
|
||||
}
|
||||
return new CheckColumn(
|
||||
source,
|
||||
calls.Count,
|
||||
found.OrderBy(c => c.Quality).ThenBy(c => c.Call, StringComparer.Ordinal).Take(limit).ToList());
|
||||
}
|
||||
|
||||
private CheckCandidate Judged(PartialMatch match) =>
|
||||
new(match.Call, match.Quality, VerdictFor(match.Call));
|
||||
|
||||
/// What logging this call on the current band and mode would do.
|
||||
private Verdict? VerdictFor(string call)
|
||||
{
|
||||
Qso candidate = new()
|
||||
{
|
||||
Id = "",
|
||||
TimestampUtc = DateTime.UtcNow,
|
||||
Call = Callsign.Parse(call),
|
||||
Frequency = session.Frequency,
|
||||
Mode = session.Mode,
|
||||
ContestName = session.Contest.Name,
|
||||
};
|
||||
return session.Log.Judge(candidate);
|
||||
}
|
||||
|
||||
private IReadOnlyList<string> LoggedCalls() =>
|
||||
session.Log.Qsos.Select(q => q.Call.Text).Distinct(StringComparer.Ordinal).ToList();
|
||||
|
||||
private IReadOnlyList<string> SpottedCalls() =>
|
||||
bandmap.All().Select(s => s.Call.Text).Distinct(StringComparer.Ordinal).ToList();
|
||||
}
|
||||
Reference in New Issue
Block a user