1094 lines
42 KiB
C#

using Krypton.Toolkit;
using qtcnet_client.Controls;
using qtcnet_client.Factories;
using qtcnet_client.Forms;
using qtcnet_client.Forms.Games;
using qtcnet_client.Model;
using qtcnet_client.Services;
using QtCNETAPI.Dtos.User;
using QtCNETAPI.Events;
using QtCNETAPI.Models;
using QtCNETAPI.Services;
using QtCNETAPI.Services.ApiService;
using QtCNETAPI.Services.GatewayService;
using System.Drawing.Drawing2D;
using System.Threading.Tasks;
namespace qtcnet_client
{
public partial class MainForm : Form
{
private BrandingControl? BrandingControl;
private LoginControl? LoginControl;
private RegisterControl? RegisterControl;
private CurrentProfileControl? CurrentProfileControl;
private MainTabControl? MainTabControl;
private readonly List<ChatRoomForm> OpenChatRoomForms = [];
private readonly List<ProfileForm> OpenProfileForms = [];
private readonly List<Contact> UserContactsList = [];
private Size LoggedOutSize = new(615, 702);
private Size LoggedInSize = new(419, 715);
private readonly IApiService _apiService;
private readonly IGatewayService _gatewayService;
private readonly LoggingService _loggingService;
private readonly CredentialService _credentialService;
private readonly ClientConfig _config;
private readonly ImageFactory _imgFactory;
private readonly UpdateService _updateService;
private readonly AudioService _audioService;
private bool IsAdmin = false;
public MainForm(IApiService apiService,
IGatewayService gatewayService,
LoggingService loggingService,
CredentialService credentialService,
ClientConfig config,
ImageFactory imageFactory,
UpdateService updateService,
AudioService audioService)
{
_apiService = apiService;
_gatewayService = gatewayService;
_loggingService = loggingService;
_credentialService = credentialService;
_config = config;
_imgFactory = imageFactory;
_updateService = updateService;
_audioService = audioService;
// sub to currentuser updates
_apiService.OnCurrentUserUpdate += _apiService_OnCurrentUserUpdate;
InitializeComponent();
}
private void MainForm_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
Rectangle _formRect = ClientRectangle;
if (_formRect.IsEmpty)
_formRect = e.ClipRectangle;
// draw gradient background
using LinearGradientBrush b = new(_formRect, Color.White, Color.DodgerBlue, LinearGradientMode.Vertical);
g.FillRectangle(b, _formRect);
}
private void MainForm_Resize(object sender, EventArgs e)
{
if (WindowState == FormWindowState.Minimized && _config.MinimizeToTray)
Hide();
Invalidate();
}
private async void MainForm_Load(object sender, EventArgs e)
{
// first check for updates
await _updateService.CheckForUpdatesAsync();
SuspendLayout();
Size = LoggedOutSize;
// add branding control
BrandingControl = new()
{
Location = new(-2, -17),
Anchor = AnchorStyles.Top | AnchorStyles.Left
};
// add login control
LoginControl = new()
{
Location = new(12, 233)
};
LoginControl.OnSuccessfulLogin += LoginControl_OnSuccessfulLogin;
LoginControl.OnRegisterPressed += LoginControl_OnRegisterPressed;
Controls.Add(BrandingControl);
Controls.Add(LoginControl);
ResumeLayout(true);
// ensure api is reachable before letting the user login
LoginControl.ToggleControls(false);
var _pingRes = await Task.Run(PingAPI);
if (_pingRes)
{
// check for existing login in credential service
var _token = _credentialService.GetAccessToken();
if (_token != null)
{
// try it
await LoginAsync();
}
else
LoginControl.ToggleControls(true);
}
else
{
KryptonMessageBox.Show("The Server Is Unreachable. Ensure Your Config Is Correct. The Client Will Now Close", "Oops");
Application.Exit();
}
}
private void LoginControl_OnRegisterPressed(object? sender, EventArgs e)
{
if (sender is LoginControl _)
{
// pause ui
SuspendLayout();
// remove and dispose login control
Controls.Remove(LoginControl);
LoginControl?.Dispose();
LoginControl = null;
// create register control
RegisterControl = new()
{
Location = new(1, 233)
};
RegisterControl.OnReshowLoginPressed += RegisterControl_OnReshowLoginPressed;
RegisterControl.OnRegister += RegisterControl_OnRegister;
Controls.Add(RegisterControl);
ResumeLayout(true);
}
}
private void RegisterControl_OnReshowLoginPressed(object? sender, EventArgs e)
{
if (sender is RegisterControl _)
{
// pause ui
SuspendLayout();
// remove and dispose register control
Controls.Remove(RegisterControl);
RegisterControl?.Dispose();
RegisterControl = null;
// add login control
LoginControl = new()
{
Location = new(12, 233)
};
LoginControl.OnSuccessfulLogin += LoginControl_OnSuccessfulLogin;
LoginControl.OnRegisterPressed += LoginControl_OnRegisterPressed;
Controls.Add(LoginControl);
ResumeLayout(true);
}
}
private async void RegisterControl_OnRegister(object? sender, EventArgs e)
{
if (sender is RegisterControl _senderCtrl)
{
// attempt registration
var res = await _apiService.RegisterAsync(new()
{
Username = _senderCtrl.Username,
Email = _senderCtrl.Email,
Password = _senderCtrl.Password,
DateOfBirth = _senderCtrl.DateOfBirth,
});
if (res.Success && res.Data != null)
{
KryptonMessageBox.Show("Registration Success!\n\nNote: Some Servers Require Email Verification, Check Your Email!\n\nYou May Now Login.", "Success!");
// pause ui
SuspendLayout();
// remove and dispose register control
Controls.Remove(RegisterControl);
RegisterControl?.Dispose();
RegisterControl = null;
// add login control
LoginControl = new()
{
Location = new(12, 233)
};
LoginControl.OnSuccessfulLogin += LoginControl_OnSuccessfulLogin;
LoginControl.OnRegisterPressed += LoginControl_OnRegisterPressed;
Controls.Add(LoginControl);
ResumeLayout(true);
}
else
{
KryptonMessageBox.Show($"Sorry, Something Went Wrong Registering You. Please Try Again Later.\n\nServer Response = {res.Message}", "Uh Oh.",
KryptonMessageBoxButtons.OK,
KryptonMessageBoxIcon.Error);
_senderCtrl.ToggleControls(true);
}
}
}
private async void LoginControl_OnSuccessfulLogin(object? sender, EventArgs e)
{
if (sender is LoginControl _senderCtrl)
{
// login using info
await LoginAsync(new() { Email = _senderCtrl.Email, Password = _senderCtrl.Password, RememberMe = _senderCtrl.RememberMe });
}
}
private async void MainTabControl_OnRoomControlDoubleClicked(object? sender, EventArgs e)
{
if (sender is RoomControl _roomCtrl)
{
if (OpenChatRoomForms.Count > 0)
{
KryptonMessageBox.Show("Joining Multiple Rooms Is Currently Unsupported.", ":(");
return;
}
// open the room form
ChatRoomForm _chatRoom = new(_gatewayService, _apiService, _imgFactory)
{
RoomId = _roomCtrl.RoomId,
RoomName = _roomCtrl.RoomName,
};
OpenChatRoomForms.Add(_chatRoom);
_chatRoom.OnSend += Chat_OnSend;
_chatRoom.OnClose += Chat_OnClose;
_chatRoom.Show();
if (_roomCtrl.RoomId == "LOBBY")
await _gatewayService.JoinRoomAsync();
else
{
// join the user to the room
await _gatewayService.JoinRoomAsync(new() // TODO - refactor this server side (its so bad)
{
Id = _roomCtrl.RoomId,
Name = _roomCtrl.Name,
});
}
}
}
private async void Chat_OnSend(object? sender, EventArgs e)
{
if (sender is ChatRoomForm _chatRoom)
{
// send the message
await _gatewayService.PostMessageAsync(new()
{
Content = _chatRoom.SentMessage
});
}
}
private async void Chat_OnClose(object? sender, EventArgs e)
{
if (sender is ChatRoomForm chatRoom)
{
// leave whatever room the user is in
await _gatewayService.LeaveRoomAsync();
OpenChatRoomForms.Remove(chatRoom);
chatRoom.Dispose();
}
}
private async void MainTabControl_OnContactControlDoubleClicked(object? sender, EventArgs e)
{
if (sender is ContactControl _contactCtrl)
{
var _user = await _apiService.GetUserInformationAsync(_contactCtrl.UserId);
if (_user.Success && _user.Data != null)
{
// create a profile form
ProfileForm _profile = new(_apiService, _imgFactory)
{
UserId = _user.Data.Id,
Username = _user.Data.Username,
Bio = _user.Data.Bio,
Status = _user.Data.Status,
};
// check if user is in contacts list (if profile isn't self)
var _contact = UserContactsList.FirstOrDefault(e => e.OwnerId == _user.Data.Id || e.UserId == _user.Data.Id);
if (_contact != null)
{
// set contact status
if (_contact.UserId == _apiService.CurrentUser?.Id)
_profile.ContactStatus = _contact.UserStatus;
else
_profile.ContactStatus = _contact.OwnerStatus;
}
else
_profile.ContactStatus = Contact.ContactStatus.NoRelation;
// get profile image
_profile.ProfileImage = _imgFactory.GetAndCreateProfileImage(_user.Data.Id, _user.Data.Status, _user.Data.ProfileCosmeticId);
_profile.OnClose += ProfileForm_OnClose;
OpenProfileForms.Add(_profile);
_profile.Show();
}
}
}
private async void MainTabControl_OnUserItemDoubleClicked(object? sender, EventArgs e)
{
if (sender is MainTabControl _mtCtrl)
{
if (_mtCtrl.SelectedUser != null)
{
// get the user to open the profile for
if (_mtCtrl.SelectedUser.Tag is string _tagString)
{
var _user = await _apiService.GetUserInformationAsync(_tagString);
if (_user.Success && _user.Data != null)
{
// create a profile form
ProfileForm _profile = new(_apiService, _imgFactory)
{
UserId = _user.Data.Id,
Username = _user.Data.Username,
Bio = _user.Data.Bio,
Status = _user.Data.Status,
};
// check if user is in contacts list (if profile isn't self)
var _contact = UserContactsList.FirstOrDefault(e => e.OwnerId == _user.Data.Id || e.UserId == _user.Data.Id);
if (_contact != null)
{
// set contact status
if (_contact.OwnerId == _apiService.CurrentUser?.Id)
_profile.ContactStatus = _contact.UserStatus;
else
_profile.ContactStatus = _contact.OwnerStatus;
}
else
_profile.ContactStatus = Contact.ContactStatus.NoRelation;
// get profile image
_profile.ProfileImage = _imgFactory.GetAndCreateProfileImage(_user.Data.Id, _user.Data.Status, _user.Data.ProfileCosmeticId);
_profile.OnClose += ProfileForm_OnClose;
OpenProfileForms.Add(_profile);
_profile.Show();
}
}
}
}
}
private void ProfileForm_OnClose(object? sender, EventArgs e)
{
if (sender is ProfileForm profile)
{
OpenProfileForms.Remove(profile);
profile.Dispose();
}
}
private async void _apiService_OnCurrentUserUpdate(object? sender, EventArgs e)
{
// set everything in the current user profile
CurrentProfileControl?.Username = _apiService.CurrentUser?.Username ?? "Username";
CurrentProfileControl?.CurrencyCount = _apiService.CurrentUser?.CurrencyAmount ?? 0;
CurrentProfileControl?.ProfileImage = _imgFactory.GetAndCreateProfileImage(_apiService.CurrentUser!.Id, _apiService.CurrentUser!.Status, _apiService.CurrentUser!.ActiveProfileCosmetic);
CurrentProfileControl?.RefreshInfo();
}
private async void _gatewayService_OnUserForceLogout(object? sender, EventArgs e)
{
KryptonMessageBox.Show("The Server Has Logged You Out. Please Try Signing In Again.", "Uh Oh.",
KryptonMessageBoxButtons.OK, KryptonMessageBoxIcon.Error);
LogoutAsync();
}
private void _gatewayService_OnServerConfigReceived(object? sender, EventArgs e)
{
if (e is ServerConfigEventArgs _args)
{
if (InvokeRequired)
Invoke(() => Text = $"{Text} - Connected To {_args.ServerConfig.Name}");
else Text = $"{Text} - Connected To {_args.ServerConfig.Name}";
}
}
private async void _gatewayService_OnRefreshContactsListReceived(object? sender, EventArgs e)
{
// get and set contacts
var _currentUserContacts = await _apiService.GetCurrentUserContacts();
if (_currentUserContacts.Success && _currentUserContacts.Data != null)
{
UserContactsList.Clear();
UserContactsList.AddRange([.. _currentUserContacts.Data.DistinctBy(c => c.Id)]);
await SetupContactsUI(_currentUserContacts.Data);
}
else
{
// if no contacts are found, just clear the lists
UserContactsList.Clear();
await SetupContactsUI([]);
}
}
private async void _gatewayService_OnRefreshRoomListReceived(object? sender, EventArgs e)
{
// get and set rooms
var _roomList = await _apiService.GetAllRoomsAsync();
if (_roomList.Success && _roomList.Data != null)
await SetupRoomsUI(_roomList.Data);
}
private async void _gatewayService_OnRefreshUserListReceived(object? sender, EventArgs e)
{
// get and set user directory
var _currentUserDirectory = await _apiService.GetAllUsersAsync();
if (_currentUserDirectory.Success && _currentUserDirectory.Data != null)
await SetupDirectoryUI(_currentUserDirectory.Data);
}
private async void _gatewayService_OnServerDisconnect(object? sender, EventArgs e)
{
if (e is ServerConnectionClosedEventArgs _args)
{
if (_args.Error != null)
{
Reconnect: // probably not the best idea to use labels but whatever
var _dialogRes = KryptonMessageBox.Show($"Connection To The Server Lost. Would You Like To Try Again?\n\nError - {_args.Error?.Message}", "Uh Oh.",
KryptonMessageBoxButtons.YesNo, KryptonMessageBoxIcon.Error);
if (_dialogRes == DialogResult.Yes)
{
// completely restart connection
await _gatewayService.StopAsync();
await _gatewayService.StartAsync();
if (_gatewayService.HubConnection?.State == Microsoft.AspNetCore.SignalR.Client.HubConnectionState.Connected)
_gatewayService_OnServerReconnected(sender, e);
else
goto Reconnect;
}
}
}
}
private void _gatewayService_OnServerReconnected(object? sender, EventArgs e)
{
// reenable interactive controls
if (InvokeRequired)
{
Invoke(() =>
{
CurrentProfileControl?.Enabled = true;
MainTabControl?.Enabled = true;
});
}
else
{
CurrentProfileControl?.Enabled = true;
MainTabControl?.Enabled = true;
}
}
private void _gatewayService_OnServerReconnecting(object? sender, EventArgs e)
{
// disable interactive controls
if(InvokeRequired)
{
Invoke(() =>
{
CurrentProfileControl?.Enabled = false;
MainTabControl?.Enabled = false;
});
}
else
{
CurrentProfileControl?.Enabled = false;
MainTabControl?.Enabled = false;
}
}
private void _gatewayService_OnDirectMessageReceived(object? sender, EventArgs e)
{
throw new NotImplementedException();
}
private async Task<bool> PingAPI()
{
// ping it
var res = await _apiService.PingServerAsync();
// return result
return res.Success;
}
private async Task LoginAsync(UserLoginDto? dto = null)
{
if (dto != null)
{
// attempt login using dto
var res = await _apiService.LoginAsync(dto);
if (res.Success && res.Data != null && _apiService.CurrentUser != null) // "CurrentUser" should not be null on successful login but checking anyways
{
// store refresh token in credential store
_credentialService.SaveAccessToken(_apiService.CurrentUser.Username, res.Message);
}
else
{
KryptonMessageBox.Show(res.Message, "Login Error", KryptonMessageBoxButtons.OK, KryptonMessageBoxIcon.Error);
LoginControl?.ToggleControls(true);
}
}
else
{
// use refresh token
var _token = _credentialService.GetAccessToken();
if (_token != null)
{
var _res = await _apiService.RefreshLogin(_token);
if (!_res.Success)
LoginControl?.ToggleControls(true);
}
}
if (_apiService.CurrentUser != null)
{
// pause ui
SuspendLayout();
// remove and dispose login and branding controls
Controls.Remove(LoginControl);
Controls.Remove(BrandingControl);
LoginControl?.Dispose();
LoginControl = null;
BrandingControl?.Dispose();
BrandingControl = null;
// set size to logged in size
Size = LoggedInSize;
// subscribe to gateway events
_gatewayService.OnServerReconnecting += _gatewayService_OnServerReconnecting;
_gatewayService.OnServerReconnected += _gatewayService_OnServerReconnected;
_gatewayService.OnServerDisconnect += _gatewayService_OnServerDisconnect;
//_gatewayService.OnDirectMessageReceived += _gatewayService_OnDirectMessageReceived;
_gatewayService.OnRoomMessageReceived += _gatewayService_OnRoomMessageReceived;
_gatewayService.OnRoomUserListReceived += _gatewayService_OnRoomUserListReceived;
_gatewayService.OnRefreshUserListsReceived += _gatewayService_OnRefreshUserListReceived;
_gatewayService.OnRefreshRoomListReceived += _gatewayService_OnRefreshRoomListReceived;
_gatewayService.OnRefreshContactsListReceived += _gatewayService_OnRefreshContactsListReceived;
_gatewayService.OnServerConfigReceived += _gatewayService_OnServerConfigReceived;
_gatewayService.OnUserForceLogout += _gatewayService_OnUserForceLogout;
// start connection
await _gatewayService.StartAsync();
var _res = _gatewayService.HubConnection != null && _gatewayService.HubConnection.State == Microsoft.AspNetCore.SignalR.Client.HubConnectionState.Connected;
if (_res)
{
// setup current profile control based on current user
CurrentProfileControl = new()
{
Username = _apiService.CurrentUser.Username,
CurrencyCount = _apiService.CurrentUser.CurrencyAmount,
Location = new(12, 12),
};
CurrentProfileControl.OnEditProfileClicked += CurrentProfileControl_OnEditProfileClicked;
CurrentProfileControl.OnSignOutClicked += CurrentProfileControl_OnSignOutClicked;
CurrentProfileControl.OnStatusChanged += CurrentProfileControl_OnStatusChanged;
// get profile image for the current user
CurrentProfileControl.ProfileImage = _imgFactory.GetAndCreateProfileImage(_apiService.CurrentUser.Id, _apiService.CurrentUser.Status, _apiService.CurrentUser.ActiveProfileCosmetic);
// setup main tab control
MainTabControl = new(_imgFactory)
{
Location = new(12, 91)
};
MainTabControl.OnRoomControlDoubleClicked += MainTabControl_OnRoomControlDoubleClicked;
MainTabControl.OnContactControlDoubleClicked += MainTabControl_OnContactControlDoubleClicked;
MainTabControl.OnUserItemDoubleClicked += MainTabControl_OnUserItemDoubleClicked;
MainTabControl.OnStoreItemDoubleClicked += MainTabControl_OnStoreItemDoubleClicked;
MainTabControl.OnGameItemDoubleClicked += MainTabControl_OnGameItemDoubleClicked;
// get and set contacts
var _currentUserContacts = await _apiService.GetCurrentUserContacts();
if (_currentUserContacts.Success && _currentUserContacts.Data != null)
{
UserContactsList.Clear();
UserContactsList.AddRange([.. _currentUserContacts.Data.DistinctBy(c => c.Id)]);
await SetupContactsUI(_currentUserContacts.Data);
}
// get and set rooms
var _roomList = await _apiService.GetAllRoomsAsync();
if (_roomList.Success && _roomList.Data != null)
await SetupRoomsUI(_roomList.Data);
// get and set user directory
var _currentUserDirectory = await _apiService.GetAllUsersAsync();
if (_currentUserDirectory.Success && _currentUserDirectory.Data != null)
await SetupDirectoryUI(_currentUserDirectory.Data);
// get and set store
var _currentStore = await _apiService.GetStoreItems();
if (_currentStore.Success && _currentStore.Data != null)
MainTabControl?.AddStoreItems(_currentStore.Data);
// add controls to current form
Controls.Add(CurrentProfileControl);
Controls.Add(MainTabControl);
if(_apiService.CurrentUser.Role == "Admin")
{
// create a link label that opens the admin panel when clicked
LinkLabel llblAdminPanel = new()
{
Location = new(325, 9),
Text = "Admin Panel",
BackColor = Color.Transparent,
};
llblAdminPanel.Click += (sender, e) =>
{
// open the admin panel
AdminPanelForm adminPanelForm = new(_apiService);
adminPanelForm.ShowDialog();
adminPanelForm.Dispose();
};
Controls.Add(llblAdminPanel);
// set isadmin to true for other admin stuff
IsAdmin = true;
}
ResumeLayout(true);
// minimize main window if start minimized is on
if (_config.StartMinimized)
WindowState = FormWindowState.Minimized;
// check for daily spin eligibility
var now = DateTime.UtcNow;
var lastSpin = _apiService.CurrentUser.LastCurrencySpin;
if (lastSpin.Date < now.Date)
{
Random rnd = new();
JackpotSpinForm _jackpotSpin = new(_audioService)
{
CurrencyWon = rnd.Next(0, 200)
};
var _dialogRes = _jackpotSpin.ShowDialog();
if (_dialogRes == DialogResult.OK)
{
// claim
var _apiRes = await _apiService.AddCurrencyToCurrentUser(_jackpotSpin.CurrencyWon, true);
if (_apiRes.Success)
_jackpotSpin.Dispose();
else
KryptonMessageBox.Show("We Couldn't Claim Your Prize At This Time. You Should Be Able To Spin Again Next Restart.", "Uh Oh.");
}
}
}
else
{
ResumeLayout(true);
KryptonMessageBox.Show("An Error Occured Trying To Connect To The Gateway. Please Try Again Later.", "Uh Oh.", KryptonMessageBoxButtons.OK, KryptonMessageBoxIcon.Error);
Application.Exit();
}
}
}
private async void _gatewayService_OnUserStatusUpdated(object? sender, EventArgs e)
{
if(e is UserStatusUpdatedEventArgs _args)
{
CurrentProfileControl?.ProfileImage = _imgFactory.GetAndCreateProfileImage(_apiService.CurrentUser!.Id, _args.StatusDto!.Status, _apiService.CurrentUser!.ActiveProfileCosmetic);
}
}
private async void CurrentProfileControl_OnStatusChanged(object? sender, EventArgs e)
{
if(sender is CurrentProfileControl _ctrl)
{
// set status based on selected
await _gatewayService.UpdateStatus(_ctrl.SelectedStatus);
}
}
private void MainTabControl_OnGameItemDoubleClicked(object? sender, EventArgs e)
{
if(sender is MainTabControl _ctrl)
{
string? gameSelected = (string?)_ctrl.SelectedGameItem?.Tag;
switch (gameSelected)
{
case "StockMarketGame":
StockMarketGame stockMarketGame = new(_apiService);
stockMarketGame.Show();
break;
case "GuessTheNumberGame":
GuessTheNumber guessTheNumber = new(_apiService, _audioService);
guessTheNumber.Show();
break;
case "TicTacToeGame":
TicTacToeGame ticTacToeGame = new(_apiService, _config);
ticTacToeGame.Show();
break;
}
}
}
private async void MainTabControl_OnStoreItemDoubleClicked(object? sender, EventArgs e)
{
if (sender is MainTabControl _ctrl && _ctrl.SelectedStoreItem?.Tag is int _itemId)
{
// get store item
var _item = await _apiService.GetStoreItem(_itemId);
if (_item.Success && _item.Data != null)
{
// create buy form
StoreItemForm _itemForm = new(_apiService)
{
ItemId = _itemId,
ItemName = _ctrl.SelectedStoreItem.Text,
ItemThumbnail = await _imgFactory.GetStoreItemThumb(_itemId)
};
_itemForm.OnBuyClicked += _itemForm_OnBuyClicked;
_itemForm.ShowDialog();
_itemForm.Dispose();
}
}
}
private async void _itemForm_OnBuyClicked(object? sender, EventArgs e)
{
if (sender is StoreItemForm _form)
{
// buy the item
var _res = await _apiService.BuyStoreItem(_form.ItemId);
if (_res.Success)
{
KryptonMessageBox.Show("Item Bought!", "Yay!");
_form.Close();
}
else
{
KryptonMessageBox.Show("Something Went Wrong Buying This Item. Please Try Again Later.", "Uh Oh.");
_form.Close();
}
}
}
private async void LogoutAsync()
{
var _res = await _apiService.LogoutAsync();
if (_res)
{
_credentialService.DeleteAccessToken();
SuspendLayout();
// remove controls
Controls.Remove(MainTabControl);
Controls.Remove(CurrentProfileControl);
// dispose of them
MainTabControl?.Dispose();
MainTabControl = null;
CurrentProfileControl?.Dispose();
CurrentProfileControl = null;
// readd login control and branding
Size = LoggedOutSize;
// unsub from gateway events
_gatewayService.OnServerReconnecting -= _gatewayService_OnServerReconnecting;
_gatewayService.OnServerReconnected -= _gatewayService_OnServerReconnected;
_gatewayService.OnServerDisconnect -= _gatewayService_OnServerDisconnect;
//_gatewayService.OnDirectMessageReceived -= _gatewayService_OnDirectMessageReceived;
_gatewayService.OnRoomMessageReceived -= _gatewayService_OnRoomMessageReceived;
_gatewayService.OnRoomUserListReceived -= _gatewayService_OnRoomUserListReceived;
_gatewayService.OnRefreshUserListsReceived -= _gatewayService_OnRefreshUserListReceived;
_gatewayService.OnRefreshRoomListReceived -= _gatewayService_OnRefreshRoomListReceived;
_gatewayService.OnRefreshContactsListReceived -= _gatewayService_OnRefreshContactsListReceived;
_gatewayService.OnServerConfigReceived -= _gatewayService_OnServerConfigReceived;
_gatewayService.OnUserForceLogout -= _gatewayService_OnUserForceLogout;
// stop gateway connection
await _gatewayService.StopAsync();
// add branding control
BrandingControl = new()
{
Location = new(-2, -17),
Anchor = AnchorStyles.Top | AnchorStyles.Left
};
// add login control
LoginControl = new()
{
Location = new(12, 233)
};
LoginControl.OnSuccessfulLogin += LoginControl_OnSuccessfulLogin;
LoginControl.OnRegisterPressed += LoginControl_OnRegisterPressed;
Controls.Add(BrandingControl);
Controls.Add(LoginControl);
ResumeLayout(true);
}
}
private async void CurrentProfileControl_OnSignOutClicked(object? sender, EventArgs e)
{
var _dialogRes = KryptonMessageBox.Show("Doing This Will Sign You Out. Are You Sure?", "are you sure...?",
KryptonMessageBoxButtons.YesNo, KryptonMessageBoxIcon.Question);
if (_dialogRes == DialogResult.Yes)
LogoutAsync();
}
private async void CurrentProfileControl_OnEditProfileClicked(object? sender, EventArgs e)
{
var _user = await _apiService.GetUserInformationAsync(_apiService.CurrentUser!.Id);
if (_user.Success && _user.Data != null)
{
// create a profile form
ProfileForm _profile = new(_apiService, _imgFactory)
{
UserId = _user.Data.Id,
Username = _user.Data.Username,
Bio = _user.Data.Bio,
Status = _user.Data.Status,
ProfileImage = _imgFactory.GetAndCreateProfileImage(_user.Data.Id, _user.Data.Status, _user.Data.ProfileCosmeticId)
};
_profile.OnClose += ProfileForm_OnClose;
OpenProfileForms.Add(_profile);
_profile.Show();
}
}
private void _gatewayService_OnRoomUserListReceived(object? sender, EventArgs e)
{
if (e is RoomListEventArgs _args)
{
// get the open chat room form
var _chatRoom = OpenChatRoomForms.FirstOrDefault(e => e.RoomId == _args.Room.Id);
if (_chatRoom != null)
{
// the users to the list
_chatRoom.AddUsersToRoomList(_args.UserList);
}
}
}
private async void _gatewayService_OnRoomMessageReceived(object? sender, EventArgs e)
{
if (e is ServerMessageEventArgs _args)
{
// get the open chat room form
var _chatRoom = OpenChatRoomForms.FirstOrDefault(e => e.RoomId == _args.Room.Id);
if (_chatRoom != null)
{
// build message control
MessageControl _msg = new()
{
Message = _args.Message,
Username = _args.User.Username
};
// add message
_chatRoom.AddMessage(_msg);
if (_args.User.Id != "0")
await _chatRoom.LoadProfileImage(_msg, _args.User);
// play sound
if (_args.User.Id != _apiService.CurrentUser?.Id)
_audioService.PlaySoundEffect("sndMessage");
else
_audioService.PlaySoundEffect("sndSendClick");
}
}
}
private async Task SetupContactsUI(List<Contact> data)
{
// build ctrl list
List<ContactControl> _contactCtrls = [];
foreach (var contact in data)
{
var ctrl = await BuildContactControl(contact);
if (ctrl != null)
_contactCtrls.Add(ctrl);
}
// add to control
MainTabControl?.AddContacts(_contactCtrls);
}
private async Task SetupRoomsUI(List<Room> data)
{
List<RoomControl> _roomCtrls = [];
// before adding db rooms, add lobby
_roomCtrls.Add(new()
{
RoomId = "LOBBY",
RoomName = "Lobby",
IsUserCountVisible = false,
});
// build roomcontrol list
foreach (var room in data)
{
RoomControl _ctrl = new()
{
RoomId = room.Id,
RoomName = room.Name,
UserCount = room.UserCount,
};
_roomCtrls.Add(_ctrl);
}
// add to control
MainTabControl?.AddRooms(_roomCtrls);
}
private async Task SetupDirectoryUI(List<UserInformationDto> data)
{
// build listviewitem list
List<ListViewItem> _userViews = [];
foreach (var user in data)
{
ListViewItem lvi = new()
{
Tag = user.Id,
Text = user.Username,
ImageIndex = user.Status,
};
_userViews.Add(lvi);
}
// add to control
MainTabControl?.AddUsers(_userViews);
}
private async Task<ContactControl?> BuildContactControl(Contact contact)
{
if (_apiService.CurrentUser != null)
{
ServiceResponse<UserInformationDto> user = null!;
if (contact.OwnerId == _apiService.CurrentUser.Id)
user = await _apiService.GetUserInformationAsync(contact.UserId);
else if (contact.UserId == _apiService.CurrentUser.Id)
user = await _apiService.GetUserInformationAsync(contact.OwnerId);
if (user.Data != null)
{
var ctrl = new ContactControl
{
UserId = user.Data.Id,
Username = user.Data.Username,
TextStatus = "NOT IMPLEMENTED",
Status = user.Data.Status,
};
if (contact.OwnerId == _apiService.CurrentUser.Id)
{
switch (contact.OwnerStatus)
{
case Contact.ContactStatus.AwaitingApprovalFromOther:
ctrl.Username = $"{user.Data.Username} [Request Sent]";
break;
case Contact.ContactStatus.Accepted:
ctrl.Username = user.Data.Username;
break;
}
// get profile image
ctrl.ProfilePic = _imgFactory.GetAndCreateProfileImage(user.Data.Id, user.Data.Status, user.Data.ProfileCosmeticId);
}
else if (contact.UserId == _apiService.CurrentUser.Id)
{
switch (contact.UserStatus)
{
case Contact.ContactStatus.AwaitingApprovalFromSelf:
ctrl.Username = $"{user.Data.Username} [Contact Request]";
_audioService.PlaySoundEffect("sndContactRequest");
break;
case Contact.ContactStatus.Accepted:
ctrl.Username = user.Data.Username;
break;
}
// get profile image
ctrl.ProfilePic = _imgFactory.GetAndCreateProfileImage(user.Data.Id, user.Data.Status, user.Data.ProfileCosmeticId);
}
// return the control
return ctrl;
}
}
return default;
}
private void niMain_DoubleClick(object sender, EventArgs e)
{
if (WindowState == FormWindowState.Minimized)
{
Show();
WindowState = FormWindowState.Normal;
}
}
private void tsiShow_Click(object sender, EventArgs e)
{
if (WindowState == FormWindowState.Minimized)
{
Show();
WindowState = FormWindowState.Normal;
}
}
private void tsiExit_Click(object sender, EventArgs e)
{
Close();
}
}
}