mirror of
https://github.com/J3vb/OwnCord.git
synced 2026-09-03 03:50:00 +03:00
Client UI: - Design system: Colors, Typography, Controls resource dictionaries - Message actions: reply compose bar, hover edit/delete/reply buttons - Rich content: code blocks, attachments, system messages, content parser - Server strip: 72px sidebar with server icons, home button, add server - Status picker: popup for changing online/idle/dnd/invisible status - ConnectPage: server health check dots with auto-refresh - User popup: profile card with banner, avatar, roles, member since - Emoji picker: 6 categories, search, grid of Unicode emojis - Settings overlay: full-screen with sidebar navigation - Friends/DM view: sidebar + friends list with tabs (online/all/pending) - Toast notifications: auto-dismiss after 3s with fade animation Models & services: - Attachment model added to Message, ApiMessage, ChatMessagePayload - EditMessageAsync, DeleteMessageAsync, SendStatusChangeAsync APIs - MessageContentParser (code blocks, inline code, bold, italic) - EmojiData, ToastService, HealthStatusToBrushConverter Server (from prior session): - Voice room management, SFU, speaker detection - ACME/TLS support, config improvements - Protocol and schema updates Tests: 331 passing (61 converter + 24 voice service + 34 voice VM + 41 parser + 9 edit/delete + existing)
86 lines
2.5 KiB
C#
86 lines
2.5 KiB
C#
using System.Windows;
|
|
using System.Windows.Controls;
|
|
using System.Windows.Media.Animation;
|
|
using System.Windows.Threading;
|
|
|
|
namespace OwnCord.Client.Controls;
|
|
|
|
public partial class ToastControl : UserControl
|
|
{
|
|
private DispatcherTimer? _autoDismissTimer;
|
|
|
|
public static readonly DependencyProperty MessageProperty =
|
|
DependencyProperty.Register(
|
|
nameof(Message),
|
|
typeof(string),
|
|
typeof(ToastControl),
|
|
new PropertyMetadata(string.Empty));
|
|
|
|
public static readonly DependencyProperty IsOpenProperty =
|
|
DependencyProperty.Register(
|
|
nameof(IsOpen),
|
|
typeof(bool),
|
|
typeof(ToastControl),
|
|
new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnIsOpenChanged));
|
|
|
|
public ToastControl()
|
|
{
|
|
InitializeComponent();
|
|
}
|
|
|
|
public string Message
|
|
{
|
|
get => (string)GetValue(MessageProperty);
|
|
set => SetValue(MessageProperty, value);
|
|
}
|
|
|
|
public bool IsOpen
|
|
{
|
|
get => (bool)GetValue(IsOpenProperty);
|
|
set => SetValue(IsOpenProperty, value);
|
|
}
|
|
|
|
private static void OnIsOpenChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
|
{
|
|
if (d is ToastControl control)
|
|
control.HandleIsOpenChanged((bool)e.NewValue);
|
|
}
|
|
|
|
private void HandleIsOpenChanged(bool isOpen)
|
|
{
|
|
_autoDismissTimer?.Stop();
|
|
_autoDismissTimer = null;
|
|
|
|
if (isOpen)
|
|
{
|
|
// Fade in
|
|
var fadeIn = new DoubleAnimation(0, 1, TimeSpan.FromMilliseconds(200))
|
|
{
|
|
EasingFunction = new QuadraticEase { EasingMode = EasingMode.EaseOut }
|
|
};
|
|
BeginAnimation(OpacityProperty, fadeIn);
|
|
|
|
// Auto-dismiss after 3 seconds
|
|
_autoDismissTimer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(3) };
|
|
_autoDismissTimer.Tick += OnAutoDismiss;
|
|
_autoDismissTimer.Start();
|
|
}
|
|
else
|
|
{
|
|
// Fade out
|
|
var fadeOut = new DoubleAnimation(1, 0, TimeSpan.FromMilliseconds(300))
|
|
{
|
|
EasingFunction = new QuadraticEase { EasingMode = EasingMode.EaseIn }
|
|
};
|
|
BeginAnimation(OpacityProperty, fadeOut);
|
|
}
|
|
}
|
|
|
|
private void OnAutoDismiss(object? sender, EventArgs e)
|
|
{
|
|
_autoDismissTimer?.Stop();
|
|
_autoDismissTimer = null;
|
|
IsOpen = false;
|
|
}
|
|
}
|