using Dalamud.Game.Gui.Dtr; using Dalamud.Plugin.Services; using MareSynchronos.MareConfiguration; using MareSynchronos.MareConfiguration.Configurations; using MareSynchronos.PlayerData.Pairs; using MareSynchronos.Services.Mediator; using MareSynchronos.WebAPI; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; namespace MareSynchronos.UI; public sealed class DtrEntry : IDisposable, IHostedService { private enum DtrStyle { Default, Style1, Style2, Style3, Style4, Style5, Style6, Style7, Style8, Style9 } public const int NumStyles = 10; private readonly ApiController _apiController; private readonly CancellationTokenSource _cancellationTokenSource = new(); private readonly ConfigurationServiceBase _configService; private readonly IDtrBar _dtrBar; private readonly Lazy _entry; private readonly ILogger _logger; private readonly MareMediator _mareMediator; private readonly PairManager _pairManager; private Task? _runTask; private string? _text; public DtrEntry(ILogger logger, IDtrBar dtrBar, ConfigurationServiceBase configService, MareMediator mareMediator, PairManager pairManager, ApiController apiController) { _logger = logger; _dtrBar = dtrBar; _entry = new(CreateEntry); _configService = configService; _mareMediator = mareMediator; _pairManager = pairManager; _apiController = apiController; } public void Dispose() { if (_entry.IsValueCreated) { _logger.LogDebug("Disposing DtrEntry"); Clear(); _entry.Value.Remove(); } } public Task StartAsync(CancellationToken cancellationToken) { _runTask = Task.Run(RunAsync, _cancellationTokenSource.Token); return Task.CompletedTask; } public async Task StopAsync(CancellationToken cancellationToken) { _cancellationTokenSource.Cancel(); try { await _runTask!.ConfigureAwait(false); } catch (OperationCanceledException) { // ignore cancelled } finally { _cancellationTokenSource.Dispose(); } } private void Clear() { if (!_entry.IsValueCreated) return; _logger.LogInformation("Clearing entry"); _text = null; _entry.Value.Shown = false; } private IDtrBarEntry CreateEntry() { _logger.LogTrace("Creating new DtrBar entry"); var entry = _dtrBar.Get("Loporrit"); entry.OnClick = () => _mareMediator.Publish(new UiToggleMessage(typeof(CompactUi))); return entry; } private async Task RunAsync() { while (!_cancellationTokenSource.IsCancellationRequested) { await Task.Delay(1000, _cancellationTokenSource.Token).ConfigureAwait(false); Update(); } } private void Update() { if (!_configService.Current.EnableDtrEntry || !_configService.Current.HasValidSetup()) { if (_entry.IsValueCreated && _entry.Value.Shown) { _logger.LogInformation("Disabling entry"); Clear(); } return; } if (!_entry.Value.Shown) { _logger.LogInformation("Showing entry"); _entry.Value.Shown = true; } string text; string tooltip; if (_apiController.IsConnected) { var pairCount = _pairManager.GetVisibleUserCount(); text = RenderDtrStyle(_configService.Current.DtrStyle, pairCount.ToString()); if (pairCount > 0) { IEnumerable visiblePairs; if (_configService.Current.ShowUidInDtrTooltip) { visiblePairs = _pairManager.GetOnlineUserPairs() .Where(x => x.IsVisible) .Select(x => string.Format("{0} ({1})", _configService.Current.PreferNoteInDtrTooltip ? x.GetNoteOrName() : x.PlayerName, x.UserData.AliasOrUID )); } else { visiblePairs = _pairManager.GetOnlineUserPairs() .Where(x => x.IsVisible) .Select(x => string.Format("{0}", _configService.Current.PreferNoteInDtrTooltip ? x.GetNoteOrName() : x.PlayerName)); } tooltip = $"Loporrit: Connected{Environment.NewLine}----------{Environment.NewLine}{string.Join(Environment.NewLine, visiblePairs)}"; } else { tooltip = "Loporrit: Connected"; } } else { text = RenderDtrStyle(_configService.Current.DtrStyle, "\uE04C"); tooltip = "Loporrit: Not Connected"; } if (!string.Equals(text, _text, StringComparison.Ordinal)) { _text = text; _entry.Value.Text = text; _entry.Value.Tooltip = tooltip; } } public static string RenderDtrStyle(int styleNum, string text) { var style = (DtrStyle)styleNum; return style switch { DtrStyle.Style1 => $"\xE039 {text}", DtrStyle.Style2 => $"\xE0BC {text}", DtrStyle.Style3 => $"\xE0BD {text}", DtrStyle.Style4 => $"\xE03A {text}", DtrStyle.Style5 => $"\xE033 {text}", DtrStyle.Style6 => $"\xE038 {text}", DtrStyle.Style7 => $"\xE05D {text}", DtrStyle.Style8 => $"\xE03C{text}", DtrStyle.Style9 => $"\xE040 {text} \xE041", _ => $"\uE044 {text}" }; } }