Merge branch '1.12.0' into ui-redesign
This commit is contained in:
Submodule LightlessAPI updated: fd4cd52d2e...5bfd21aaa9
@@ -230,7 +230,7 @@ public sealed class Plugin : IDalamudPlugin
|
|||||||
s.GetRequiredService<LightlessProfileManager>(), s.GetRequiredService<PerformanceCollectorService>()));
|
s.GetRequiredService<LightlessProfileManager>(), s.GetRequiredService<PerformanceCollectorService>()));
|
||||||
collection.AddScoped<WindowMediatorSubscriberBase, PopupHandler>();
|
collection.AddScoped<WindowMediatorSubscriberBase, PopupHandler>();
|
||||||
collection.AddScoped<WindowMediatorSubscriberBase, BroadcastUI>((s) => new BroadcastUI(s.GetRequiredService<ILogger<BroadcastUI>>(), s.GetRequiredService<LightlessMediator>(), s.GetRequiredService<PerformanceCollectorService>(), s.GetRequiredService<BroadcastService>(), s.GetRequiredService<LightlessConfigService>(), s.GetRequiredService<UiSharedService>(), s.GetRequiredService<ApiController>(), s.GetRequiredService<BroadcastScannerService>()));
|
collection.AddScoped<WindowMediatorSubscriberBase, BroadcastUI>((s) => new BroadcastUI(s.GetRequiredService<ILogger<BroadcastUI>>(), s.GetRequiredService<LightlessMediator>(), s.GetRequiredService<PerformanceCollectorService>(), s.GetRequiredService<BroadcastService>(), s.GetRequiredService<LightlessConfigService>(), s.GetRequiredService<UiSharedService>(), s.GetRequiredService<ApiController>(), s.GetRequiredService<BroadcastScannerService>()));
|
||||||
collection.AddScoped<WindowMediatorSubscriberBase, SyncshellFinderUI>((s) => new SyncshellFinderUI(s.GetRequiredService<ILogger<SyncshellFinderUI>>(), s.GetRequiredService<LightlessMediator>(), s.GetRequiredService<PerformanceCollectorService>(), s.GetRequiredService<BroadcastService>(), s.GetRequiredService<LightlessConfigService>(), s.GetRequiredService<UiSharedService>(), s.GetRequiredService<ApiController>(), s.GetRequiredService<BroadcastScannerService>()));
|
collection.AddScoped<WindowMediatorSubscriberBase, SyncshellFinderUI>((s) => new SyncshellFinderUI(s.GetRequiredService<ILogger<SyncshellFinderUI>>(), s.GetRequiredService<LightlessMediator>(), s.GetRequiredService<PerformanceCollectorService>(), s.GetRequiredService<BroadcastService>(), s.GetRequiredService<UiSharedService>(), s.GetRequiredService<ApiController>(), s.GetRequiredService<BroadcastScannerService>(), s.GetRequiredService<PairManager>()));
|
||||||
collection.AddScoped<IPopupHandler, BanUserPopupHandler>();
|
collection.AddScoped<IPopupHandler, BanUserPopupHandler>();
|
||||||
collection.AddScoped<IPopupHandler, CensusPopupHandler>();
|
collection.AddScoped<IPopupHandler, CensusPopupHandler>();
|
||||||
collection.AddScoped<CacheCreationService>();
|
collection.AddScoped<CacheCreationService>();
|
||||||
|
|||||||
@@ -4,9 +4,7 @@ using LightlessSync.LightlessConfiguration;
|
|||||||
using LightlessSync.Services.Mediator;
|
using LightlessSync.Services.Mediator;
|
||||||
using LightlessSync.Utils;
|
using LightlessSync.Utils;
|
||||||
using LightlessSync.WebAPI;
|
using LightlessSync.WebAPI;
|
||||||
using LightlessSync.WebAPI.SignalR;
|
|
||||||
using Microsoft.AspNetCore.SignalR;
|
using Microsoft.AspNetCore.SignalR;
|
||||||
using Microsoft.AspNetCore.SignalR.Client;
|
|
||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
@@ -16,7 +14,6 @@ public class BroadcastService : IHostedService, IMediatorSubscriber
|
|||||||
private readonly ILogger<BroadcastService> _logger;
|
private readonly ILogger<BroadcastService> _logger;
|
||||||
private readonly ApiController _apiController;
|
private readonly ApiController _apiController;
|
||||||
private readonly LightlessMediator _mediator;
|
private readonly LightlessMediator _mediator;
|
||||||
private readonly HubFactory _hubFactory;
|
|
||||||
private readonly LightlessConfigService _config;
|
private readonly LightlessConfigService _config;
|
||||||
private readonly DalamudUtilService _dalamudUtil;
|
private readonly DalamudUtilService _dalamudUtil;
|
||||||
public LightlessMediator Mediator => _mediator;
|
public LightlessMediator Mediator => _mediator;
|
||||||
@@ -29,35 +26,37 @@ public class BroadcastService : IHostedService, IMediatorSubscriber
|
|||||||
private TimeSpan? _remainingTtl = null;
|
private TimeSpan? _remainingTtl = null;
|
||||||
private DateTime _lastTtlCheck = DateTime.MinValue;
|
private DateTime _lastTtlCheck = DateTime.MinValue;
|
||||||
private DateTime _lastForcedDisableTime = DateTime.MinValue;
|
private DateTime _lastForcedDisableTime = DateTime.MinValue;
|
||||||
private static readonly TimeSpan DisableCooldown = TimeSpan.FromSeconds(5);
|
private static readonly TimeSpan _disableCooldown = TimeSpan.FromSeconds(5);
|
||||||
public TimeSpan? RemainingTtl => _remainingTtl;
|
public TimeSpan? RemainingTtl => _remainingTtl;
|
||||||
public TimeSpan? RemainingCooldown
|
public TimeSpan? RemainingCooldown
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
var elapsed = DateTime.UtcNow - _lastForcedDisableTime;
|
var elapsed = DateTime.UtcNow - _lastForcedDisableTime;
|
||||||
if (elapsed >= DisableCooldown) return null;
|
if (elapsed >= _disableCooldown) return null;
|
||||||
return DisableCooldown - elapsed;
|
return _disableCooldown - elapsed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public BroadcastService(ILogger<BroadcastService> logger, LightlessMediator mediator, HubFactory hubFactory, LightlessConfigService config, DalamudUtilService dalamudUtil, ApiController apiController)
|
|
||||||
|
public BroadcastService(ILogger<BroadcastService> logger, LightlessMediator mediator, LightlessConfigService config, DalamudUtilService dalamudUtil, ApiController apiController)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_mediator = mediator;
|
_mediator = mediator;
|
||||||
_hubFactory = hubFactory;
|
|
||||||
_config = config;
|
_config = config;
|
||||||
_dalamudUtil = dalamudUtil;
|
_dalamudUtil = dalamudUtil;
|
||||||
_apiController = apiController;
|
_apiController = apiController;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task RequireConnectionAsync(string context, Func<Task> action)
|
private async Task RequireConnectionAsync(string context, Func<Task> action)
|
||||||
{
|
{
|
||||||
if (!_apiController.IsConnected)
|
if (!_apiController.IsConnected)
|
||||||
{
|
{
|
||||||
_logger.LogDebug($"{context} skipped, not connected");
|
_logger.LogDebug(context + " skipped, not connected");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await action().ConfigureAwait(false);
|
await action().ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task StartAsync(CancellationToken cancellationToken)
|
public async Task StartAsync(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
_mediator.Subscribe<EnableBroadcastMessage>(this, OnEnableBroadcast);
|
_mediator.Subscribe<EnableBroadcastMessage>(this, OnEnableBroadcast);
|
||||||
@@ -65,7 +64,7 @@ public class BroadcastService : IHostedService, IMediatorSubscriber
|
|||||||
_mediator.Subscribe<PriorityFrameworkUpdateMessage>(this, OnTick);
|
_mediator.Subscribe<PriorityFrameworkUpdateMessage>(this, OnTick);
|
||||||
|
|
||||||
_apiController.OnConnected += () => _ = CheckLightfinderSupportAsync(cancellationToken);
|
_apiController.OnConnected += () => _ = CheckLightfinderSupportAsync(cancellationToken);
|
||||||
_ = CheckLightfinderSupportAsync(cancellationToken);
|
//_ = CheckLightfinderSupportAsync(cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task StopAsync(CancellationToken cancellationToken)
|
public Task StopAsync(CancellationToken cancellationToken)
|
||||||
@@ -86,13 +85,12 @@ public class BroadcastService : IHostedService, IMediatorSubscriber
|
|||||||
if (cancellationToken.IsCancellationRequested)
|
if (cancellationToken.IsCancellationRequested)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var hub = _hubFactory.GetOrCreate(CancellationToken.None);
|
|
||||||
var dummy = "0".PadLeft(64, '0');
|
var dummy = "0".PadLeft(64, '0');
|
||||||
|
|
||||||
await hub.InvokeAsync<BroadcastStatusInfoDto?>("IsUserBroadcasting", dummy, cancellationToken);
|
await _apiController.IsUserBroadcasting(dummy).ConfigureAwait(false);
|
||||||
await hub.InvokeAsync("SetBroadcastStatus", dummy, true, null, cancellationToken);
|
await _apiController.SetBroadcastStatus(dummy, true, null).ConfigureAwait(false);
|
||||||
await hub.InvokeAsync<TimeSpan?>("GetBroadcastTtl", dummy, cancellationToken);
|
await _apiController.GetBroadcastTtl(dummy).ConfigureAwait(false);
|
||||||
await hub.InvokeAsync<Dictionary<string, BroadcastStatusInfoDto?>>("AreUsersBroadcasting", new[] { dummy }, cancellationToken);
|
await _apiController.AreUsersBroadcasting([dummy]).ConfigureAwait(false);
|
||||||
|
|
||||||
IsLightFinderAvailable = true;
|
IsLightFinderAvailable = true;
|
||||||
_logger.LogInformation("Lightfinder is available.");
|
_logger.LogInformation("Lightfinder is available.");
|
||||||
@@ -119,6 +117,7 @@ public class BroadcastService : IHostedService, IMediatorSubscriber
|
|||||||
_config.Current.BroadcastEnabled = false;
|
_config.Current.BroadcastEnabled = false;
|
||||||
_config.Current.BroadcastTtl = DateTime.MinValue;
|
_config.Current.BroadcastTtl = DateTime.MinValue;
|
||||||
_config.Save();
|
_config.Save();
|
||||||
|
|
||||||
_mediator.Publish(new BroadcastStatusChangedMessage(false, null));
|
_mediator.Publish(new BroadcastStatusChangedMessage(false, null));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -157,7 +156,7 @@ public class BroadcastService : IHostedService, IMediatorSubscriber
|
|||||||
|
|
||||||
_waitingForTtlFetch = true;
|
_waitingForTtlFetch = true;
|
||||||
|
|
||||||
var ttl = await GetBroadcastTtlAsync(msg.HashedCid).ConfigureAwait(false);
|
TimeSpan? ttl = await GetBroadcastTtlAsync(msg.HashedCid).ConfigureAwait(false);
|
||||||
|
|
||||||
if (ttl is { } remaining && remaining > TimeSpan.Zero)
|
if (ttl is { } remaining && remaining > TimeSpan.Zero)
|
||||||
{
|
{
|
||||||
@@ -325,8 +324,8 @@ public class BroadcastService : IHostedService, IMediatorSubscriber
|
|||||||
_syncedOnStartup = true;
|
_syncedOnStartup = true;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var hashedCid = (await _dalamudUtil.GetCIDAsync().ConfigureAwait(false)).ToString().GetHash256();
|
string hashedCid = (await _dalamudUtil.GetCIDAsync().ConfigureAwait(false)).ToString().GetHash256();
|
||||||
var ttl = await GetBroadcastTtlAsync(hashedCid).ConfigureAwait(false);
|
TimeSpan? ttl = await GetBroadcastTtlAsync(hashedCid).ConfigureAwait(false);
|
||||||
if (ttl is { }
|
if (ttl is { }
|
||||||
remaining && remaining > TimeSpan.Zero)
|
remaining && remaining > TimeSpan.Zero)
|
||||||
{
|
{
|
||||||
@@ -357,8 +356,8 @@ public class BroadcastService : IHostedService, IMediatorSubscriber
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var expiry = _config.Current.BroadcastTtl;
|
DateTime expiry = _config.Current.BroadcastTtl;
|
||||||
var remaining = expiry - DateTime.UtcNow;
|
TimeSpan remaining = expiry - DateTime.UtcNow;
|
||||||
_remainingTtl = remaining > TimeSpan.Zero ? remaining : null;
|
_remainingTtl = remaining > TimeSpan.Zero ? remaining : null;
|
||||||
if (_remainingTtl == null)
|
if (_remainingTtl == null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ namespace LightlessSync.UI
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_allSyncshells = await _apiController.GroupsGetAll();
|
_allSyncshells = await _apiController.GroupsGetAll().ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -131,7 +131,7 @@ namespace LightlessSync.UI
|
|||||||
ImGuiHelpers.ScaledDummy(0.25f);
|
ImGuiHelpers.ScaledDummy(0.25f);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui.BeginTabBar("##MyTabBar"))
|
if (ImGui.BeginTabBar("##BroadcastTabs"))
|
||||||
{
|
{
|
||||||
if (ImGui.BeginTabItem("Lightfinder"))
|
if (ImGui.BeginTabItem("Lightfinder"))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -141,7 +141,7 @@ public class CompactUi : WindowMediatorSubscriberBase
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
_drawFolders = [.. GetDrawFolders()];
|
_drawFolders = [.. DrawFolders];
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
string dev = "Dev Build";
|
string dev = "Dev Build";
|
||||||
@@ -158,7 +158,7 @@ public class CompactUi : WindowMediatorSubscriberBase
|
|||||||
Mediator.Subscribe<CutsceneEndMessage>(this, (_) => UiSharedService_GposeEnd());
|
Mediator.Subscribe<CutsceneEndMessage>(this, (_) => UiSharedService_GposeEnd());
|
||||||
Mediator.Subscribe<DownloadStartedMessage>(this, (msg) => _currentDownloads[msg.DownloadId] = msg.DownloadStatus);
|
Mediator.Subscribe<DownloadStartedMessage>(this, (msg) => _currentDownloads[msg.DownloadId] = msg.DownloadStatus);
|
||||||
Mediator.Subscribe<DownloadFinishedMessage>(this, (msg) => _currentDownloads.TryRemove(msg.DownloadId, out _));
|
Mediator.Subscribe<DownloadFinishedMessage>(this, (msg) => _currentDownloads.TryRemove(msg.DownloadId, out _));
|
||||||
Mediator.Subscribe<RefreshUiMessage>(this, (msg) => _drawFolders = GetDrawFolders().ToList());
|
Mediator.Subscribe<RefreshUiMessage>(this, (msg) => _drawFolders = DrawFolders.ToList());
|
||||||
|
|
||||||
Flags |= ImGuiWindowFlags.NoDocking;
|
Flags |= ImGuiWindowFlags.NoDocking;
|
||||||
|
|
||||||
@@ -561,6 +561,7 @@ public class CompactUi : WindowMediatorSubscriberBase
|
|||||||
if ((isOverTriHold || isOverVRAMUsage) && _playerPerformanceConfig.Current.WarnOnExceedingThresholds)
|
if ((isOverTriHold || isOverVRAMUsage) && _playerPerformanceConfig.Current.WarnOnExceedingThresholds)
|
||||||
{
|
{
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
|
ImGui.SetCursorPosY(cursorY + 15f);
|
||||||
_uiSharedService.IconText(FontAwesomeIcon.ExclamationTriangle, UIColors.Get("LightlessYellow"));
|
_uiSharedService.IconText(FontAwesomeIcon.ExclamationTriangle, UIColors.Get("LightlessYellow"));
|
||||||
|
|
||||||
string warningMessage = "";
|
string warningMessage = "";
|
||||||
@@ -611,152 +612,151 @@ public class CompactUi : WindowMediatorSubscriberBase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private IEnumerable<IDrawFolder> GetDrawFolders()
|
private IEnumerable<IDrawFolder> DrawFolders
|
||||||
{
|
{
|
||||||
List<IDrawFolder> drawFolders = [];
|
get
|
||||||
|
|
||||||
var allPairs = _pairManager.PairsWithGroups
|
|
||||||
.ToDictionary(k => k.Key, k => k.Value);
|
|
||||||
var filteredPairs = allPairs
|
|
||||||
.Where(p =>
|
|
||||||
{
|
{
|
||||||
if (_tabMenu.Filter.IsNullOrEmpty()) return true;
|
var drawFolders = new List<IDrawFolder>();
|
||||||
return p.Key.UserData.AliasOrUID.Contains(_tabMenu.Filter, StringComparison.OrdinalIgnoreCase) ||
|
var filter = _tabMenu.Filter;
|
||||||
(p.Key.GetNote()?.Contains(_tabMenu.Filter, StringComparison.OrdinalIgnoreCase) ?? false) ||
|
|
||||||
(p.Key.PlayerName?.Contains(_tabMenu.Filter, StringComparison.OrdinalIgnoreCase) ?? false);
|
|
||||||
})
|
|
||||||
.ToDictionary(k => k.Key, k => k.Value);
|
|
||||||
|
|
||||||
string? AlphabeticalSort(KeyValuePair<Pair, List<GroupFullInfoDto>> u)
|
|
||||||
=> (_configService.Current.ShowCharacterNameInsteadOfNotesForVisible && !string.IsNullOrEmpty(u.Key.PlayerName)
|
|
||||||
? (_configService.Current.PreferNotesOverNamesForVisible ? u.Key.GetNote() : u.Key.PlayerName)
|
|
||||||
: (u.Key.GetNote() ?? u.Key.UserData.AliasOrUID));
|
|
||||||
bool FilterOnlineOrPausedSelf(KeyValuePair<Pair, List<GroupFullInfoDto>> u)
|
|
||||||
=> (u.Key.IsOnline || (!u.Key.IsOnline && !_configService.Current.ShowOfflineUsersSeparately)
|
|
||||||
|| u.Key.UserPair.OwnPermissions.IsPaused());
|
|
||||||
Dictionary<Pair, List<GroupFullInfoDto>> BasicSortedDictionary(IEnumerable<KeyValuePair<Pair, List<GroupFullInfoDto>>> u)
|
|
||||||
=> u.OrderByDescending(u => u.Key.IsVisible)
|
|
||||||
.ThenByDescending(u => u.Key.IsOnline)
|
|
||||||
.ThenBy(AlphabeticalSort, StringComparer.OrdinalIgnoreCase)
|
|
||||||
.ToDictionary(u => u.Key, u => u.Value);
|
|
||||||
ImmutableList<Pair> ImmutablePairList(IEnumerable<KeyValuePair<Pair, List<GroupFullInfoDto>>> u)
|
|
||||||
=> u.Select(k => k.Key).ToImmutableList();
|
|
||||||
bool FilterVisibleUsers(KeyValuePair<Pair, List<GroupFullInfoDto>> u)
|
|
||||||
=> u.Key.IsVisible
|
|
||||||
&& (_configService.Current.ShowSyncshellUsersInVisible || !(!_configService.Current.ShowSyncshellUsersInVisible && !u.Key.IsDirectlyPaired));
|
|
||||||
bool FilterTagUsers(KeyValuePair<Pair, List<GroupFullInfoDto>> u, string tag)
|
|
||||||
=> u.Key.IsDirectlyPaired && !u.Key.IsOneSidedPair && _tagHandler.HasPairTag(u.Key.UserData.UID, tag);
|
|
||||||
bool FilterGroupUsers(KeyValuePair<Pair, List<GroupFullInfoDto>> u, GroupFullInfoDto group)
|
|
||||||
=> u.Value.Exists(g => string.Equals(g.GID, group.GID, StringComparison.Ordinal));
|
|
||||||
bool FilterNotTaggedUsers(KeyValuePair<Pair, List<GroupFullInfoDto>> u)
|
|
||||||
=> u.Key.IsDirectlyPaired && !u.Key.IsOneSidedPair && !_tagHandler.HasAnyPairTag(u.Key.UserData.UID);
|
|
||||||
bool FilterNotTaggedSyncshells(GroupFullInfoDto group)
|
|
||||||
=> (!_tagHandler.HasAnySyncshellTag(group.GID) && !_configService.Current.ShowGroupedSyncshellsInAll) || true;
|
|
||||||
bool FilterOfflineUsers(KeyValuePair<Pair, List<GroupFullInfoDto>> u)
|
|
||||||
=> ((u.Key.IsDirectlyPaired && _configService.Current.ShowSyncshellOfflineUsersSeparately)
|
|
||||||
|| !_configService.Current.ShowSyncshellOfflineUsersSeparately)
|
|
||||||
&& (!u.Key.IsOneSidedPair || u.Value.Any()) && !u.Key.IsOnline && !u.Key.UserPair.OwnPermissions.IsPaused();
|
|
||||||
bool FilterOfflineSyncshellUsers(KeyValuePair<Pair, List<GroupFullInfoDto>> u)
|
|
||||||
=> (!u.Key.IsDirectlyPaired && !u.Key.IsOnline && !u.Key.UserPair.OwnPermissions.IsPaused());
|
|
||||||
|
|
||||||
|
var allPairs = _pairManager.PairsWithGroups.ToDictionary(k => k.Key, k => k.Value);
|
||||||
|
var filteredPairs = allPairs.Where(p => PassesFilter(p.Key, filter)).ToDictionary(k => k.Key, k => k.Value);
|
||||||
|
|
||||||
|
//Filter of online/visible pairs
|
||||||
if (_configService.Current.ShowVisibleUsersSeparately)
|
if (_configService.Current.ShowVisibleUsersSeparately)
|
||||||
{
|
{
|
||||||
var allVisiblePairs = ImmutablePairList(allPairs
|
var allVisiblePairs = ImmutablePairList(allPairs.Where(p => FilterVisibleUsers(p.Key)));
|
||||||
.Where(FilterVisibleUsers));
|
var filteredVisiblePairs = BasicSortedDictionary(filteredPairs.Where(p => FilterVisibleUsers(p.Key)));
|
||||||
var filteredVisiblePairs = BasicSortedDictionary(filteredPairs
|
|
||||||
.Where(FilterVisibleUsers));
|
|
||||||
|
|
||||||
drawFolders.Add(_drawEntityFactory.CreateDrawTagFolder(TagHandler.CustomVisibleTag, filteredVisiblePairs, allVisiblePairs));
|
drawFolders.Add(_drawEntityFactory.CreateDrawTagFolder(TagHandler.CustomVisibleTag, filteredVisiblePairs, allVisiblePairs));
|
||||||
}
|
}
|
||||||
|
|
||||||
List<IDrawFolder> groupFolders = new();
|
//Filter of not foldered syncshells
|
||||||
|
var groupFolders = new List<IDrawFolder>();
|
||||||
foreach (var group in _pairManager.GroupPairs.Select(g => g.Key).OrderBy(g => g.GroupAliasOrGID, StringComparer.OrdinalIgnoreCase))
|
foreach (var group in _pairManager.GroupPairs.Select(g => g.Key).OrderBy(g => g.GroupAliasOrGID, StringComparer.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
GetGroups(allPairs, filteredPairs, group, out ImmutableList<Pair> allGroupPairs, out Dictionary<Pair, List<GroupFullInfoDto>> filteredGroupPairs);
|
GetGroups(allPairs, filteredPairs, group, out ImmutableList<Pair> allGroupPairs, out Dictionary<Pair, List<GroupFullInfoDto>> filteredGroupPairs);
|
||||||
|
|
||||||
if (FilterNotTaggedSyncshells(group))
|
if (FilterNotTaggedSyncshells(group))
|
||||||
{
|
{
|
||||||
groupFolders.Add(_drawEntityFactory.CreateDrawGroupFolder(group, filteredGroupPairs, allGroupPairs));
|
groupFolders.Add(_drawEntityFactory.CreateDrawGroupFolder(group, filteredGroupPairs, allGroupPairs));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Filter of grouped up syncshells (All Syncshells Folder)
|
||||||
if (_configService.Current.GroupUpSyncshells)
|
if (_configService.Current.GroupUpSyncshells)
|
||||||
drawFolders.Add(new DrawGroupedGroupFolder(groupFolders, _tagHandler, _uiSharedService, _selectSyncshellForTagUi, _renameSyncshellTagUi, ""));
|
drawFolders.Add(new DrawGroupedGroupFolder(groupFolders, _tagHandler, _uiSharedService,
|
||||||
|
_selectSyncshellForTagUi, _renameSyncshellTagUi, ""));
|
||||||
else
|
else
|
||||||
drawFolders.AddRange(groupFolders);
|
drawFolders.AddRange(groupFolders);
|
||||||
|
|
||||||
var tags = _tagHandler.GetAllPairTagsSorted();
|
//Filter of grouped/foldered pairs
|
||||||
foreach (var tag in tags)
|
foreach (var tag in _tagHandler.GetAllPairTagsSorted())
|
||||||
{
|
{
|
||||||
var allTagPairs = ImmutablePairList(allPairs
|
var allTagPairs = ImmutablePairList(allPairs.Where(p => FilterTagUsers(p.Key, tag)));
|
||||||
.Where(u => FilterTagUsers(u, tag)));
|
var filteredTagPairs = BasicSortedDictionary(filteredPairs.Where(p => FilterTagUsers(p.Key, tag) && FilterOnlineOrPausedSelf(p.Key)));
|
||||||
var filteredTagPairs = BasicSortedDictionary(filteredPairs
|
|
||||||
.Where(u => FilterTagUsers(u, tag) && FilterOnlineOrPausedSelf(u)));
|
|
||||||
|
|
||||||
drawFolders.Add(_drawEntityFactory.CreateDrawTagFolder(tag, filteredTagPairs, allTagPairs));
|
drawFolders.Add(_drawEntityFactory.CreateDrawTagFolder(tag, filteredTagPairs, allTagPairs));
|
||||||
}
|
}
|
||||||
|
|
||||||
var syncshellTags = _tagHandler.GetAllSyncshellTagsSorted();
|
//Filter of grouped/foldered syncshells
|
||||||
foreach (var syncshelltag in syncshellTags)
|
foreach (var syncshellTag in _tagHandler.GetAllSyncshellTagsSorted())
|
||||||
{
|
{
|
||||||
List<IDrawFolder> syncshellFolderTags = [];
|
var syncshellFolderTags = new List<IDrawFolder>();
|
||||||
foreach (var group in _pairManager.GroupPairs.Select(g => g.Key).OrderBy(g => g.GroupAliasOrGID, StringComparer.OrdinalIgnoreCase))
|
foreach (var group in _pairManager.GroupPairs.Select(g => g.Key).OrderBy(g => g.GroupAliasOrGID, StringComparer.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
if (_tagHandler.HasSyncshellTag(group.GID, syncshelltag))
|
if (_tagHandler.HasSyncshellTag(group.GID, syncshellTag))
|
||||||
{
|
{
|
||||||
GetGroups(allPairs, filteredPairs, group, out ImmutableList<Pair> allGroupPairs, out Dictionary<Pair, List<GroupFullInfoDto>> filteredGroupPairs);
|
GetGroups(allPairs, filteredPairs, group,
|
||||||
|
out ImmutableList<Pair> allGroupPairs,
|
||||||
|
out Dictionary<Pair, List<GroupFullInfoDto>> filteredGroupPairs);
|
||||||
|
|
||||||
syncshellFolderTags.Add(_drawEntityFactory.CreateDrawGroupFolder($"tag_{group.GID}", group, filteredGroupPairs, allGroupPairs));
|
syncshellFolderTags.Add(_drawEntityFactory.CreateDrawGroupFolder($"tag_{group.GID}", group, filteredGroupPairs, allGroupPairs));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (syncshellFolderTags.Count > 0)
|
drawFolders.Add(new DrawGroupedGroupFolder(syncshellFolderTags, _tagHandler, _uiSharedService, _selectSyncshellForTagUi, _renameSyncshellTagUi, syncshellTag));
|
||||||
{
|
|
||||||
drawFolders.Add(new DrawGroupedGroupFolder(syncshellFolderTags, _tagHandler, _uiSharedService, _selectSyncshellForTagUi, _renameSyncshellTagUi, syncshelltag));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var allOnlineNotTaggedPairs = ImmutablePairList(allPairs
|
//Filter of not grouped/foldered and offline pairs
|
||||||
.Where(FilterNotTaggedUsers));
|
var allOnlineNotTaggedPairs = ImmutablePairList(allPairs.Where(p => FilterNotTaggedUsers(p.Key)));
|
||||||
var onlineNotTaggedPairs = BasicSortedDictionary(filteredPairs
|
var onlineNotTaggedPairs = BasicSortedDictionary(filteredPairs.Where(p => FilterNotTaggedUsers(p.Key) && FilterOnlineOrPausedSelf(p.Key)));
|
||||||
.Where(u => FilterNotTaggedUsers(u) && FilterOnlineOrPausedSelf(u)));
|
|
||||||
|
|
||||||
drawFolders.Add(_drawEntityFactory.CreateDrawTagFolder((_configService.Current.ShowOfflineUsersSeparately ? TagHandler.CustomOnlineTag : TagHandler.CustomAllTag),
|
drawFolders.Add(_drawEntityFactory.CreateDrawTagFolder((_configService.Current.ShowOfflineUsersSeparately ? TagHandler.CustomOnlineTag : TagHandler.CustomAllTag), onlineNotTaggedPairs, allOnlineNotTaggedPairs));
|
||||||
onlineNotTaggedPairs, allOnlineNotTaggedPairs));
|
|
||||||
|
|
||||||
if (_configService.Current.ShowOfflineUsersSeparately)
|
if (_configService.Current.ShowOfflineUsersSeparately)
|
||||||
{
|
{
|
||||||
var allOfflinePairs = ImmutablePairList(allPairs
|
var allOfflinePairs = ImmutablePairList(allPairs.Where(p => FilterOfflineUsers(p.Key, p.Value)));
|
||||||
.Where(FilterOfflineUsers));
|
var filteredOfflinePairs = BasicSortedDictionary(filteredPairs.Where(p => FilterOfflineUsers(p.Key, p.Value)));
|
||||||
var filteredOfflinePairs = BasicSortedDictionary(filteredPairs
|
|
||||||
.Where(FilterOfflineUsers));
|
|
||||||
|
|
||||||
drawFolders.Add(_drawEntityFactory.CreateDrawTagFolder(TagHandler.CustomOfflineTag, filteredOfflinePairs, allOfflinePairs));
|
drawFolders.Add(_drawEntityFactory.CreateDrawTagFolder(TagHandler.CustomOfflineTag, filteredOfflinePairs, allOfflinePairs));
|
||||||
|
|
||||||
if (_configService.Current.ShowSyncshellOfflineUsersSeparately)
|
if (_configService.Current.ShowSyncshellOfflineUsersSeparately)
|
||||||
{
|
{
|
||||||
var allOfflineSyncshellUsers = ImmutablePairList(allPairs
|
var allOfflineSyncshellUsers = ImmutablePairList(allPairs.Where(p => FilterOfflineSyncshellUsers(p.Key)));
|
||||||
.Where(FilterOfflineSyncshellUsers));
|
var filteredOfflineSyncshellUsers = BasicSortedDictionary(filteredPairs.Where(p => FilterOfflineSyncshellUsers(p.Key)));
|
||||||
var filteredOfflineSyncshellUsers = BasicSortedDictionary(filteredPairs
|
|
||||||
.Where(FilterOfflineSyncshellUsers));
|
|
||||||
|
|
||||||
drawFolders.Add(_drawEntityFactory.CreateDrawTagFolder(TagHandler.CustomOfflineSyncshellTag,
|
drawFolders.Add(_drawEntityFactory.CreateDrawTagFolder(TagHandler.CustomOfflineSyncshellTag, filteredOfflineSyncshellUsers, allOfflineSyncshellUsers));
|
||||||
filteredOfflineSyncshellUsers,
|
|
||||||
allOfflineSyncshellUsers));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Unpaired
|
||||||
drawFolders.Add(_drawEntityFactory.CreateDrawTagFolder(TagHandler.CustomUnpairedTag,
|
drawFolders.Add(_drawEntityFactory.CreateDrawTagFolder(TagHandler.CustomUnpairedTag,
|
||||||
BasicSortedDictionary(filteredPairs.Where(u => u.Key.IsOneSidedPair)),
|
BasicSortedDictionary(filteredPairs.Where(p => p.Key.IsOneSidedPair)),
|
||||||
ImmutablePairList(allPairs.Where(u => u.Key.IsOneSidedPair))));
|
ImmutablePairList(allPairs.Where(p => p.Key.IsOneSidedPair))));
|
||||||
|
|
||||||
return drawFolders;
|
return drawFolders;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void GetGroups(Dictionary<Pair, List<GroupFullInfoDto>> allPairs, Dictionary<Pair, List<GroupFullInfoDto>> filteredPairs, GroupFullInfoDto group, out ImmutableList<Pair> allGroupPairs, out Dictionary<Pair, List<GroupFullInfoDto>> filteredGroupPairs)
|
private static bool PassesFilter(Pair pair, string filter)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(filter)) return true;
|
||||||
|
|
||||||
|
return pair.UserData.AliasOrUID.Contains(filter, StringComparison.OrdinalIgnoreCase) || (pair.GetNote()?.Contains(filter, StringComparison.OrdinalIgnoreCase) ?? false) || (pair.PlayerName?.Contains(filter, StringComparison.OrdinalIgnoreCase) ?? false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private string AlphabeticalSortKey(Pair pair)
|
||||||
|
{
|
||||||
|
if (_configService.Current.ShowCharacterNameInsteadOfNotesForVisible && !string.IsNullOrEmpty(pair.PlayerName))
|
||||||
|
{
|
||||||
|
return _configService.Current.PreferNotesOverNamesForVisible ? (pair.GetNote() ?? string.Empty) : pair.PlayerName;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pair.GetNote() ?? pair.UserData.AliasOrUID;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool FilterOnlineOrPausedSelf(Pair pair) => pair.IsOnline || (!pair.IsOnline && !_configService.Current.ShowOfflineUsersSeparately) || pair.UserPair.OwnPermissions.IsPaused();
|
||||||
|
|
||||||
|
private bool FilterVisibleUsers(Pair pair) => pair.IsVisible && (_configService.Current.ShowSyncshellUsersInVisible || pair.IsDirectlyPaired);
|
||||||
|
|
||||||
|
private bool FilterTagUsers(Pair pair, string tag) => pair.IsDirectlyPaired && !pair.IsOneSidedPair && _tagHandler.HasPairTag(pair.UserData.UID, tag);
|
||||||
|
|
||||||
|
private static bool FilterGroupUsers(List<GroupFullInfoDto> groups, GroupFullInfoDto group) => groups.Exists(g => string.Equals(g.GID, group.GID, StringComparison.Ordinal));
|
||||||
|
|
||||||
|
private bool FilterNotTaggedUsers(Pair pair) => pair.IsDirectlyPaired && !pair.IsOneSidedPair && !_tagHandler.HasAnyPairTag(pair.UserData.UID);
|
||||||
|
|
||||||
|
private bool FilterNotTaggedSyncshells(GroupFullInfoDto group) => !_tagHandler.HasAnySyncshellTag(group.GID) || _configService.Current.ShowGroupedSyncshellsInAll;
|
||||||
|
|
||||||
|
private bool FilterOfflineUsers(Pair pair, List<GroupFullInfoDto> groups) => ((pair.IsDirectlyPaired && _configService.Current.ShowSyncshellOfflineUsersSeparately) || !_configService.Current.ShowSyncshellOfflineUsersSeparately) && (!pair.IsOneSidedPair || groups.Count != 0) && !pair.IsOnline && !pair.UserPair.OwnPermissions.IsPaused();
|
||||||
|
|
||||||
|
private static bool FilterOfflineSyncshellUsers(Pair pair) => !pair.IsDirectlyPaired && !pair.IsOnline && !pair.UserPair.OwnPermissions.IsPaused();
|
||||||
|
|
||||||
|
private Dictionary<Pair, List<GroupFullInfoDto>> BasicSortedDictionary(IEnumerable<KeyValuePair<Pair, List<GroupFullInfoDto>>> pairs) => pairs.OrderByDescending(u => u.Key.IsVisible).ThenByDescending(u => u.Key.IsOnline).ThenBy(u => AlphabeticalSortKey(u.Key), StringComparer.OrdinalIgnoreCase).ToDictionary(u => u.Key, u => u.Value);
|
||||||
|
|
||||||
|
private static ImmutableList<Pair> ImmutablePairList(IEnumerable<KeyValuePair<Pair, List<GroupFullInfoDto>>> pairs) => [.. pairs.Select(k => k.Key)];
|
||||||
|
|
||||||
|
private void GetGroups(Dictionary<Pair, List<GroupFullInfoDto>> allPairs,
|
||||||
|
Dictionary<Pair, List<GroupFullInfoDto>> filteredPairs,
|
||||||
|
GroupFullInfoDto group,
|
||||||
|
out ImmutableList<Pair> allGroupPairs,
|
||||||
|
out Dictionary<Pair, List<GroupFullInfoDto>> filteredGroupPairs)
|
||||||
{
|
{
|
||||||
allGroupPairs = ImmutablePairList(allPairs
|
allGroupPairs = ImmutablePairList(allPairs
|
||||||
.Where(u => FilterGroupUsers(u, group)));
|
.Where(u => FilterGroupUsers(u.Value, group)));
|
||||||
|
|
||||||
filteredGroupPairs = filteredPairs
|
filteredGroupPairs = filteredPairs
|
||||||
.Where(u => FilterGroupUsers(u, group) && FilterOnlineOrPausedSelf(u))
|
.Where(u => FilterGroupUsers( u.Value, group) && FilterOnlineOrPausedSelf(u.Key))
|
||||||
.OrderByDescending(u => u.Key.IsOnline)
|
.OrderByDescending(u => u.Key.IsOnline)
|
||||||
.ThenBy(u =>
|
.ThenBy(u =>
|
||||||
{
|
{
|
||||||
@@ -768,10 +768,9 @@ public class CompactUi : WindowMediatorSubscriberBase
|
|||||||
}
|
}
|
||||||
return u.Key.IsVisible ? 3 : 4;
|
return u.Key.IsVisible ? 3 : 4;
|
||||||
})
|
})
|
||||||
.ThenBy(AlphabeticalSort, StringComparer.OrdinalIgnoreCase)
|
.ThenBy(u => AlphabeticalSortKey(u.Key), StringComparer.OrdinalIgnoreCase)
|
||||||
.ToDictionary(k => k.Key, k => k.Value);
|
.ToDictionary(k => k.Key, k => k.Value);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private string GetServerError()
|
private string GetServerError()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -34,8 +34,6 @@ public class DrawGroupedGroupFolder : IDrawFolder
|
|||||||
|
|
||||||
public void Draw()
|
public void Draw()
|
||||||
{
|
{
|
||||||
if (!_groups.Any()) return;
|
|
||||||
|
|
||||||
string _id = "__folder_syncshells";
|
string _id = "__folder_syncshells";
|
||||||
if (_tag != "")
|
if (_tag != "")
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -4,14 +4,17 @@ using Dalamud.Interface.Colors;
|
|||||||
using Dalamud.Interface.ImGuiFileDialog;
|
using Dalamud.Interface.ImGuiFileDialog;
|
||||||
using Dalamud.Interface.Textures.TextureWraps;
|
using Dalamud.Interface.Textures.TextureWraps;
|
||||||
using Dalamud.Interface.Utility;
|
using Dalamud.Interface.Utility;
|
||||||
|
using Dalamud.Interface.Utility.Raii;
|
||||||
using LightlessSync.API.Data;
|
using LightlessSync.API.Data;
|
||||||
using LightlessSync.API.Dto.User;
|
using LightlessSync.API.Dto.User;
|
||||||
using LightlessSync.Services;
|
using LightlessSync.Services;
|
||||||
using LightlessSync.Services.Mediator;
|
using LightlessSync.Services.Mediator;
|
||||||
|
using LightlessSync.Utils;
|
||||||
using LightlessSync.WebAPI;
|
using LightlessSync.WebAPI;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using SixLabors.ImageSharp;
|
using SixLabors.ImageSharp;
|
||||||
using SixLabors.ImageSharp.PixelFormats;
|
using SixLabors.ImageSharp.PixelFormats;
|
||||||
|
using System.Numerics;
|
||||||
|
|
||||||
namespace LightlessSync.UI;
|
namespace LightlessSync.UI;
|
||||||
|
|
||||||
@@ -30,6 +33,15 @@ public class EditProfileUi : WindowMediatorSubscriberBase
|
|||||||
private bool _showFileDialogError = false;
|
private bool _showFileDialogError = false;
|
||||||
private bool _wasOpen;
|
private bool _wasOpen;
|
||||||
|
|
||||||
|
private bool vanityInitialized; // useless for now
|
||||||
|
private bool textEnabled;
|
||||||
|
private bool glowEnabled;
|
||||||
|
private Vector4 textColor;
|
||||||
|
private Vector4 glowColor;
|
||||||
|
|
||||||
|
private record VanityState(bool TextEnabled, bool GlowEnabled, Vector4 TextColor, Vector4 GlowColor);
|
||||||
|
private VanityState _savedVanity;
|
||||||
|
|
||||||
public EditProfileUi(ILogger<EditProfileUi> logger, LightlessMediator mediator,
|
public EditProfileUi(ILogger<EditProfileUi> logger, LightlessMediator mediator,
|
||||||
ApiController apiController, UiSharedService uiSharedService, FileDialogManager fileDialogManager,
|
ApiController apiController, UiSharedService uiSharedService, FileDialogManager fileDialogManager,
|
||||||
LightlessProfileManager lightlessProfileManager, PerformanceCollectorService performanceCollectorService)
|
LightlessProfileManager lightlessProfileManager, PerformanceCollectorService performanceCollectorService)
|
||||||
@@ -38,8 +50,8 @@ public class EditProfileUi : WindowMediatorSubscriberBase
|
|||||||
IsOpen = false;
|
IsOpen = false;
|
||||||
this.SizeConstraints = new()
|
this.SizeConstraints = new()
|
||||||
{
|
{
|
||||||
MinimumSize = new(768, 512),
|
MinimumSize = new(850, 640),
|
||||||
MaximumSize = new(768, 2000)
|
MaximumSize = new(850, 700)
|
||||||
};
|
};
|
||||||
_apiController = apiController;
|
_apiController = apiController;
|
||||||
_uiSharedService = uiSharedService;
|
_uiSharedService = uiSharedService;
|
||||||
@@ -57,14 +69,61 @@ public class EditProfileUi : WindowMediatorSubscriberBase
|
|||||||
_pfpTextureWrap = null;
|
_pfpTextureWrap = null;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
Mediator.Subscribe<ConnectedMessage>(this, msg =>
|
||||||
|
{
|
||||||
|
LoadVanity();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawNoteLine(string icon, Vector4 color, string text)
|
||||||
|
{
|
||||||
|
_uiSharedService.MediumText(icon, color);
|
||||||
|
ImGui.SameLine();
|
||||||
|
|
||||||
|
ImGui.SetCursorPosY(ImGui.GetCursorPosY() + 3);
|
||||||
|
ImGui.TextWrapped(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadVanity()
|
||||||
|
{
|
||||||
|
textEnabled = !string.IsNullOrEmpty(_apiController.TextColorHex);
|
||||||
|
glowEnabled = !string.IsNullOrEmpty(_apiController.TextGlowColorHex);
|
||||||
|
|
||||||
|
textColor = textEnabled ? UIColors.HexToRgba(_apiController.TextColorHex!) : Vector4.One;
|
||||||
|
glowColor = glowEnabled ? UIColors.HexToRgba(_apiController.TextGlowColorHex!) : Vector4.Zero;
|
||||||
|
|
||||||
|
_savedVanity = new VanityState(textEnabled, glowEnabled, textColor, glowColor);
|
||||||
|
vanityInitialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void DrawInternal()
|
protected override void DrawInternal()
|
||||||
{
|
{
|
||||||
_uiSharedService.BigText("Current Profile (as saved on server)");
|
_uiSharedService.UnderlinedBigText("Notes and Rules for Profiles", UIColors.Get("LightlessYellow"));
|
||||||
|
ImGui.Dummy(new Vector2(5));
|
||||||
|
|
||||||
|
ImGui.PushStyleVar(ImGuiStyleVar.ItemSpacing, new Vector2(2, 2));
|
||||||
|
|
||||||
|
DrawNoteLine("# ", UIColors.Get("LightlessBlue"), "All users that are paired and unpaused with you will be able to see your profile picture and description.");
|
||||||
|
DrawNoteLine("! ", UIColors.Get("LightlessYellow"), "Other users have the possibility to report your profile for breaking the rules.");
|
||||||
|
DrawNoteLine("!!! ", UIColors.Get("DimRed"), "AVOID: Anything as profile image that can be considered highly illegal or obscene (bestiality, anything that could be considered a sexual act with a minor (that includes Lalafells), etc.)");
|
||||||
|
DrawNoteLine("!!! ", UIColors.Get("DimRed"), "AVOID: Slurs of any kind in the description that can be considered highly offensive");
|
||||||
|
DrawNoteLine("! ", UIColors.Get("LightlessYellow"), "In case of valid reports from other users this can lead to disabling your profile forever or terminating your Lightless account indefinitely.");
|
||||||
|
DrawNoteLine("! ", UIColors.Get("LightlessYellow"), "Judgement of your profile validity from reports through staff is not up to debate and the decisions to disable your profile/account permanent.");
|
||||||
|
DrawNoteLine("! ", UIColors.Get("LightlessBlue"), "If your profile picture or profile description could be considered NSFW, enable the toggle in profile settings.");
|
||||||
|
|
||||||
|
ImGui.PopStyleVar();
|
||||||
|
|
||||||
|
ImGui.Dummy(new Vector2(3));
|
||||||
|
|
||||||
var profile = _lightlessProfileManager.GetLightlessProfile(new UserData(_apiController.UID));
|
var profile = _lightlessProfileManager.GetLightlessProfile(new UserData(_apiController.UID));
|
||||||
|
|
||||||
|
if (ImGui.BeginTabBar("##EditProfileTabs"))
|
||||||
|
{
|
||||||
|
if (ImGui.BeginTabItem("Current Profile"))
|
||||||
|
{
|
||||||
|
_uiSharedService.MediumText("Current Profile (as saved on server)", UIColors.Get("LightlessPurple"));
|
||||||
|
ImGui.Dummy(new Vector2(5));
|
||||||
|
|
||||||
if (profile.IsFlagged)
|
if (profile.IsFlagged)
|
||||||
{
|
{
|
||||||
UiSharedService.ColorTextWrapped(profile.Description, ImGuiColors.DalamudRed);
|
UiSharedService.ColorTextWrapped(profile.Description, ImGuiColors.DalamudRed);
|
||||||
@@ -119,18 +178,14 @@ public class EditProfileUi : WindowMediatorSubscriberBase
|
|||||||
ImGui.Checkbox("Is NSFW", ref nsfw);
|
ImGui.Checkbox("Is NSFW", ref nsfw);
|
||||||
ImGui.EndDisabled();
|
ImGui.EndDisabled();
|
||||||
|
|
||||||
ImGui.Separator();
|
_uiSharedService.ColoredSeparator(UIColors.Get("LightlessPurple"), 1.5f);
|
||||||
_uiSharedService.BigText("Notes and Rules for Profiles");
|
ImGui.EndTabItem();
|
||||||
|
}
|
||||||
|
|
||||||
ImGui.TextWrapped($"- All users that are paired and unpaused with you will be able to see your profile picture and description.{Environment.NewLine}" +
|
if (ImGui.BeginTabItem("Profile Settings"))
|
||||||
$"- Other users have the possibility to report your profile for breaking the rules.{Environment.NewLine}" +
|
{
|
||||||
$"- !!! AVOID: anything as profile image that can be considered highly illegal or obscene (bestiality, anything that could be considered a sexual act with a minor (that includes Lalafells), etc.){Environment.NewLine}" +
|
_uiSharedService.MediumText("Profile Settings", UIColors.Get("LightlessPurple"));
|
||||||
$"- !!! AVOID: slurs of any kind in the description that can be considered highly offensive{Environment.NewLine}" +
|
ImGui.Dummy(new Vector2(5));
|
||||||
$"- In case of valid reports from other users this can lead to disabling your profile forever or terminating your Lightless account indefinitely.{Environment.NewLine}" +
|
|
||||||
$"- Judgement of your profile validity from reports through staff is not up to debate and the decisions to disable your profile/account permanent.{Environment.NewLine}" +
|
|
||||||
$"- If your profile picture or profile description could be considered NSFW, enable the toggle below.");
|
|
||||||
ImGui.Separator();
|
|
||||||
_uiSharedService.BigText("Profile Settings");
|
|
||||||
|
|
||||||
if (_uiSharedService.IconTextButton(FontAwesomeIcon.FileUpload, "Upload new profile picture"))
|
if (_uiSharedService.IconTextButton(FontAwesomeIcon.FileUpload, "Upload new profile picture"))
|
||||||
{
|
{
|
||||||
@@ -223,6 +278,105 @@ public class EditProfileUi : WindowMediatorSubscriberBase
|
|||||||
_ = _apiController.UserSetProfile(new UserProfileDto(new UserData(_apiController.UID), Disabled: false, IsNSFW: null, ProfilePictureBase64: null, ""));
|
_ = _apiController.UserSetProfile(new UserProfileDto(new UserData(_apiController.UID), Disabled: false, IsNSFW: null, ProfilePictureBase64: null, ""));
|
||||||
}
|
}
|
||||||
UiSharedService.AttachToolTip("Clears your profile description text");
|
UiSharedService.AttachToolTip("Clears your profile description text");
|
||||||
|
|
||||||
|
ImGui.EndTabItem();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui.BeginTabItem("Vanity Settings"))
|
||||||
|
{
|
||||||
|
_uiSharedService.MediumText("Supporter Vanity Settings", UIColors.Get("LightlessPurple"));
|
||||||
|
ImGui.Dummy(new Vector2(4));
|
||||||
|
DrawNoteLine("# ", UIColors.Get("LightlessPurple"), "Must be a supporter through Patreon/Ko-fi to access these settings.");
|
||||||
|
|
||||||
|
var hasVanity = _apiController.HasVanity;
|
||||||
|
|
||||||
|
if (!hasVanity)
|
||||||
|
{
|
||||||
|
UiSharedService.ColorTextWrapped("You do not currently have vanity access. Become a supporter to unlock these features.", UIColors.Get("DimRed"));
|
||||||
|
ImGui.Dummy(new Vector2(8));
|
||||||
|
ImGui.BeginDisabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
_uiSharedService.ColoredSeparator(UIColors.Get("LightlessPurpleDefault"), 1.5f);
|
||||||
|
_uiSharedService.MediumText("Colored UID", UIColors.Get("LightlessPurple"));
|
||||||
|
ImGui.Dummy(new Vector2(5));
|
||||||
|
|
||||||
|
var font = UiBuilder.MonoFont;
|
||||||
|
var playerUID = _apiController.UID;
|
||||||
|
var playerDisplay = _apiController.DisplayName;
|
||||||
|
|
||||||
|
var previewTextColor = textEnabled ? textColor : Vector4.One;
|
||||||
|
var previewGlowColor = glowEnabled ? glowColor : Vector4.Zero;
|
||||||
|
|
||||||
|
var seString = SeStringUtils.BuildFormattedPlayerName(playerDisplay, previewTextColor, previewGlowColor);
|
||||||
|
|
||||||
|
using (ImRaii.PushFont(font))
|
||||||
|
{
|
||||||
|
var offsetX = 10f;
|
||||||
|
var pos = ImGui.GetCursorScreenPos() + new Vector2(offsetX, 0);
|
||||||
|
var size = ImGui.CalcTextSize(seString.TextValue);
|
||||||
|
|
||||||
|
var padding = new Vector2(6, 3);
|
||||||
|
var rectMin = pos - padding;
|
||||||
|
var rectMax = pos + size + padding;
|
||||||
|
|
||||||
|
var bgColor = new Vector4(0.15f, 0.15f, 0.15f, 1f);
|
||||||
|
var borderColor = UIColors.Get("LightlessPurple");
|
||||||
|
|
||||||
|
var drawList = ImGui.GetWindowDrawList();
|
||||||
|
drawList.AddRectFilled(rectMin, rectMax, ImGui.GetColorU32(bgColor), 6.0f);
|
||||||
|
drawList.AddRect(rectMin, rectMax, ImGui.GetColorU32(borderColor), 6.0f, ImDrawFlags.None, 1.5f);
|
||||||
|
|
||||||
|
SeStringUtils.RenderSeStringWithHitbox(seString, pos, font);
|
||||||
|
}
|
||||||
|
|
||||||
|
const float colorPickAlign = 90f;
|
||||||
|
|
||||||
|
DrawNoteLine("- ", UIColors.Get("LightlessPurple"), "Text Color");
|
||||||
|
ImGui.SameLine(colorPickAlign);
|
||||||
|
ImGui.Checkbox("##toggleTextColor", ref textEnabled);
|
||||||
|
ImGui.SameLine();
|
||||||
|
ImGui.BeginDisabled(!textEnabled);
|
||||||
|
ImGui.ColorEdit4($"##color_text", ref textColor, ImGuiColorEditFlags.NoInputs | ImGuiColorEditFlags.AlphaPreviewHalf);
|
||||||
|
ImGui.EndDisabled();
|
||||||
|
|
||||||
|
DrawNoteLine("- ", UIColors.Get("LightlessPurple"), "Glow Color");
|
||||||
|
ImGui.SameLine(colorPickAlign);
|
||||||
|
ImGui.Checkbox("##toggleGlowColor", ref glowEnabled);
|
||||||
|
ImGui.SameLine();
|
||||||
|
ImGui.BeginDisabled(!glowEnabled);
|
||||||
|
ImGui.ColorEdit4($"##color_glow", ref glowColor, ImGuiColorEditFlags.NoInputs | ImGuiColorEditFlags.AlphaPreviewHalf);
|
||||||
|
ImGui.EndDisabled();
|
||||||
|
|
||||||
|
bool changed = !Equals(_savedVanity, new VanityState(textEnabled, glowEnabled, textColor, glowColor));
|
||||||
|
|
||||||
|
if (!changed)
|
||||||
|
ImGui.BeginDisabled();
|
||||||
|
|
||||||
|
if (_uiSharedService.IconTextButton(FontAwesomeIcon.Save, "Save Changes"))
|
||||||
|
{
|
||||||
|
string? newText = textEnabled ? UIColors.RgbaToHex(textColor) : string.Empty;
|
||||||
|
string? newGlow = glowEnabled ? UIColors.RgbaToHex(glowColor) : string.Empty;
|
||||||
|
|
||||||
|
_ = _apiController.UserUpdateVanityColors(new UserVanityColorsDto(newText, newGlow));
|
||||||
|
|
||||||
|
_savedVanity = new VanityState(textEnabled, glowEnabled, textColor, glowColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!changed)
|
||||||
|
ImGui.EndDisabled();
|
||||||
|
|
||||||
|
ImGui.Dummy(new Vector2(5));
|
||||||
|
_uiSharedService.ColoredSeparator(UIColors.Get("LightlessPurple"), 1.5f);
|
||||||
|
|
||||||
|
if (!hasVanity)
|
||||||
|
ImGui.EndDisabled();
|
||||||
|
|
||||||
|
ImGui.EndTabItem();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.EndTabBar();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Dispose(bool disposing)
|
protected override void Dispose(bool disposing)
|
||||||
|
|||||||
@@ -98,20 +98,21 @@ public class IdDisplayHandler
|
|||||||
|
|
||||||
var font = UiBuilder.MonoFont;
|
var font = UiBuilder.MonoFont;
|
||||||
|
|
||||||
var isAdmin = pair.UserData.IsAdmin;
|
Vector4? textColor = null;
|
||||||
var isModerator = pair.UserData.IsModerator;
|
Vector4? glowColor = null;
|
||||||
|
|
||||||
Vector4? textColor = isAdmin
|
if (pair.UserData.HasVanity)
|
||||||
? UIColors.Get("LightlessAdminText")
|
{
|
||||||
: isModerator
|
if (!string.IsNullOrWhiteSpace(pair.UserData.TextColorHex))
|
||||||
? UIColors.Get("LightlessModeratorText")
|
{
|
||||||
: null;
|
textColor = UIColors.HexToRgba(pair.UserData.TextColorHex);
|
||||||
|
}
|
||||||
|
|
||||||
Vector4? glowColor = isAdmin
|
if (!string.IsNullOrWhiteSpace(pair.UserData.TextGlowColorHex))
|
||||||
? UIColors.Get("LightlessAdminGlow")
|
{
|
||||||
: isModerator
|
glowColor = UIColors.HexToRgba(pair.UserData.TextGlowColorHex);
|
||||||
? UIColors.Get("LightlessModeratorGlow")
|
}
|
||||||
: null;
|
}
|
||||||
|
|
||||||
var seString = (textColor != null || glowColor != null)
|
var seString = (textColor != null || glowColor != null)
|
||||||
? SeStringUtils.BuildFormattedPlayerName(playerText, textColor, glowColor)
|
? SeStringUtils.BuildFormattedPlayerName(playerText, textColor, glowColor)
|
||||||
|
|||||||
@@ -167,7 +167,7 @@ public partial class IntroUi : WindowMediatorSubscriberBase
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UiSharedService.TextWrapped("To not unnecessary download files already present on your computer, Lightless Sync will have to scan your Penumbra mod directory. " +
|
UiSharedService.TextWrapped("To not unnecessarily download files already present on your computer, Lightless Sync will have to scan your Penumbra mod directory. " +
|
||||||
"Additionally, a local storage folder must be set where Lightless Sync will download other character files to. " +
|
"Additionally, a local storage folder must be set where Lightless Sync will download other character files to. " +
|
||||||
"Once the storage folder is set and the scan complete, this page will automatically forward to registration at a service.");
|
"Once the storage folder is set and the scan complete, this page will automatically forward to registration at a service.");
|
||||||
UiSharedService.TextWrapped("Note: The initial scan, depending on the amount of mods you have, might take a while. Please wait until it is completed.");
|
UiSharedService.TextWrapped("Note: The initial scan, depending on the amount of mods you have, might take a while. Please wait until it is completed.");
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ internal class JoinSyncshellUI : WindowMediatorSubscriberBase
|
|||||||
"Joining a Syncshell will pair you implicitly with all existing users in the Syncshell." + Environment.NewLine +
|
"Joining a Syncshell will pair you implicitly with all existing users in the Syncshell." + Environment.NewLine +
|
||||||
"All permissions to all users in the Syncshell will be set to the preferred Syncshell permissions on joining, excluding prior set preferred permissions.");
|
"All permissions to all users in the Syncshell will be set to the preferred Syncshell permissions on joining, excluding prior set preferred permissions.");
|
||||||
ImGui.Separator();
|
ImGui.Separator();
|
||||||
ImGui.TextUnformatted("Note: Syncshell ID and Password are case sensitive. MSS- is part of Syncshell IDs, unless using Vanity IDs.");
|
ImGui.TextUnformatted("Note: Syncshell ID and Password are case sensitive. LLS- is part of Syncshell IDs, unless using Vanity IDs.");
|
||||||
|
|
||||||
ImGui.AlignTextToFramePadding();
|
ImGui.AlignTextToFramePadding();
|
||||||
ImGui.TextUnformatted("Syncshell ID");
|
ImGui.TextUnformatted("Syncshell ID");
|
||||||
|
|||||||
@@ -1152,12 +1152,12 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
|||||||
}
|
}
|
||||||
_uiShared.DrawHelpText("This will group up all Syncshells in a special 'All Syncshells' folder in the main UI.");
|
_uiShared.DrawHelpText("This will group up all Syncshells in a special 'All Syncshells' folder in the main UI.");
|
||||||
|
|
||||||
//if (ImGui.Checkbox("Show grouped syncshells in main screen/all syncshells", ref groupedSyncshells))
|
if (ImGui.Checkbox("Show grouped syncshells in main screen/all syncshells", ref groupedSyncshells))
|
||||||
//{
|
{
|
||||||
// _configService.Current.ShowGroupedSyncshellsInAll = groupedSyncshells;
|
_configService.Current.ShowGroupedSyncshellsInAll = groupedSyncshells;
|
||||||
// _configService.Save();
|
_configService.Save();
|
||||||
// Mediator.Publish(new RefreshUiMessage());
|
Mediator.Publish(new RefreshUiMessage());
|
||||||
//}
|
}
|
||||||
_uiShared.DrawHelpText("This will show grouped syncshells in main screen or group 'All Syncshells'.");
|
_uiShared.DrawHelpText("This will show grouped syncshells in main screen or group 'All Syncshells'.");
|
||||||
|
|
||||||
if (ImGui.Checkbox("Show player name for visible players", ref showNameInsteadOfNotes))
|
if (ImGui.Checkbox("Show player name for visible players", ref showNameInsteadOfNotes))
|
||||||
|
|||||||
@@ -336,7 +336,7 @@ public class SyncshellAdminUI : WindowMediatorSubscriberBase
|
|||||||
}
|
}
|
||||||
ImGui.Separator();
|
ImGui.Separator();
|
||||||
|
|
||||||
if (_uiSharedService.MediumTreeNode("Mass Cleanup", UIColors.Get("LightlessPurple")))
|
if (_uiSharedService.MediumTreeNode("Mass Cleanup", UIColors.Get("DimRed")))
|
||||||
{
|
{
|
||||||
using (ImRaii.Disabled(!UiSharedService.CtrlPressed()))
|
using (ImRaii.Disabled(!UiSharedService.CtrlPressed()))
|
||||||
{
|
{
|
||||||
@@ -348,6 +348,18 @@ public class SyncshellAdminUI : WindowMediatorSubscriberBase
|
|||||||
UiSharedService.AttachToolTip("This will remove all non-pinned, non-moderator users from the Syncshell."
|
UiSharedService.AttachToolTip("This will remove all non-pinned, non-moderator users from the Syncshell."
|
||||||
+ UiSharedService.TooltipSeparator + "Hold CTRL to enable this button");
|
+ UiSharedService.TooltipSeparator + "Hold CTRL to enable this button");
|
||||||
|
|
||||||
|
ImGui.SameLine();
|
||||||
|
|
||||||
|
using (ImRaii.Disabled(!UiSharedService.CtrlPressed()))
|
||||||
|
{
|
||||||
|
if (_uiSharedService.IconTextButton(FontAwesomeIcon.Brush, "Clear Lightfinder Users"))
|
||||||
|
{
|
||||||
|
_ = _apiController.GroupClearFinder(new(GroupFullInfo.Group));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UiSharedService.AttachToolTip("This will remove all users that joined through Lightfinder from the Syncshell."
|
||||||
|
+ UiSharedService.TooltipSeparator + "Hold CTRL to enable this button");
|
||||||
|
|
||||||
ImGuiHelpers.ScaledDummy(2f);
|
ImGuiHelpers.ScaledDummy(2f);
|
||||||
ImGui.Separator();
|
ImGui.Separator();
|
||||||
ImGuiHelpers.ScaledDummy(2f);
|
ImGuiHelpers.ScaledDummy(2f);
|
||||||
@@ -410,12 +422,12 @@ public class SyncshellAdminUI : WindowMediatorSubscriberBase
|
|||||||
UiSharedService.TextWrapped($"Syncshell was pruned and {_pruneTask.Result} inactive user(s) have been removed.");
|
UiSharedService.TextWrapped($"Syncshell was pruned and {_pruneTask.Result} inactive user(s) have been removed.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_uiSharedService.ColoredSeparator(UIColors.Get("LightlessPurple"), 1.5f);
|
_uiSharedService.ColoredSeparator(UIColors.Get("DimRed"), 1.5f);
|
||||||
ImGui.TreePop();
|
ImGui.TreePop();
|
||||||
}
|
}
|
||||||
ImGui.Separator();
|
ImGui.Separator();
|
||||||
|
|
||||||
if (_uiSharedService.MediumTreeNode("User Bans", UIColors.Get("LightlessPurple")))
|
if (_uiSharedService.MediumTreeNode("User Bans", UIColors.Get("LightlessYellow")))
|
||||||
{
|
{
|
||||||
if (_uiSharedService.IconTextButton(FontAwesomeIcon.Retweet, "Refresh Banlist from Server"))
|
if (_uiSharedService.IconTextButton(FontAwesomeIcon.Retweet, "Refresh Banlist from Server"))
|
||||||
{
|
{
|
||||||
@@ -456,7 +468,7 @@ public class SyncshellAdminUI : WindowMediatorSubscriberBase
|
|||||||
}
|
}
|
||||||
ImGui.EndTable();
|
ImGui.EndTable();
|
||||||
}
|
}
|
||||||
_uiSharedService.ColoredSeparator(UIColors.Get("LightlessPurple"), 1.5f);
|
_uiSharedService.ColoredSeparator(UIColors.Get("LightlessYellow"), 1.5f);
|
||||||
ImGui.TreePop();
|
ImGui.TreePop();
|
||||||
}
|
}
|
||||||
ImGui.Separator();
|
ImGui.Separator();
|
||||||
|
|||||||
@@ -4,15 +4,15 @@ using Dalamud.Interface.Colors;
|
|||||||
using Dalamud.Interface.Utility;
|
using Dalamud.Interface.Utility;
|
||||||
using Dalamud.Interface.Utility.Raii;
|
using Dalamud.Interface.Utility.Raii;
|
||||||
using LightlessSync.API.Data.Enum;
|
using LightlessSync.API.Data.Enum;
|
||||||
|
using LightlessSync.API.Data.Extensions;
|
||||||
using LightlessSync.API.Dto;
|
using LightlessSync.API.Dto;
|
||||||
using LightlessSync.API.Dto.Group;
|
using LightlessSync.API.Dto.Group;
|
||||||
using LightlessSync.LightlessConfiguration;
|
using LightlessSync.PlayerData.Pairs;
|
||||||
using LightlessSync.Services;
|
using LightlessSync.Services;
|
||||||
using LightlessSync.Services.Mediator;
|
using LightlessSync.Services.Mediator;
|
||||||
using LightlessSync.Utils;
|
using LightlessSync.Utils;
|
||||||
using LightlessSync.WebAPI;
|
using LightlessSync.WebAPI;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using LightlessSync.API.Data.Extensions;
|
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
|
|
||||||
namespace LightlessSync.UI;
|
namespace LightlessSync.UI;
|
||||||
@@ -20,12 +20,13 @@ namespace LightlessSync.UI;
|
|||||||
public class SyncshellFinderUI : WindowMediatorSubscriberBase
|
public class SyncshellFinderUI : WindowMediatorSubscriberBase
|
||||||
{
|
{
|
||||||
private readonly ApiController _apiController;
|
private readonly ApiController _apiController;
|
||||||
private readonly LightlessConfigService _configService;
|
|
||||||
private readonly BroadcastService _broadcastService;
|
private readonly BroadcastService _broadcastService;
|
||||||
private readonly UiSharedService _uiSharedService;
|
private readonly UiSharedService _uiSharedService;
|
||||||
private readonly BroadcastScannerService _broadcastScannerService;
|
private readonly BroadcastScannerService _broadcastScannerService;
|
||||||
|
private readonly PairManager _pairManager;
|
||||||
|
|
||||||
private readonly List<GroupJoinDto> _nearbySyncshells = new();
|
private readonly List<GroupJoinDto> _nearbySyncshells = [];
|
||||||
|
private List<GroupFullInfoDto> _currentSyncshells = [];
|
||||||
private int _selectedNearbyIndex = -1;
|
private int _selectedNearbyIndex = -1;
|
||||||
|
|
||||||
private GroupJoinDto? _joinDto;
|
private GroupJoinDto? _joinDto;
|
||||||
@@ -37,17 +38,16 @@ public class SyncshellFinderUI : WindowMediatorSubscriberBase
|
|||||||
LightlessMediator mediator,
|
LightlessMediator mediator,
|
||||||
PerformanceCollectorService performanceCollectorService,
|
PerformanceCollectorService performanceCollectorService,
|
||||||
BroadcastService broadcastService,
|
BroadcastService broadcastService,
|
||||||
LightlessConfigService configService,
|
|
||||||
UiSharedService uiShared,
|
UiSharedService uiShared,
|
||||||
ApiController apiController,
|
ApiController apiController,
|
||||||
BroadcastScannerService broadcastScannerService
|
BroadcastScannerService broadcastScannerService,
|
||||||
) : base(logger, mediator, "Shellfinder###LightlessSyncshellFinderUI", performanceCollectorService)
|
PairManager pairManager) : base(logger, mediator, "Shellfinder###LightlessSyncshellFinderUI", performanceCollectorService)
|
||||||
{
|
{
|
||||||
_broadcastService = broadcastService;
|
_broadcastService = broadcastService;
|
||||||
_uiSharedService = uiShared;
|
_uiSharedService = uiShared;
|
||||||
_configService = configService;
|
|
||||||
_apiController = apiController;
|
_apiController = apiController;
|
||||||
_broadcastScannerService = broadcastScannerService;
|
_broadcastScannerService = broadcastScannerService;
|
||||||
|
_pairManager = pairManager;
|
||||||
|
|
||||||
IsOpen = false;
|
IsOpen = false;
|
||||||
SizeConstraints = new()
|
SizeConstraints = new()
|
||||||
@@ -56,14 +56,14 @@ public class SyncshellFinderUI : WindowMediatorSubscriberBase
|
|||||||
MaximumSize = new(600, 550)
|
MaximumSize = new(600, 550)
|
||||||
};
|
};
|
||||||
|
|
||||||
Mediator.Subscribe<SyncshellBroadcastsUpdatedMessage>(this, async _ => await RefreshSyncshellsAsync());
|
Mediator.Subscribe<SyncshellBroadcastsUpdatedMessage>(this, async _ => await RefreshSyncshellsAsync().ConfigureAwait(false));
|
||||||
Mediator.Subscribe<BroadcastStatusChangedMessage>(this, async _ => await RefreshSyncshellsAsync());
|
Mediator.Subscribe<BroadcastStatusChangedMessage>(this, async _ => await RefreshSyncshellsAsync().ConfigureAwait(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async void OnOpen()
|
public override async void OnOpen()
|
||||||
{
|
{
|
||||||
_ownPermissions = _apiController.DefaultPermissions.DeepClone()!;
|
_ownPermissions = _apiController.DefaultPermissions.DeepClone()!;
|
||||||
await RefreshSyncshellsAsync();
|
await RefreshSyncshellsAsync().ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void DrawInternal()
|
protected override void DrawInternal()
|
||||||
@@ -107,10 +107,8 @@ public class SyncshellFinderUI : WindowMediatorSubscriberBase
|
|||||||
ImGui.TableSetupColumn("Join", ImGuiTableColumnFlags.WidthFixed, 80f * ImGuiHelpers.GlobalScale);
|
ImGui.TableSetupColumn("Join", ImGuiTableColumnFlags.WidthFixed, 80f * ImGuiHelpers.GlobalScale);
|
||||||
ImGui.TableHeadersRow();
|
ImGui.TableHeadersRow();
|
||||||
|
|
||||||
for (int i = 0; i < _nearbySyncshells.Count; i++)
|
foreach (var shell in _nearbySyncshells)
|
||||||
{
|
{
|
||||||
var shell = _nearbySyncshells[i];
|
|
||||||
|
|
||||||
ImGui.TableNextRow();
|
ImGui.TableNextRow();
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
ImGui.TextUnformatted(shell.Group.Alias ?? "(No Alias)");
|
ImGui.TextUnformatted(shell.Group.Alias ?? "(No Alias)");
|
||||||
@@ -123,6 +121,10 @@ public class SyncshellFinderUI : WindowMediatorSubscriberBase
|
|||||||
ImGui.PushStyleColor(ImGuiCol.ButtonHovered, UIColors.Get("LightlessGreen").WithAlpha(0.85f));
|
ImGui.PushStyleColor(ImGuiCol.ButtonHovered, UIColors.Get("LightlessGreen").WithAlpha(0.85f));
|
||||||
ImGui.PushStyleColor(ImGuiCol.ButtonActive, UIColors.Get("LightlessGreen").WithAlpha(0.75f));
|
ImGui.PushStyleColor(ImGuiCol.ButtonActive, UIColors.Get("LightlessGreen").WithAlpha(0.75f));
|
||||||
|
|
||||||
|
if (!_currentSyncshells.Exists(g => string.Equals(g.GID, shell.GID, StringComparison.Ordinal)))
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
if (ImGui.Button(label))
|
if (ImGui.Button(label))
|
||||||
{
|
{
|
||||||
_logger.LogInformation($"Join requested for Syncshell {shell.Group.GID} ({shell.Group.Alias})");
|
_logger.LogInformation($"Join requested for Syncshell {shell.Group.GID} ({shell.Group.Alias})");
|
||||||
@@ -156,8 +158,16 @@ public class SyncshellFinderUI : WindowMediatorSubscriberBase
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
using (ImRaii.Disabled())
|
||||||
|
{
|
||||||
|
ImGui.Button(label);
|
||||||
|
}
|
||||||
|
UiSharedService.AttachToolTip("Already a member or owner of this Syncshell.");
|
||||||
|
}
|
||||||
ImGui.PopStyleColor(3);
|
ImGui.PopStyleColor(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,6 +179,8 @@ public class SyncshellFinderUI : WindowMediatorSubscriberBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void DrawConfirmation()
|
private void DrawConfirmation()
|
||||||
|
{
|
||||||
|
if (_joinDto != null && _joinInfo != null)
|
||||||
{
|
{
|
||||||
ImGui.Separator();
|
ImGui.Separator();
|
||||||
ImGui.TextUnformatted($"Join Syncshell: {_joinDto.Group.AliasOrGID} by {_joinInfo.OwnerAliasOrUID}");
|
ImGui.TextUnformatted($"Join Syncshell: {_joinDto.Group.AliasOrGID} by {_joinInfo.OwnerAliasOrUID}");
|
||||||
@@ -194,6 +206,7 @@ public class SyncshellFinderUI : WindowMediatorSubscriberBase
|
|||||||
_joinInfo = null;
|
_joinInfo = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void DrawPermissionRow(string label, bool suggested, bool current, Action<bool> apply)
|
private void DrawPermissionRow(string label, bool suggested, bool current, Action<bool> apply)
|
||||||
{
|
{
|
||||||
@@ -224,6 +237,7 @@ public class SyncshellFinderUI : WindowMediatorSubscriberBase
|
|||||||
private async Task RefreshSyncshellsAsync()
|
private async Task RefreshSyncshellsAsync()
|
||||||
{
|
{
|
||||||
var syncshellBroadcasts = _broadcastScannerService.GetActiveSyncshellBroadcasts();
|
var syncshellBroadcasts = _broadcastScannerService.GetActiveSyncshellBroadcasts();
|
||||||
|
_currentSyncshells = _pairManager.GroupPairs.Select(g => g.Key).ToList();
|
||||||
|
|
||||||
if (syncshellBroadcasts.Count == 0)
|
if (syncshellBroadcasts.Count == 0)
|
||||||
{
|
{
|
||||||
@@ -231,11 +245,11 @@ public class SyncshellFinderUI : WindowMediatorSubscriberBase
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<GroupJoinDto> updatedList;
|
List<GroupJoinDto> updatedList = [];
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var groups = await _apiController.GetBroadcastedGroups(syncshellBroadcasts);
|
var groups = await _apiController.GetBroadcastedGroups(syncshellBroadcasts).ConfigureAwait(false);
|
||||||
updatedList = groups?.ToList() ?? new();
|
updatedList = groups?.ToList();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -243,8 +257,8 @@ public class SyncshellFinderUI : WindowMediatorSubscriberBase
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var currentGids = _nearbySyncshells.Select(s => s.Group.GID).ToHashSet();
|
var currentGids = _nearbySyncshells.Select(s => s.Group.GID).ToHashSet(StringComparer.Ordinal);
|
||||||
var newGids = updatedList.Select(s => s.Group.GID).ToHashSet();
|
var newGids = updatedList.Select(s => s.Group.GID).ToHashSet(StringComparer.Ordinal);
|
||||||
|
|
||||||
if (currentGids.SetEquals(newGids))
|
if (currentGids.SetEquals(newGids))
|
||||||
return;
|
return;
|
||||||
@@ -256,7 +270,7 @@ public class SyncshellFinderUI : WindowMediatorSubscriberBase
|
|||||||
|
|
||||||
if (previousGid != null)
|
if (previousGid != null)
|
||||||
{
|
{
|
||||||
var newIndex = _nearbySyncshells.FindIndex(s => s.Group.GID == previousGid);
|
var newIndex = _nearbySyncshells.FindIndex(s => string.Equals(s.Group.GID, previousGid, StringComparison.Ordinal));
|
||||||
if (newIndex >= 0)
|
if (newIndex >= 0)
|
||||||
{
|
{
|
||||||
_selectedNearbyIndex = newIndex;
|
_selectedNearbyIndex = newIndex;
|
||||||
@@ -290,9 +304,4 @@ public class SyncshellFinderUI : WindowMediatorSubscriberBase
|
|||||||
|
|
||||||
return _nearbySyncshells[_selectedNearbyIndex].Group.GID;
|
return _nearbySyncshells[_selectedNearbyIndex].Group.GID;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Dispose(bool disposing)
|
|
||||||
{
|
|
||||||
base.Dispose(disposing);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -134,6 +134,12 @@ public partial class ApiController
|
|||||||
await _lightlessHub!.InvokeAsync(nameof(UserSetProfile), userDescription).ConfigureAwait(false);
|
await _lightlessHub!.InvokeAsync(nameof(UserSetProfile), userDescription).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task UserUpdateVanityColors(UserVanityColorsDto dto)
|
||||||
|
{
|
||||||
|
if (!IsConnected) return;
|
||||||
|
await _lightlessHub!.InvokeAsync(nameof(UserUpdateVanityColors), dto).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
public async Task UserUpdateDefaultPermissions(DefaultPermissionsDto defaultPermissionsDto)
|
public async Task UserUpdateDefaultPermissions(DefaultPermissionsDto defaultPermissionsDto)
|
||||||
{
|
{
|
||||||
CheckConnection();
|
CheckConnection();
|
||||||
|
|||||||
@@ -277,6 +277,12 @@ public partial class ApiController
|
|||||||
_lightlessHub!.On(nameof(Client_GroupSendInfo), act);
|
_lightlessHub!.On(nameof(Client_GroupSendInfo), act);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void OnGroupUpdateProfile(Action<GroupProfileDto> act)
|
||||||
|
{
|
||||||
|
if (_initialized) return;
|
||||||
|
_lightlessHub!.On(nameof(Client_GroupSendProfile), act);
|
||||||
|
}
|
||||||
|
|
||||||
public void OnReceiveServerMessage(Action<MessageSeverity, string> act)
|
public void OnReceiveServerMessage(Action<MessageSeverity, string> act)
|
||||||
{
|
{
|
||||||
if (_initialized) return;
|
if (_initialized) return;
|
||||||
|
|||||||
@@ -45,6 +45,11 @@ public partial class ApiController
|
|||||||
CheckConnection();
|
CheckConnection();
|
||||||
await _lightlessHub!.SendAsync(nameof(GroupClear), group).ConfigureAwait(false);
|
await _lightlessHub!.SendAsync(nameof(GroupClear), group).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
public async Task GroupClearFinder(GroupDto group)
|
||||||
|
{
|
||||||
|
CheckConnection();
|
||||||
|
await _lightlessHub!.SendAsync(nameof(GroupClearFinder), group).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<GroupJoinDto> GroupCreate()
|
public async Task<GroupJoinDto> GroupCreate()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
using LightlessSync.API.Data;
|
using LightlessSync.API.Data;
|
||||||
using LightlessSync.API.Data.Extensions;
|
using LightlessSync.API.Data.Extensions;
|
||||||
using LightlessSync.API.Dto;
|
using LightlessSync.API.Dto;
|
||||||
|
using LightlessSync.API.Dto.Group;
|
||||||
using LightlessSync.API.Dto.User;
|
using LightlessSync.API.Dto.User;
|
||||||
using LightlessSync.API.SignalR;
|
using LightlessSync.API.SignalR;
|
||||||
using LightlessSync.LightlessConfiguration;
|
using LightlessSync.LightlessConfiguration;
|
||||||
@@ -76,6 +77,10 @@ public sealed partial class ApiController : DisposableMediatorSubscriberBase, IL
|
|||||||
public DefaultPermissionsDto? DefaultPermissions => _connectionDto?.DefaultPreferredPermissions ?? null;
|
public DefaultPermissionsDto? DefaultPermissions => _connectionDto?.DefaultPreferredPermissions ?? null;
|
||||||
public string DisplayName => _connectionDto?.User.AliasOrUID ?? string.Empty;
|
public string DisplayName => _connectionDto?.User.AliasOrUID ?? string.Empty;
|
||||||
|
|
||||||
|
public bool HasVanity => _connectionDto?.HasVanity ?? false;
|
||||||
|
public string TextColorHex => _connectionDto?.TextColorHex ?? string.Empty;
|
||||||
|
public string TextGlowColorHex => _connectionDto?.TextGlowColorHex ?? string.Empty;
|
||||||
|
|
||||||
public bool IsConnected => ServerState == ServerState.Connected;
|
public bool IsConnected => ServerState == ServerState.Connected;
|
||||||
|
|
||||||
public bool IsCurrentVersion => (Assembly.GetExecutingAssembly().GetName().Version ?? new Version(0, 0, 0, 0)) >= (_connectionDto?.CurrentClientVersion ?? new Version(0, 0, 0, 0));
|
public bool IsCurrentVersion => (Assembly.GetExecutingAssembly().GetName().Version ?? new Version(0, 0, 0, 0)) >= (_connectionDto?.CurrentClientVersion ?? new Version(0, 0, 0, 0));
|
||||||
@@ -444,6 +449,7 @@ public sealed partial class ApiController : DisposableMediatorSubscriberBase, IL
|
|||||||
OnGroupPairLeft((dto) => _ = Client_GroupPairLeft(dto));
|
OnGroupPairLeft((dto) => _ = Client_GroupPairLeft(dto));
|
||||||
OnGroupSendFullInfo((dto) => _ = Client_GroupSendFullInfo(dto));
|
OnGroupSendFullInfo((dto) => _ = Client_GroupSendFullInfo(dto));
|
||||||
OnGroupSendInfo((dto) => _ = Client_GroupSendInfo(dto));
|
OnGroupSendInfo((dto) => _ = Client_GroupSendInfo(dto));
|
||||||
|
OnGroupUpdateProfile((dto) => _ = Client_GroupSendProfile(dto));
|
||||||
OnGroupChangeUserPairPermissions((dto) => _ = Client_GroupChangeUserPairPermissions(dto));
|
OnGroupChangeUserPairPermissions((dto) => _ = Client_GroupChangeUserPairPermissions(dto));
|
||||||
|
|
||||||
OnGposeLobbyJoin((dto) => _ = Client_GposeLobbyJoin(dto));
|
OnGposeLobbyJoin((dto) => _ = Client_GposeLobbyJoin(dto));
|
||||||
@@ -596,5 +602,20 @@ public sealed partial class ApiController : DisposableMediatorSubscriberBase, IL
|
|||||||
|
|
||||||
ServerState = state;
|
ServerState = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Task Client_GroupSendProfile(GroupProfileDto groupInfo)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<GroupProfileDto> GroupGetProfile(GroupDto dto)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task GroupSetProfile(GroupProfileDto dto)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#pragma warning restore MA0040
|
#pragma warning restore MA0040
|
||||||
Reference in New Issue
Block a user