AlanMoonbase 003d01fe4e Implement Store Frontend
Implement Profile Cosmetics
2025-07-10 17:18:54 -07:00

874 lines
39 KiB
C#

using QtCNETAPI.Dtos.User;
using QtCNETAPI.Services.ApiService;
using QtCNETAPI.Services.GatewayService;
using QtCNETAPI.Events;
using QtCNETAPI.Models;
using qtc_net_client_2.Forms;
using qtc_net_client_2.Services;
using qtc_net_client_2.ClientModel;
using System.Threading.Tasks;
using QtCNETAPI.Schema;
namespace qtc_net_client_2
{
public partial class Main : Form
{
private IApiService _apiService;
private IGatewayService _gatewayService;
private Config _config;
private AudioService AudioService = new();
private LoggingService LoggingService;
public List<Room> RoomList = [];
public List<UserInformationDto> UserDirectory = [];
public List<Contact> Contacts = [];
private bool FirstMinimize = true;
public Main(IApiService apiService, IGatewayService gatewayService, Config config, LoggingService loggingService)
{
_apiService = apiService;
_gatewayService = gatewayService;
_config = config;
LoggingService = loggingService;
InitializeComponent();
}
private async void frmMain_Load(object sender, EventArgs e)
{
LoggingService.LogString("Main Form Loaded");
// start request notif blink task
Thread blinkThread = new Thread(async () => await StartRequestNotifBlankLoop(lblRequestNotif));
blinkThread.Start();
// check if client is already logged in
if (_apiService.CurrentUser == null)
{
// not logged in, load the login form
Login frmLogin = new Login(_apiService);
var result = frmLogin.ShowDialog();
if (result == DialogResult.OK)
await OnSuccessfulLogin();
}
}
private async void llblSignIn_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
// just reshow the login dialog lol
Login frmLogin = new Login(_apiService);
var result = frmLogin.ShowDialog();
if (result == DialogResult.OK)
await OnSuccessfulLogin();
}
private async void lbRooms_DoubleClick(object sender, EventArgs e)
{
if (lbRooms.SelectedItems.Count > 0)
{
string? selectedRoom = (string?)lbRooms.SelectedItems[lbRooms.SelectedItems.Count - 1];
if (selectedRoom != null)
{
if (selectedRoom == "Lobby")
{
// join lobby
if (!_gatewayService.InLobby) await _gatewayService.JoinLobbyAsync();
ChatRoom frmChat = new ChatRoom(_gatewayService, _apiService);
frmChat.Show();
LoggingService.LogString("User Has Joined Lobby Room");
return;
}
// join the room
Room? room = RoomList.FirstOrDefault(e => e.Name == selectedRoom);
if (room != null)
{
if (_gatewayService.CurrentRoom != room) await _gatewayService.JoinRoomAsync(room);
ChatRoom frmChat = new ChatRoom(_gatewayService, _apiService);
frmChat.Show();
LoggingService.LogString($"User Has Joined {room.Name}");
}
}
}
}
private void pbUserPfp_Click(object sender, EventArgs e)
{
var args = (MouseEventArgs)e;
if (args.Button == MouseButtons.Right) return;
Thread t = new Thread(new ThreadStart(async () =>
{
using (OpenFileDialog openFileDialog = new OpenFileDialog())
{
openFileDialog.InitialDirectory = Environment.CurrentDirectory;
openFileDialog.Title = "Select New Profile Picture";
openFileDialog.Filter = "Image Files (*.png, *.jpg)|*.png;*.jpg";
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
// upload to server with api endpoint
var res = await _apiService.UpdateUserProfilePic(openFileDialog.FileName);
if (res.Success)
{
// update profile pic in ui
var pfpRes = await _apiService.GetUserProfilePic(_apiService.CurrentUser.Id);
if (pfpRes.Success && pfpRes.Data != null)
{
using (var ms = new MemoryStream(pfpRes.Data))
{
pbUserPfp.Image = Image.FromStream(ms);
ms.Dispose();
}
}
else LoggingService.LogString($"User Has No Profile Picture Or It Could Not Be Loaded.\n{pfpRes.Message}");
}
}
}
}));
t.SetApartmentState(ApartmentState.STA);
t.Start();
}
private void llblSignOut_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
if (MessageBox.Show("Are You Sure You Want To Sign Out?\nThis Deletes Your session.token, Requiring You To Sign In Again", "are you sure...?", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes)
{
File.Delete("./session.token");
Environment.Exit(0);
}
}
private void llblEditProfile_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
ProfileEdit frmProfileEdit = new ProfileEdit(_apiService);
var dialogResult = frmProfileEdit.ShowDialog();
if (dialogResult == DialogResult.OK)
{
MessageBox.Show("If you updated your username, hit the refresh button to see it update on your lists.\nThe top username will not update until you restart your client.");
}
}
private async void lvContacts_DoubleClick(object sender, EventArgs e)
{
if (lvContacts.SelectedItems.Count > 0)
{
string? selectedUser = (string?)lvContacts.SelectedItems[lvContacts.SelectedItems.Count - 1].Text;
if (selectedUser != null)
{
// split from [ if it exists
if (selectedUser.Contains('[')) selectedUser = selectedUser.Split('[', options: StringSplitOptions.TrimEntries)[0];
// get user info and open profile dialog
var user = UserDirectory.FirstOrDefault(e => e.Username == selectedUser);
var res = await _apiService.GetUserInformationAsync(user!.Id);
var pfpRes = await _apiService.GetUserProfilePic(user!.Id);
if (pfpRes != null && !pfpRes.Success) LoggingService.LogString($"User Has No Profile Picture Or It Could Not Be Loaded.\n{pfpRes.Message}");
if (res.Data != null && res.Success)
{
LoggingService.LogString($"Opening Profile For User '{res.Data.Username}'");
Profile frmProfile = new Profile(res.Data, pfpRes, Contacts, _apiService, _gatewayService);
frmProfile.Show();
}
}
}
}
private void frmMain_Resize(object sender, EventArgs e)
{
if (WindowState == FormWindowState.Minimized && _config.MinimizeToTray)
{
Hide();
niMain.Visible = true;
if (FirstMinimize)
{
niMain.ShowBalloonTip(10,
"I'm over here!",
"QtC.NET Mimimizes To Tray By Default. To Change This Behaviour, Refer To config.json",
ToolTipIcon.Info);
FirstMinimize = false;
}
}
}
private void niMain_DoubleClick(object sender, EventArgs e)
{
Show();
WindowState = FormWindowState.Normal;
niMain.Visible = false;
}
private async void frmMain_FormClosed(object sender, FormClosedEventArgs e)
{
DialogResult = DialogResult.OK;
// ensure the gateway stops the connection and disposes properly
await _gatewayService.StopAsync();
await _gatewayService.DisposeAsync();
}
private async void ctxmChangeStatus_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
{
if (e.ClickedItem != null)
{
UserStatus userStatus = UserStatus.Unknown;
switch (e.ClickedItem.Name)
{
case "onlineToolStripMenuItem":
userStatus = UserStatus.Online;
onlineToolStripMenuItem.Checked = true;
awayToolStripMenuItem.Checked = false;
doNotDisturbToolStripMenuItem.Checked = false;
invisibleToolStripMenuItem.Checked = false;
break;
case "awayToolStripMenuItem":
userStatus = UserStatus.Away;
onlineToolStripMenuItem.Checked = false;
awayToolStripMenuItem.Checked = true;
doNotDisturbToolStripMenuItem.Checked = false;
invisibleToolStripMenuItem.Checked = false;
break;
case "doNotDisturbToolStripMenuItem":
userStatus = UserStatus.DoNotDisturb;
onlineToolStripMenuItem.Checked = false;
awayToolStripMenuItem.Checked = false;
doNotDisturbToolStripMenuItem.Checked = true;
invisibleToolStripMenuItem.Checked = false;
break;
case "invisibleToolStripMenuItem":
userStatus = UserStatus.Offline;
onlineToolStripMenuItem.Checked = false;
awayToolStripMenuItem.Checked = false;
doNotDisturbToolStripMenuItem.Checked = false;
invisibleToolStripMenuItem.Checked = true;
break;
}
// set it
await _gatewayService.UpdateStatus((int)userStatus);
}
}
private void btnAddRoom_Click(object sender, EventArgs e)
{
CreateRoom createRoom = new CreateRoom(_apiService);
createRoom.ShowDialog();
}
private async void llblClaimSpin_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
CurrencyJackpotSpinner tokenJackpotSpinner = new CurrencyJackpotSpinner();
var frmResult = tokenJackpotSpinner.ShowDialog();
if (frmResult == DialogResult.OK && tokenJackpotSpinner.TokensWon > 0)
{
// claim
var result = await _apiService.AddCurrencyToCurrentUser(tokenJackpotSpinner.TokensWon, true);
if (result.Success)
{
lblCurrencyAmount.Text = _apiService.CurrentUser.CurrencyAmount.ToString("N0");
llblClaimSpin.Visible = false;
}
else MessageBox.Show("We Were Unable To Claim Your Prize At This Time. Please Try Again Later.", "Uh Oh.", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private async void lbUserDirectory_DoubleClick(object sender, EventArgs e)
{
if (lvUserDirectory.SelectedItems.Count > 0)
{
string? selectedUser = (string?)lvUserDirectory.SelectedItems[lvUserDirectory.SelectedItems.Count - 1].Text;
if (selectedUser != null)
{
// get user info and open profile dialog
var user = UserDirectory.FirstOrDefault(e => e.Username == selectedUser);
var res = await _apiService.GetUserInformationAsync(user!.Id);
var pfpRes = await _apiService.GetUserProfilePic(user!.Id);
if (pfpRes != null && !pfpRes.Success) LoggingService.LogString($"User Has No Profile Picture Or It Could Not Be Loaded.\n{pfpRes.Message}");
if (res.Data != null && res.Success)
{
LoggingService.LogString($"Opening Profile For User '{res.Data.Username}'");
Profile frmProfile = new Profile(res.Data, pfpRes, Contacts, _apiService, _gatewayService);
frmProfile.Show();
}
}
}
}
private void lvGames_DoubleClick(object sender, EventArgs e)
{
if (lvGames.SelectedItems.Count > 0)
{
string? gameSelected = (string?)lvGames.SelectedItems[lvGames.SelectedItems.Count - 1].Tag;
switch (gameSelected)
{
case "StockMarketGame":
StockMarketGame stockMarketGame = new StockMarketGame(_apiService);
stockMarketGame.Show();
break;
case "GuessTheNumberGame":
GuessTheNumber guessTheNumber = new GuessTheNumber(_apiService);
guessTheNumber.Show();
break;
case "TicTacToeGame":
TicTacToeGame ticTacToeGame = new TicTacToeGame(_apiService, _config);
ticTacToeGame.Show();
break;
}
}
}
private async void refreshToolStripMenuItem_Click(object sender, EventArgs e)
{
if (tbcMain.SelectedIndex == 0) await RefreshContactsList();
if (tbcMain.SelectedIndex == 1) await RefreshRoomsList();
if (tbcMain.SelectedIndex == 2) await RefreshUsers();
}
private void pbDonate_Click(object sender, EventArgs e)
{
DonationWindow donationWindow = new DonationWindow();
donationWindow.Show();
}
private async void tbcMain_SelectedIndexChanged(object sender, EventArgs e)
{
if (tbcMain.SelectedIndex == 4)
{
// get store items
var storeItems = await _apiService.GetStoreItems();
if (storeItems != null && storeItems.Success && storeItems.Data != null)
{
ilStoreThumbnails.Images.Clear();
foreach (var item in storeItems.Data)
{
await GetAndAddStoreThumbnail(item);
var lvitem = lvStoreItems.Items.Add(new ListViewItem { Text = item.Name, Name = item.Id.ToString() });
lvitem.ImageKey = item.Id.ToString();
}
}
}
else lvStoreItems.Clear();
}
private async void lvStoreItems_DoubleClick(object sender, EventArgs e)
{
if (lvStoreItems.SelectedItems.Count > 0)
{
string? itemSelected = (string?)lvStoreItems.SelectedItems[lvStoreItems.SelectedItems.Count - 1].Name;
if(itemSelected != null)
{
// get item
var item = await _apiService.GetStoreItem(int.Parse(itemSelected));
if(item != null && item.Success && item.Data != null)
{
StoreItemDisplay storeItemDisplay = new StoreItemDisplay(item.Data, LoggingService, _apiService);
storeItemDisplay.ShowDialog();
}
}
}
}
private async Task OnSuccessfulLogin()
{
// double check
if (_apiService.CurrentUser != null && _apiService.SessionToken != null)
{
LoggingService.LogString($"Logged In As '{_apiService.CurrentUser.Username}'");
LoggingService.LogString("Starting SignalR Connection...");
// start gateway connection
await _gatewayService.StartAsync();
// subscribe to gateway events
_gatewayService.OnServerReconnecting += _gatewayService_OnServerReconnecting;
_gatewayService.OnServerReconnected += _gatewayService_OnServerReconnected;
_gatewayService.OnServerDisconnect += _gatewayService_OnServerDisconnect;
_gatewayService.OnDirectMessageReceived += _gatewayService_OnDirectMessageReceived;
_gatewayService.OnRefreshUserListsReceived += _gatewayService_OnRefreshUserListReceived;
_gatewayService.OnRefreshRoomListReceived += _gatewayService_OnRefreshRoomListReceived;
_gatewayService.OnRefreshContactsListReceived += _gatewayService_OnRefreshContactsListReceived;
_gatewayService.OnServerConfigReceived += _gatewayService_OnServerConfigReceived;
if (_gatewayService.HubConnection != null && _gatewayService.HubConnection.State == Microsoft.AspNetCore.SignalR.Client.HubConnectionState.Connected)
{
LoggingService.LogString("Connected To SignalR Succesfully.");
// we are fully logged in, get current user profile pic and set up ui
llblSignIn.Visible = false;
lblWelcome.Text = $"Welcome, {_apiService.CurrentUser.Username}";
lblCurrencyAmount.Visible = true;
pbCurrencyIcon.Visible = true;
lblCurrencyAmount.Text = _apiService.CurrentUser.CurrencyAmount.ToString("N0");
llblSignOut.Visible = true;
llblEditProfile.Visible = true;
tbcMain.Enabled = true;
var pfpRes = await _apiService.GetUserProfilePic(_apiService.CurrentUser.Id);
if (pfpRes.Success && pfpRes.Data != null)
{
using (var ms = new MemoryStream(pfpRes.Data))
{
pbUserPfp.Image = Image.FromStream(ms);
ms.Dispose();
}
}
await RefreshContactsList();
await RefreshRoomsList();
await RefreshUsers();
// TODO - figure out server side why online status is invisible on login
_apiService.CurrentUser.Status = 1;
// set status context menu checked
UserStatus cuStatus = (UserStatus)_apiService.CurrentUser.Status;
switch (cuStatus)
{
case UserStatus.Online:
onlineToolStripMenuItem.Checked = true;
awayToolStripMenuItem.Checked = false;
doNotDisturbToolStripMenuItem.Checked = false;
invisibleToolStripMenuItem.Checked = false;
break;
case UserStatus.Away:
onlineToolStripMenuItem.Checked = false;
awayToolStripMenuItem.Checked = true;
doNotDisturbToolStripMenuItem.Checked = false;
invisibleToolStripMenuItem.Checked = false;
break;
case UserStatus.DoNotDisturb:
onlineToolStripMenuItem.Checked = false;
awayToolStripMenuItem.Checked = false;
doNotDisturbToolStripMenuItem.Checked = true;
invisibleToolStripMenuItem.Checked = false;
break;
case UserStatus.Offline:
onlineToolStripMenuItem.Checked = false;
awayToolStripMenuItem.Checked = false;
doNotDisturbToolStripMenuItem.Checked = false;
invisibleToolStripMenuItem.Checked = true;
break;
}
if (_apiService.CurrentUser.Role == "Admin") btnAddRoom.Enabled = true;
else btnAddRoom.Enabled = false;
var current = DateTime.UtcNow;
if (current > _apiService.CurrentUser.LastCurrencySpin.ToUniversalTime() || _apiService.CurrentUser.LastCurrencySpin == new DateTime()) llblClaimSpin.Visible = true;
else llblClaimSpin.Visible = false;
if (_config.StartMinimized) WindowState = FormWindowState.Minimized;
LoggingService.LogString("Client Ready");
}
}
}
private async Task RefreshUsers()
{
LoggingService.LogString("Refreshing All Users List...");
// get all users on server
var userList = await _apiService.GetAllUsersAsync();
if (userList != null && userList.Success && userList.Data != null)
{
// clear the list
if (lvUserDirectory.InvokeRequired) lvUserDirectory.BeginInvoke(lvUserDirectory.Items.Clear);
else lvUserDirectory.Items.Clear();
UserDirectory.Clear();
// populate list
foreach (var user in userList.Data)
{
if (lvUserDirectory.InvokeRequired)
{
lvUserDirectory.BeginInvoke(delegate () { lvUserDirectory.Items.Add(user.Username, user.Status); });
}
else
{
lvUserDirectory.Items.Add(user.Username, user.Status);
}
UserDirectory.Add(user);
}
}
}
private async Task RefreshRoomsList()
{
LoggingService.LogString("Refreshing Rooms List...");
if (InvokeRequired)
{
await Invoke(async delegate ()
{
lbRooms.Items.Clear();
var roomsRes = await _apiService.GetAllRoomsAsync();
if (roomsRes.Success && roomsRes.Data != null)
{
foreach (var room in roomsRes.Data)
{
lbRooms.Items.Add(room.Name);
}
RoomList = roomsRes.Data;
}
// always add lobby room to rooms list
lbRooms.Items.Add("Lobby");
});
return;
}
lbRooms.Items.Clear();
var roomsRes = await _apiService.GetAllRoomsAsync();
if (roomsRes.Success && roomsRes.Data != null)
{
lbRooms.Items.Clear();
foreach (var room in roomsRes.Data)
{
lbRooms.Items.Add(room.Name);
}
RoomList = roomsRes.Data;
}
// always add lobby room to rooms list
lbRooms.Items.Add("Lobby");
}
private async Task RefreshContactsList()
{
LoggingService.LogString("Refreshing Contacts List...");
if (InvokeRequired)
{
await Invoke(async delegate ()
{
lvContacts.Items.Clear();
Contacts.Clear();
lblRequestNotif.Visible = false;
var contactsRes = await _apiService.GetCurrentUserContacts();
if (contactsRes.Success && contactsRes.Data != null)
{
if (contactsRes.Data.Where(e => e.UserId == _apiService.CurrentUser!.Id && e.UserStatus == Contact.ContactStatus.AwaitingApprovalFromSelf).Count() >= 1)
lblRequestNotif.Visible = true;
else
lblRequestNotif.Visible = false;
foreach (var contact in contactsRes.Data)
{
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)
{
Contacts.Add(contact);
if (contact.OwnerId == _apiService.CurrentUser!.Id)
{
switch (contact.OwnerStatus)
{
case Contact.ContactStatus.AwaitingApprovalFromOther:
var lvi = lvContacts.Items.Add($"{user.Data.Username} [Request Sent]");
await AddProfilePicToList(user.Data.Id);
if (ilProfilePics.Images.ContainsKey(user.Data.Id))
lvi.ImageKey = user.Data.Id;
else lvi.ImageKey = "DEFAULT";
break;
case Contact.ContactStatus.Accepted:
var lvi2 = lvContacts.Items.Add($"{user.Data.Username}");
await AddProfilePicToList(user.Data.Id);
if (ilProfilePics.Images.ContainsKey(user.Data.Id))
lvi2.ImageKey = user.Data.Id;
else lvi2.ImageKey = "DEFAULT";
break;
}
}
else if (contact.UserId == _apiService.CurrentUser!.Id)
{
switch (contact.UserStatus)
{
case Contact.ContactStatus.AwaitingApprovalFromSelf:
var lvi = lvContacts.Items.Add($"{user.Data.Username} [Contact Request]");
await AddProfilePicToList(user.Data.Id);
if (ilProfilePics.Images.ContainsKey(user.Data.Id))
lvi.ImageKey = user.Data.Id;
else lvi.ImageKey = "DEFAULT";
AudioService.PlaySoundEffect("sndContactRequest");
break;
case Contact.ContactStatus.Accepted:
var lvi2 = lvContacts.Items.Add($"{user.Data.Username}");
await AddProfilePicToList(user.Data.Id);
if (ilProfilePics.Images.ContainsKey(user.Data.Id))
lvi2.ImageKey = user.Data.Id;
else lvi2.ImageKey = "DEFAULT";
break;
}
}
}
}
}
});
return;
}
lvContacts.Items.Clear();
Contacts.Clear();
lblRequestNotif.Visible = false;
var contactsRes = await _apiService.GetCurrentUserContacts();
if (contactsRes.Success && contactsRes.Data != null)
{
if (contactsRes.Data.Where(e => e.UserId == _apiService.CurrentUser!.Id && e.UserStatus == Contact.ContactStatus.AwaitingApprovalFromSelf).Count() >= 1)
lblRequestNotif.Visible = true;
else
lblRequestNotif.Visible = false;
foreach (var contact in contactsRes.Data)
{
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)
{
Contacts.Add(contact);
if (contact.OwnerId == _apiService.CurrentUser!.Id)
{
switch (contact.OwnerStatus)
{
case Contact.ContactStatus.AwaitingApprovalFromOther:
var lvi = lvContacts.Items.Add($"{user.Data.Username} [Request Sent]");
await AddProfilePicToList(user.Data.Id);
if (ilProfilePics.Images.ContainsKey(user.Data.Id))
lvi.ImageKey = user.Data.Id;
else lvi.ImageKey = "DEFAULT";
break;
case Contact.ContactStatus.Accepted:
var lvi2 = lvContacts.Items.Add($"{user.Data.Username}");
await AddProfilePicToList(user.Data.Id);
if (ilProfilePics.Images.ContainsKey(user.Data.Id))
lvi2.ImageKey = user.Data.Id;
else lvi2.ImageKey = "DEFAULT";
break;
}
}
else if (contact.UserId == _apiService.CurrentUser!.Id)
{
switch (contact.UserStatus)
{
case Contact.ContactStatus.AwaitingApprovalFromSelf:
var lvi = lvContacts.Items.Add($"{user.Data.Username} [Contact Request]");
await AddProfilePicToList(user.Data.Id);
if (ilProfilePics.Images.ContainsKey(user.Data.Id))
lvi.ImageKey = user.Data.Id;
else lvi.ImageKey = "DEFAULT";
AudioService.PlaySoundEffect("sndContactRequest");
break;
case Contact.ContactStatus.Accepted:
var lvi2 = lvContacts.Items.Add($"{user.Data.Username}");
await AddProfilePicToList(user.Data.Id);
if (ilProfilePics.Images.ContainsKey(user.Data.Id))
lvi2.ImageKey = user.Data.Id;
else lvi2.ImageKey = "DEFAULT";
break;
}
}
}
}
}
}
private async Task StartRequestNotifBlankLoop(Label label)
{
while (true)
{
if (!IsHandleCreated) { LoggingService.LogString("Form Handle Wasn't Created"); return; }
if (InvokeRequired && !IsDisposed)
{
BeginInvoke(async delegate ()
{
label.ForeColor = Color.Red;
await Task.Delay(500);
label.ForeColor = Color.Blue;
await Task.Delay(500);
});
}
label.ForeColor = Color.Red;
await Task.Delay(500);
label.ForeColor = Color.Blue;
await Task.Delay(500);
}
}
private async Task AddProfilePicToList(string userId)
{
var result = await _apiService.GetUserProfilePic(userId);
if (result != null && result.Success && result.Data != null)
{
using (var ms = new MemoryStream(result.Data))
{
ilProfilePics.Images.Add(userId, Image.FromStream(ms));
ms.Dispose();
}
}
else if (result != null) LoggingService.LogString($"User Has No Profile Picture Or It Could Not Be Loaded.\n{result.Message}");
}
private async Task GetAndAddStoreThumbnail(StoreItem item)
{
try
{
using HttpClient client = new();
var response = await client.GetAsync(item.ThumbnailUrl);
if (response != null && response.IsSuccessStatusCode)
{
using var stream = await response.Content.ReadAsStreamAsync();
Image image = Image.FromStream(stream);
stream.Dispose();
ilStoreThumbnails.Images.Add(item.Id.ToString(), image);
}
else if (response != null) LoggingService.LogString($"Store Item Thumbnail Could Not Be Loaded Due To Status Code {response.StatusCode}");
else LoggingService.LogString("Store Item Thumbnail Could Not Be Loaded");
client.Dispose();
}
catch (Exception ex)
{
LoggingService.LogString("Store Item Thumbnail Could Not Be Loaded\n" + ex.Message);
}
}
public void RefreshCurrencyCounter()
{
if (lblCurrencyAmount.InvokeRequired)
{
lblCurrencyAmount.BeginInvoke(delegate ()
{
lblCurrencyAmount.Text = _apiService.CurrentUser.CurrencyAmount.ToString("N0");
});
}
else
{
lblCurrencyAmount.Text = _apiService.CurrentUser.CurrencyAmount.ToString("N0");
}
}
private async void _gatewayService_OnServerDisconnect(object? sender, EventArgs e)
{
LoggingService.LogString("Disconnected From SignalR");
if (DialogResult == DialogResult.OK) return;
var args = (ServerConnectionClosedEventArgs)e;
string? error = string.Empty;
if (args.Error != null) { error = args.Error.Message; LoggingService.LogString($"{args.Error.Message}\n{args.Error.StackTrace}"); }
// disconnect can sometimes be caused by an expired JWT token, attempt connection restart
await _gatewayService.StopAsync();
await _gatewayService.StartAsync();
if (_gatewayService.HubConnection != null && _gatewayService.HubConnection.State == Microsoft.AspNetCore.SignalR.Client.HubConnectionState.Connected)
{ BeginInvoke(delegate () { Enabled = true; }); return; }
ConnectionClosed frmConnectionClosed = new ConnectionClosed(error);
var result = frmConnectionClosed.ShowDialog();
if (result == DialogResult.OK)
{
// tell the gateway service to attempt reconnection
Reconnect:
if (_gatewayService.HubConnection != null)
{
try
{
await _gatewayService.StopAsync();
await _gatewayService.StartAsync();
if (_gatewayService.HubConnection.State == Microsoft.AspNetCore.SignalR.Client.HubConnectionState.Connected)
BeginInvoke(delegate () { Enabled = true; });
}
catch (HttpRequestException ex)
{
// reshow the dialog
frmConnectionClosed.Reason = ex.Message;
var result1 = frmConnectionClosed.ShowDialog();
if (result1 == DialogResult.OK) goto Reconnect;
else Environment.Exit(0);
}
}
}
else Environment.Exit(0);
}
private void _gatewayService_OnServerReconnecting(object? sender, EventArgs e) => BeginInvoke(delegate () { Enabled = false; });
private void _gatewayService_OnServerReconnected(object? sender, EventArgs e) => BeginInvoke(delegate () { Enabled = true; });
private async void _gatewayService_OnServerConfigReceived(object? sender, EventArgs e)
{
var args = (ServerConfigEventArgs)e;
LoggingService.LogString($"Server Config Received");
LoggingService.LogModel(args.ServerConfig);
if (args.ServerConfig != null)
{
if (args.ServerConfig.IsDown)
{
LoggingService.LogString("Server Is Marked As Down");
MessageBox.Show($"Sorry, This Server Is Currently Down.\nMessage: {args.ServerConfig.IsDownMessage}\n\nPlease Try Again Later");
if (_gatewayService.HubConnection != null && _gatewayService.HubConnection.State == Microsoft.AspNetCore.SignalR.Client.HubConnectionState.Connected)
{
await _gatewayService.StopAsync();
await _gatewayService.DisposeAsync();
}
Environment.Exit(0);
}
}
}
private void _gatewayService_OnDirectMessageReceived(object? sender, EventArgs e)
{
var args = (DirectMessageEventArgs)e;
LoggingService.LogString($"Direct Message Received From '{args.User.Username}'");
DirectMessage? existingForm = (DirectMessage?)Application.OpenForms.Cast<Form>().FirstOrDefault(e => e.Name == "DirectMessage");
if (existingForm != null && existingForm.User.Id == args.User.Id)
{
// we want to just add to its text box
existingForm.Messages.Add($"[{args.User.Username}] {args.Message.Content}\n");
}
else
{
// start a new form
DirectMessage frmDirectMessage = new DirectMessage(_gatewayService, _apiService, args.User, args.Message);
Task.Run(frmDirectMessage.ShowDialog);
}
}
private async void _gatewayService_OnRefreshContactsListReceived(object? sender, EventArgs e) => await RefreshContactsList();
private async void _gatewayService_OnRefreshRoomListReceived(object? sender, EventArgs e) => await RefreshRoomsList();
private async void _gatewayService_OnRefreshUserListReceived(object? sender, EventArgs e) => await RefreshUsers();
}
}