From 15b19188629fb5101a27bb7ea9c9edf47a31ae9d Mon Sep 17 00:00:00 2001 From: GID Date: Mon, 19 Jan 2026 14:06:55 +0700 Subject: [PATCH 01/16] Redesign ProfileOverlay with navigation and sections Refactors ProfileOverlay to use a NavigationView for sectioned navigation (Overview, Activities, Mutual Friends, Mutual Servers). Adds new layouts for each section, improves responsive design, and implements navigation logic and item click handlers in the code-behind. Also adds a Copy User ID action and updates the UI for a more following windows 11 ui design --- Unicord.Universal/Dialogs/ProfileOverlay.xaml | 497 ++++++++++++++---- .../Dialogs/ProfileOverlay.xaml.cs | 162 +++++- 2 files changed, 552 insertions(+), 107 deletions(-) diff --git a/Unicord.Universal/Dialogs/ProfileOverlay.xaml b/Unicord.Universal/Dialogs/ProfileOverlay.xaml index 2232aedc..b17cdeed 100644 --- a/Unicord.Universal/Dialogs/ProfileOverlay.xaml +++ b/Unicord.Universal/Dialogs/ProfileOverlay.xaml @@ -9,122 +9,407 @@ xmlns:toolkit="using:Microsoft.Toolkit.Uwp.UI.Controls" xmlns:media="using:Microsoft.UI.Xaml.Media" xmlns:lib="using:Microsoft.UI.Xaml.Controls" - xmlns:users="using:Unicord.Universal.Controls.Users" xmlns:guild="using:Unicord.Universal.Models.Guild" - x:DefaultBindMode="OneWay" mc:Ignorable="d" MaxWidth="550"> - - - Segoe UI Variable Display - Medium - + xmlns:users="using:Unicord.Universal.Controls.Users" + xmlns:guild="using:Unicord.Universal.Models.Guild" + xmlns:user="using:Unicord.Universal.Models.User" + x:DefaultBindMode="OneWay" + mc:Ignorable="d" + MaxWidth="645" + Height="600"> - - - - - - - - - - - - - + BorderThickness="1" + CornerRadius="{ThemeResource ProfileOverlay_Dialog_CornerRadius}"> + + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Unicord.Universal/Dialogs/ProfileOverlay.xaml.cs b/Unicord.Universal/Dialogs/ProfileOverlay.xaml.cs index 47ff7d93..c21e9d1b 100644 --- a/Unicord.Universal/Dialogs/ProfileOverlay.xaml.cs +++ b/Unicord.Universal/Dialogs/ProfileOverlay.xaml.cs @@ -1,14 +1,22 @@ -using Unicord.Universal.Models.User; +using System.Linq; +using DSharpPlus.Entities; +using Unicord.Universal.Extensions; +using Unicord.Universal.Models.User; using Unicord.Universal.Services; +using Windows.ApplicationModel.DataTransfer; using Windows.System; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Input; +using Lib = Microsoft.UI.Xaml.Controls; namespace Unicord.Universal.Dialogs { public sealed partial class ProfileOverlay : UserControl { + private const double CompactThresholdWidth = 640; + private string _pendingNavigationTag; + public UserViewModel User { get => (UserViewModel)GetValue(UserProperty); @@ -22,11 +30,107 @@ private static void OnUserChanged(DependencyObject d, DependencyPropertyChangedE { var overlay = (ProfileOverlay)d; overlay.Bindings.Update(); + + overlay.ApplyPendingNavigationOrDefault(); } public ProfileOverlay() { InitializeComponent(); + + SizeChanged += (_, __) => UpdatePaneMode(); + + Loaded += (s, e) => + { + ApplyPendingNavigationOrDefault(); + + UpdatePaneMode(); + }; + } + + public void NavigateToSection(string tag) + { + _pendingNavigationTag = tag; + ApplyPendingNavigationOrDefault(); + } + + private void ApplyPendingNavigationOrDefault() + { + if (NavView == null) + return; + + var tag = _pendingNavigationTag; + + Lib.NavigationViewItem targetItem = tag switch + { + "mutualfriends" => MutualFriendsItem, + "mutual" => MutualServersItem, + "activities" => ActivitiesItem, + _ => null + }; + + // If we have a pending navigation target, apply it + if (targetItem != null) + { + _pendingNavigationTag = null; + NavView.SelectedItem = targetItem; + } + // Only apply default Overview if nothing is selected yet + else if (NavView.SelectedItem == null && _pendingNavigationTag == null) + { + NavView.SelectedItem = OverviewItem; + } + } + + private void UpdatePaneMode() + { + if (NavView == null) + return; + + var isCompact = ActualWidth > 0 && ActualWidth < CompactThresholdWidth; + + var desiredMode = isCompact + ? Lib.NavigationViewPaneDisplayMode.LeftCompact + : Lib.NavigationViewPaneDisplayMode.Left; + + if (NavView.PaneDisplayMode != desiredMode) + NavView.PaneDisplayMode = desiredMode; + + var desiredIsPaneOpen = !isCompact; + if (NavView.IsPaneOpen != desiredIsPaneOpen) + NavView.IsPaneOpen = desiredIsPaneOpen; + + NavView.InvalidateMeasure(); + NavView.UpdateLayout(); + } + + private void NavView_SelectionChanged(Lib.NavigationView sender, Lib.NavigationViewSelectionChangedEventArgs args) + { + if (args.SelectedItemContainer?.Tag is not string tag) + return; + + // Hide all content + OverviewContent.Visibility = Visibility.Collapsed; + ActivitiesContent.Visibility = Visibility.Collapsed; + MutualFriendsContent.Visibility = Visibility.Collapsed; + MutualServersContent.Visibility = Visibility.Collapsed; + + // Show selected content + switch (tag) + { + case "overview": + OverviewContent.Visibility = Visibility.Visible; + break; + case "activities": + ActivitiesContent.Visibility = Visibility.Visible; + break; + case "mutualfriends": + MutualFriendsContent.Visibility = Visibility.Visible; + break; + case "mutual": + MutualServersContent.Visibility = Visibility.Visible; + break; + } } private void DropShadowPanel_PreviewKeyUp(object sender, KeyRoutedEventArgs e) @@ -37,5 +141,61 @@ private void DropShadowPanel_PreviewKeyUp(object sender, KeyRoutedEventArgs e) .CloseOverlay(); } } + + private async void MutualServersList_ItemClick(object sender, ItemClickEventArgs e) + { + if (e.ClickedItem is Unicord.Universal.Models.Guild.GuildViewModel guild) + { + OverlayService.GetForCurrentView().CloseOverlay(); + + if (App.LocalSettings.Read(Constants.ENABLE_GUILD_BROWSING, Constants.ENABLE_GUILD_BROWSING_DEFAULT)) + { + // Navigate to guild browsing view + var discordPage = Window.Current.Content.FindChild(); + if (discordPage != null) + { + discordPage.LeftSidebarFrame.Navigate(typeof(Pages.Subpages.GuildChannelListPage), guild.Guild); + } + } + else + { + // Navigate to previously selected channel or first accessible text channel + var channelId = App.RoamingSettings.Read($"GuildPreviousChannels::{guild.Guild.Id}", 0UL); + if (!guild.Guild.Channels.TryGetValue(channelId, out var channel) || (!channel.IsAccessible() || !channel.IsText())) + { + channel = guild.Guild.Channels.Values + .Where(c => c.IsAccessible()) + .Where(c => c.IsText()) + .OrderBy(c => c.Position) + .FirstOrDefault(); + } + + if (channel != null) + { + await DiscordNavigationService.GetForCurrentView() + .NavigateAsync(channel); + } + } + } + } + + private async void MutualFriendsList_ItemClick(object sender, ItemClickEventArgs e) + { + if (e.ClickedItem is Unicord.Universal.Models.User.UserViewModel friendUser) + { + await OverlayService.GetForCurrentView() + .ReplaceOverlayWithAnimationAsync(friendUser); + } + } + + private void CopyUserId_Click(object sender, RoutedEventArgs e) + { + if (User == null) + return; + + var dataPackage = new DataPackage(); + dataPackage.SetText(User.Id.ToString()); + Clipboard.SetContent(dataPackage); + } } } From a4a33ed8deffcd5dbddc35c41afb91e8dc4d6783 Mon Sep 17 00:00:00 2001 From: GID Date: Mon, 19 Jan 2026 14:17:28 +0700 Subject: [PATCH 02/16] Redesign and enhance UserFlyout UI Revamps the UserFlyout with windows 11 design, improved role and mutual info display, and a new message composer with emoji picker. Adds support for viewing/copying user ID, mutual friends/servers overlays, and dynamic role expansion. --- .../Controls/Flyouts/UserFlyout.xaml | 338 ++++++++++++--- .../Controls/Flyouts/UserFlyout.xaml.cs | 406 +++++++++++++++++- 2 files changed, 686 insertions(+), 58 deletions(-) diff --git a/Unicord.Universal/Controls/Flyouts/UserFlyout.xaml b/Unicord.Universal/Controls/Flyouts/UserFlyout.xaml index 710f88a1..c554dcd6 100644 --- a/Unicord.Universal/Controls/Flyouts/UserFlyout.xaml +++ b/Unicord.Universal/Controls/Flyouts/UserFlyout.xaml @@ -11,60 +11,288 @@ xmlns:user="using:Unicord.Universal.Controls.Users" mc:Ignorable="d"> - - - - - - - - - - - - - - - - - - - - @# - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +