using XFEEDToolBox.Core.Engineering;
using XFEEDToolBox.Core.Models;
using XFEEDToolBox.Core.Services;
using XFEEDToolBox.Core.Localization;
namespace XFEEDToolBox.Core.Presentation;
public sealed class NavigationLegLiveRow(Navigation.NavigationLegPreview row) : LiveRow<Navigation.NavigationLegPreview>(row)
{
public Navigation.NavigationLegState Status=>Record.Status;
public bool IsRunning=>Status==Navigation.NavigationLegState.Running;
public bool HasIcon=>!IsRunning;
public string Glyph=>Status switch{Navigation.NavigationLegState.Completed=>"\uE73E",Navigation.NavigationLegState.Warning=>"\uE7BA",Navigation.NavigationLegState.Error=>"\uEA39",_=>"\uE823"};
public string Message=>Record.Message;
public bool HasMessage=>Message.Length>0;
public string Title=>Record.Title;
public string Details=>Record.Details;
public string State=>Record.State;
public string Fuel=>Record.Fuel;
}
public sealed class MarketLiveRow(MarketRow row) : LiveRow<MarketRow>(row)
{
public string Name => Record.Name;
public string Source => Record.Source;
public string SystemName => Record.Station.SystemName;
public string StationName => Record.Station.Name;
public string Location => Record.Station.DisplayName;
public string SourceAndTime => $"{Source} · {Record.Quote.CollectedAt.ToLocalTime():yyyy-MM-dd HH:mm}";
public string Category => string.IsNullOrWhiteSpace(Record.Quote.Category)?"未提供分类":Record.Quote.Category;
public string CollectedAtFull => Record.Quote.CollectedAt.ToLocalTime().ToString("yyyy-MM-dd HH:mm:ss");
public string StationAccess => $"{Record.Station.MaxLandingPad switch{LandingPad.Large=>"大型 L",LandingPad.Medium=>"中型 M",LandingPad.Small=>"小型 S",_=>"停机坪未知"}} · {Record.Station.SecurityDisplay}";
public string ArrivalDistance => Record.Station.DistanceToArrivalLs is {} distance?$"{distance:N1} ls":"抵达距离未知";
public string Buy => Record.Buy;
public string Sell => Record.Sell;
public string Supply => Record.Supply;
public string Demand => Record.Demand;
// Absolute source time stays truthful when no data update occurs.
public string Updated => Record.Quote.CollectedAt.ToLocalTime().ToString("MM-dd HH:mm:ss");
}
public sealed class MaterialLiveRow(MaterialStock row) : LiveRow<MaterialStock>(row)
{
public int Grade=>Record.Grade;
public string Category => Record.Category;
public string Key => Record.Key;
public string Name => Record.Name;
public string Detail => Record.Detail;
public string CategoryName=>ChineseNames.Category(Record.Category);
public string GradeLabel=>Record.Grade>0?$"G{Record.Grade}":"—";
public string Quantity=>Record.Capacity>0?$"{Record.Owned:N0} / {Record.Capacity:N0}":$"{Record.Owned:N0} / —";
public int Owned => Record.Owned;
public double FillPercent => Record.Capacity>0?100.0*Record.Owned/Record.Capacity:0;
public bool HasCapacity => Record.Capacity>0;
}
public sealed class MaterialNeedLiveRow(MaterialNeed row) : LiveRow<MaterialNeed>(row)
{
public string Key=>Record.Key;
public string Name=>Record.Name;
public string Category=>Record.Category;
public int Grade=>Record.Grade;
public string Detail=>Record.Detail;
public int Missing=>Record.Missing;
public string MissingText=>Record.MissingText;
public string StockText=>Record.StockText;
public string RequiredText=>Record.RequiredText;
}
public sealed class InventoryLiveRow(InventoryItem row) : LiveRow<InventoryItem>(row)
{
public string Key => Record.Key;
public string Name => Record.Name;
public string Group => Record.Group;
public int Count => Record.Count;
public int Stolen => Record.Stolen;
public long? MissionId => Record.MissionId;
}
public sealed class ShipLiveRow(ShipRecord row) : LiveRow<ShipRecord>(row)
{
public long ShipId => Record.ShipId;
public string Type => ChineseNames.Ship(Record.Type);
public string OriginalName => Record.OriginalName;
public string DisplayName => Record.DisplayName;
public string Ident => Record.Ident;
public string Location => Record.Location;
public string ConfigurationStatus => Record.ConfigurationStatus;
public DateTimeOffset? ConfigurationAt => Record.ConfigurationAt;
public bool ConfigurationChanged => Record.ConfigurationChanged;
public int? CargoCapacity => Record.CargoCapacity;
public double? MaxJumpRange => Record.MaxJumpRange;
public decimal? Rebuy => Record.Rebuy;
public IReadOnlyList<FittedModule> Modules => Record.Modules;
}
public sealed class ModuleLiveRow(FittedModule row) : LiveRow<FittedModule>(row)
{
public string Slot => Record.Slot;
public string Item => Record.Item;
public string Name => Record.DisplayName;
public string OriginalName => Record.OriginalName;
public string SlotName => Record.SlotName;
public string SlotOriginal => Record.SlotOriginal;
public string State => Record.State;
public string HealthText => Record.HealthText;
public string EngineeringText => Record.EngineeringText;
public string EngineeringOriginal => Record.EngineeringOriginal;
public double HealthPercent => (Record.Health??0)*100;
public bool HasHealth => Record.Health is not null;
public string ModifierText => Record.ModifierText;
public IReadOnlyList<EngineeringModifier> Modifiers=>Record.Engineering?.Modifiers??[];
public string AmmoText => Record.AmmoText;
public ModuleEngineering? Engineering => Record.Engineering;
}
public sealed class StoredModuleLiveRow(StoredModule row) : LiveRow<StoredModule>(row)
{
public string Name => ChineseNames.Module(Record.Item,Record.Name);
public string OriginalName => ChineseNames.ModuleEnglish(Record.Item,Record.Name);
public string SystemName => Record.SystemName;
public string EngineeringText => Record.EngineeringText;
public string EngineeringOriginal => Record.EngineeringOriginal;
public string TransferText => Record.TransferText;
}
public sealed class EngineerLiveRow(EngineerAccess row) : LiveRow<EngineerAccess>(row)
{
public long Id => Record.Id;
public string Name => Record.Name;
public string DisplayName => ChineseNames.Translate(Record.Name);
public string OriginalName => Record.Name;
public string? Portrait => Galaxy.EngineerDirectory.Find(Record.Name)?.Portrait;
public int Rank => Record.Rank;
public bool Unlocked => Record.Unlocked;
public string Status => Record.Status;
public string Display => DisplayName+" · "+Status;
public bool HasRankProgress => Record.Unlocked&&(Record.Rank==5||Record.RankProgress is not null);
public double RankPercent => Record.Rank==5?100:Record.RankProgress??0;
}
public sealed class StationLiveRow(Station row) : LiveRow<Station>(row)
{
public long MarketId => Record.MarketId;
public string DisplayName => Record.DisplayName;
}
public sealed class ReadCheckLiveRow(ReadVerificationItem row) : LiveRow<ReadVerificationItem>(row)
{
public string Category => Record.Category;
public string Status => Record.Status;
public int Count => Record.Count;
public string Updated => Record.Updated;
public string Source => Record.Source;
public string Note => Record.Note;
}
public sealed class ActivityLiveRow(ActivityEntry row) : LiveRow<ActivityEntry>(row)
{
public string TimeDisplay => Record.TimeDisplay;
public string Kind => Record.Kind;
public string Message => Record.Message;
public string SeverityDisplay=>Record.SeverityDisplay;
public string RepetitionDisplay=>Record.RepetitionDisplay;
public bool HasDiagnostic=>Record.HasDiagnostic;
public string DiagnosticDisplay=>Record.DiagnosticDisplay;
}
using XFEEDToolBox.Core.Engineering;
using XFEEDToolBox.Core.Models;
using XFEEDToolBox.Core.Services;
using XFEEDToolBox.Core.Localization;
namespace XFEEDToolBox.Core.Presentation;
public sealed class NavigationLegLiveRow(Navigation.NavigationLegPreview row) : LiveRow<Navigation.NavigationLegPreview>(row)
{
public Navigation.NavigationLegState Status=>Record.Status;
public bool IsRunning=>Status==Navigation.NavigationLegState.Running;
public bool HasIcon=>!IsRunning;
public string Glyph=>Status switch{Navigation.NavigationLegState.Completed=>"\uE73E",Navigation.NavigationLegState.Warning=>"\uE7BA",Navigation.NavigationLegState.Error=>"\uEA39",_=>"\uE823"};
public string Message=>Record.Message;
public bool HasMessage=>Message.Length>0;
public string Title=>Record.Title;
public string Details=>Record.Details;
public string State=>Record.State;
public string Fuel=>Record.Fuel;
}
public sealed class MarketLiveRow(MarketRow row) : LiveRow<MarketRow>(row)
{
public string Name => Record.Name;
public string Source => Record.Source;
public string SystemName => Record.Station.SystemName;
public string StationName => Record.Station.Name;
public string Location => Record.Station.DisplayName;
public string SourceAndTime => $"{Source} · {Record.Quote.CollectedAt.ToLocalTime():yyyy-MM-dd HH:mm}";
public string Category => string.IsNullOrWhiteSpace(Record.Quote.Category)?"未提供分类":Record.Quote.Category;
public string CollectedAtFull => Record.Quote.CollectedAt.ToLocalTime().ToString("yyyy-MM-dd HH:mm:ss");
public string StationAccess => $"{Record.Station.MaxLandingPad switch{LandingPad.Large=>"大型 L",LandingPad.Medium=>"中型 M",LandingPad.Small=>"小型 S",_=>"停机坪未知"}} · {Record.Station.SecurityDisplay}";
public string ArrivalDistance => Record.Station.DistanceToArrivalLs is {} distance?$"{distance:N1} ls":"抵达距离未知";
public string Buy => Record.Buy;
public string Sell => Record.Sell;
public string Supply => Record.Supply;
public string Demand => Record.Demand;
// Absolute source time stays truthful when no data update occurs.
public string Updated => Record.Quote.CollectedAt.ToLocalTime().ToString("MM-dd HH:mm:ss");
}
public sealed class MaterialLiveRow(MaterialStock row) : LiveRow<MaterialStock>(row)
{
public int Grade=>Record.Grade;
public string Category => Record.Category;
public string Key => Record.Key;
public string Name => Record.Name;
public string Detail => Record.Detail;
public string CategoryName=>ChineseNames.Category(Record.Category);
public string GradeLabel=>Record.Grade>0?$"G{Record.Grade}":"—";
public string Quantity=>Record.Capacity>0?$"{Record.Owned:N0} / {Record.Capacity:N0}":$"{Record.Owned:N0} / —";
public int Owned => Record.Owned;
public double FillPercent => Record.Capacity>0?100.0*Record.Owned/Record.Capacity:0;
public bool HasCapacity => Record.Capacity>0;
}
public sealed class MaterialNeedLiveRow(MaterialNeed row) : LiveRow<MaterialNeed>(row)
{
public string Key=>Record.Key;
public string Name=>Record.Name;
public string Category=>Record.Category;
public int Grade=>Record.Grade;
public string Detail=>Record.Detail;
public int Missing=>Record.Missing;
public string MissingText=>Record.MissingText;
public string StockText=>Record.StockText;
public string RequiredText=>Record.RequiredText;
}
public sealed class InventoryLiveRow(InventoryItem row) : LiveRow<InventoryItem>(row)
{
public string Key => Record.Key;
public string Name => Record.Name;
public string Group => Record.Group;
public int Count => Record.Count;
public int Stolen => Record.Stolen;
public long? MissionId => Record.MissionId;
}
public sealed class ShipLiveRow(ShipRecord row) : LiveRow<ShipRecord>(row)
{
public long ShipId => Record.ShipId;
public string Type => ChineseNames.Ship(Record.Type);
public string OriginalName => Record.OriginalName;
public string DisplayName => Record.DisplayName;
public string Ident => Record.Ident;
public string Location => Record.Location;
public string ConfigurationStatus => Record.ConfigurationStatus;
public DateTimeOffset? ConfigurationAt => Record.ConfigurationAt;
public bool ConfigurationChanged => Record.ConfigurationChanged;
public int? CargoCapacity => Record.CargoCapacity;
public double? MaxJumpRange => Record.MaxJumpRange;
public decimal? Rebuy => Record.Rebuy;
public IReadOnlyList<FittedModule> Modules => Record.Modules;
}
public sealed class ModuleLiveRow(FittedModule row) : LiveRow<FittedModule>(row)
{
public string Slot => Record.Slot;
public string Item => Record.Item;
public string Name => Record.DisplayName;
public string OriginalName => Record.OriginalName;
public string SlotName => Record.SlotName;
public string SlotOriginal => Record.SlotOriginal;
public string State => Record.State;
public string HealthText => Record.HealthText;
public string EngineeringText => Record.EngineeringText;
public string EngineeringOriginal => Record.EngineeringOriginal;
public double HealthPercent => (Record.Health??0)*100;
public bool HasHealth => Record.Health is not null;
public string ModifierText => Record.ModifierText;
public IReadOnlyList<EngineeringModifier> Modifiers=>Record.Engineering?.Modifiers??[];
public string AmmoText => Record.AmmoText;
public ModuleEngineering? Engineering => Record.Engineering;
}
public sealed class StoredModuleLiveRow(StoredModule row) : LiveRow<StoredModule>(row)
{
public string Name => ChineseNames.Module(Record.Item,Record.Name);
public string OriginalName => ChineseNames.ModuleEnglish(Record.Item,Record.Name);
public string SystemName => Record.SystemName;
public string EngineeringText => Record.EngineeringText;
public string EngineeringOriginal => Record.EngineeringOriginal;
public string TransferText => Record.TransferText;
}
public sealed class EngineerLiveRow(EngineerAccess row) : LiveRow<EngineerAccess>(row)
{
public long Id => Record.Id;
public string Name => Record.Name;
public string DisplayName => ChineseNames.Translate(Record.Name);
public string OriginalName => Record.Name;
public string? Portrait => Galaxy.EngineerDirectory.Find(Record.Name)?.Portrait;
public int Rank => Record.Rank;
public bool Unlocked => Record.Unlocked;
public string Status => Record.Status;
public string Display => DisplayName+" · "+Status;
public bool HasRankProgress => Record.Unlocked&&(Record.Rank==5||Record.RankProgress is not null);
public double RankPercent => Record.Rank==5?100:Record.RankProgress??0;
}
public sealed class StationLiveRow(Station row) : LiveRow<Station>(row)
{
public long MarketId => Record.MarketId;
public string DisplayName => Record.DisplayName;
}
public sealed class ReadCheckLiveRow(ReadVerificationItem row) : LiveRow<ReadVerificationItem>(row)
{
public string Category => Record.Category;
public string Status => Record.Status;
public int Count => Record.Count;
public string Updated => Record.Updated;
public string Source => Record.Source;
public string Note => Record.Note;
}
public sealed class ActivityLiveRow(ActivityEntry row) : LiveRow<ActivityEntry>(row)
{
public string TimeDisplay => Record.TimeDisplay;
public string Kind => Record.Kind;
public string Message => Record.Message;
public string SeverityDisplay=>Record.SeverityDisplay;
public string RepetitionDisplay=>Record.RepetitionDisplay;
public bool HasDiagnostic=>Record.HasDiagnostic;
public string DiagnosticDisplay=>Record.DiagnosticDisplay;
}