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(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(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(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(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(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(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 Modules => Record.Modules; } public sealed class ModuleLiveRow(FittedModule row) : LiveRow(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 Modifiers=>Record.Engineering?.Modifiers??[]; public string AmmoText => Record.AmmoText; public ModuleEngineering? Engineering => Record.Engineering; } public sealed class StoredModuleLiveRow(StoredModule row) : LiveRow(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(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(row) { public long MarketId => Record.MarketId; public string DisplayName => Record.DisplayName; } public sealed class ReadCheckLiveRow(ReadVerificationItem row) : LiveRow(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(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; }