Compare commits
No commits in common. "ui-updating-rework" and "master" have entirely different histories.
ui-updatin
...
master
1
qtc-net-client-2/Forms/Main.Designer.cs
generated
1
qtc-net-client-2/Forms/Main.Designer.cs
generated
@ -113,6 +113,7 @@
|
||||
tbcMain.SelectedIndex = 0;
|
||||
tbcMain.Size = new Size(352, 499);
|
||||
tbcMain.TabIndex = 0;
|
||||
tbcMain.SelectedIndexChanged += tbcMain_SelectedIndexChanged;
|
||||
//
|
||||
// tbpContacts
|
||||
//
|
||||
|
||||
@ -1,9 +1,7 @@
|
||||
using Microsoft.AspNetCore.Mvc.Routing;
|
||||
using Microsoft.VisualBasic.ApplicationServices;
|
||||
using qtc_net_client_2.ClientModel;
|
||||
using qtc_net_client_2.Controls;
|
||||
using qtc_net_client_2.Forms;
|
||||
using qtc_net_client_2.Properties;
|
||||
using qtc_net_client_2.Services;
|
||||
using QtCNETAPI.Dtos.User;
|
||||
using QtCNETAPI.Events;
|
||||
@ -22,7 +20,7 @@ namespace qtc_net_client_2
|
||||
private IGatewayService _gatewayService;
|
||||
|
||||
private Config _config;
|
||||
private ServerConfig? _serverConfig;
|
||||
private ServerConfig _serverConfig;
|
||||
private AudioService AudioService = new();
|
||||
private ImageFactory _imgFactory = new();
|
||||
private CredentialService _credService = new();
|
||||
@ -367,67 +365,27 @@ namespace qtc_net_client_2
|
||||
donationWindow.Show();
|
||||
}
|
||||
|
||||
private async Task RefreshStore()
|
||||
private async void tbcMain_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
// get store items
|
||||
var storeItems = await _apiService.GetStoreItems();
|
||||
if (storeItems != null && storeItems.Success && storeItems.Data != null)
|
||||
if (tbcMain.SelectedIndex == 4)
|
||||
{
|
||||
if (lvStoreItems.Items.Count == storeItems.Data.Count) return;
|
||||
|
||||
if (!IsHandleCreated || IsDisposed)
|
||||
return;
|
||||
|
||||
if (InvokeRequired)
|
||||
// get store items
|
||||
var storeItems = await _apiService.GetStoreItems();
|
||||
if (storeItems != null && storeItems.Success && storeItems.Data != null)
|
||||
{
|
||||
Invoke(() => ApplyStoreItems(storeItems.Data));
|
||||
}
|
||||
else
|
||||
{
|
||||
ApplyStoreItems(storeItems.Data);
|
||||
if (lvStoreItems.Items.Count == storeItems.Data.Count) return;
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async void ApplyStoreItems(IEnumerable<StoreItem> storeItems)
|
||||
{
|
||||
ilStoreThumbnails.Images.Clear();
|
||||
lvStoreItems.Items.Clear();
|
||||
|
||||
var items = await BuildListViewItemsAsync(storeItems);
|
||||
|
||||
lvStoreItems.BeginUpdate();
|
||||
try
|
||||
{
|
||||
lvStoreItems.Items.AddRange([.. items]);
|
||||
}
|
||||
finally
|
||||
{
|
||||
lvStoreItems.EndUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<List<ListViewItem>> BuildListViewItemsAsync(IEnumerable<StoreItem> storeItems)
|
||||
{
|
||||
var items = new List<ListViewItem>();
|
||||
|
||||
foreach (var item in storeItems)
|
||||
{
|
||||
await GetAndAddStoreThumbnail(item);
|
||||
|
||||
var lvItem = new ListViewItem
|
||||
{
|
||||
Text = item.Name,
|
||||
Name = item.Id.ToString(),
|
||||
ImageKey = item.Id.ToString()
|
||||
};
|
||||
|
||||
items.Add(lvItem);
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
private async void lvStoreItems_DoubleClick(object sender, EventArgs e)
|
||||
{
|
||||
if (lvStoreItems.SelectedItems.Count > 0)
|
||||
@ -663,8 +621,6 @@ namespace qtc_net_client_2
|
||||
llblEditProfile.Visible = true;
|
||||
tbcMain.Enabled = true;
|
||||
|
||||
await RefreshStore();
|
||||
|
||||
var pfpRes = await _apiService.GetUserProfilePic(_apiService.CurrentUser.Id);
|
||||
var cosmeticRes = await GetCosmeticImage(_apiService.CurrentUser.ActiveProfileCosmetic);
|
||||
|
||||
@ -691,6 +647,12 @@ namespace qtc_net_client_2
|
||||
pbUserPfp.Image = _imgFactory.CreateProfileImage(null, null, cosmetic);
|
||||
}
|
||||
|
||||
if (lvUserDirectory.Items.Count <= 0)
|
||||
await RefreshUsers(); // prevent edge case where the refresh event never gets sent to connecting client
|
||||
|
||||
await RefreshContactsList();
|
||||
await RefreshRoomsList();
|
||||
|
||||
// set status context menu checked
|
||||
// TODO - figure out more efficient way to do this
|
||||
UserStatus cuStatus = (UserStatus)_apiService.CurrentUser.Status;
|
||||
@ -771,200 +733,153 @@ namespace qtc_net_client_2
|
||||
}
|
||||
}
|
||||
|
||||
private readonly SemaphoreSlim _roomsRefreshLock = new(1, 1);
|
||||
private async Task RefreshRoomsList()
|
||||
{
|
||||
LoggingService.LogString("Refreshing Rooms List...");
|
||||
|
||||
if (IsHandleCreated && !IsDisposed)
|
||||
{
|
||||
if (!await _roomsRefreshLock.WaitAsync(0))
|
||||
return;
|
||||
|
||||
try
|
||||
await Invoke(async delegate ()
|
||||
{
|
||||
flpRooms.Controls.Clear();
|
||||
|
||||
// always add lobby room to rooms list
|
||||
var lobbyCtrl = new RoomEntryControl
|
||||
{
|
||||
RoomName = "Lobby",
|
||||
HideUserCount = true,
|
||||
BackColor = flpRooms.BackColor
|
||||
};
|
||||
|
||||
lobbyCtrl.Margin = new Padding(0, 4, 0, 4);
|
||||
lobbyCtrl.Width = flpRooms.ClientSize.Width - flpRooms.Padding.Horizontal;
|
||||
lobbyCtrl.OnRoomDoubleClicked += OnRoomDoubleClicked;
|
||||
|
||||
flpRooms.Controls.Add(lobbyCtrl);
|
||||
|
||||
var roomsRes = await _apiService.GetAllRoomsAsync();
|
||||
|
||||
if (!roomsRes.Success || roomsRes.Data == null)
|
||||
return;
|
||||
|
||||
roomsRes.Data.Add(new Room
|
||||
if (roomsRes.Success && roomsRes.Data != null)
|
||||
{
|
||||
Id = "LOBBY",
|
||||
Name = "Lobby"
|
||||
});
|
||||
foreach (var room in roomsRes.Data)
|
||||
{
|
||||
// create room entry
|
||||
var ctrl = new RoomEntryControl
|
||||
{
|
||||
RoomName = room.Name,
|
||||
RoomUserCount = room.UserCount, // placeholder
|
||||
BackColor = flpRooms.BackColor
|
||||
};
|
||||
|
||||
var uniqueRooms = roomsRes.Data
|
||||
.GroupBy(r => r.Id)
|
||||
.Select(g => g.First())
|
||||
.ToList();
|
||||
ctrl.Margin = new Padding(0, 4, 0, 4);
|
||||
ctrl.Width = flpRooms.ClientSize.Width - flpRooms.Padding.Horizontal;
|
||||
ctrl.OnRoomDoubleClicked += OnRoomDoubleClicked;
|
||||
|
||||
if (InvokeRequired)
|
||||
{
|
||||
Invoke(() => ApplyRooms(uniqueRooms));
|
||||
flpRooms.Controls.Add(ctrl);
|
||||
}
|
||||
RoomList = roomsRes.Data;
|
||||
if (System.Diagnostics.Debugger.IsAttached || _config.EnableDebugLogs)
|
||||
LoggingService.LogModel(roomsRes.Data);
|
||||
}
|
||||
else
|
||||
{
|
||||
ApplyRooms(uniqueRooms);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_roomsRefreshLock.Release();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void ApplyRooms(List<Room> newRooms)
|
||||
{
|
||||
RoomList.Clear();
|
||||
RoomList.AddRange(newRooms.DistinctBy(r => r.Id));
|
||||
|
||||
var roomsSnap = RoomList.ToList();
|
||||
|
||||
flpRooms.SuspendLayout();
|
||||
flpRooms.Controls.Clear();
|
||||
|
||||
foreach (var room in roomsSnap)
|
||||
{
|
||||
var ctrl = new RoomEntryControl
|
||||
{
|
||||
RoomName = room.Name,
|
||||
RoomUserCount = room.UserCount,
|
||||
};
|
||||
|
||||
if(room.Id == "LOBBY")
|
||||
ctrl.HideUserCount = true; // TODO - probably make this work with the lobby room (might need backend work)
|
||||
|
||||
ctrl.Margin = new Padding(0, 4, 0, 4);
|
||||
ctrl.Width = flpRooms.ClientSize.Width - flpRooms.Padding.Horizontal;
|
||||
ctrl.OnRoomDoubleClicked += OnRoomDoubleClicked;
|
||||
|
||||
flpRooms.Controls.Add(ctrl);
|
||||
}
|
||||
|
||||
flpRooms.ResumeLayout(true);
|
||||
}
|
||||
|
||||
private readonly SemaphoreSlim _contactsRefreshLock = new(1, 1);
|
||||
private async Task RefreshContactsList()
|
||||
{
|
||||
if (!await _contactsRefreshLock.WaitAsync(0))
|
||||
return; // already refreshing, skip
|
||||
LoggingService.LogString("Refreshing Contacts List...");
|
||||
|
||||
try
|
||||
if (IsHandleCreated && !IsDisposed)
|
||||
{
|
||||
var contactsRes = await _apiService.GetCurrentUserContacts();
|
||||
if (!contactsRes.Success || contactsRes.Data == null)
|
||||
return;
|
||||
|
||||
if (InvokeRequired)
|
||||
Invoke(() => ApplyContacts(contactsRes.Data));
|
||||
else
|
||||
ApplyContacts(contactsRes.Data);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_contactsRefreshLock.Release();
|
||||
}
|
||||
}
|
||||
|
||||
private async void ApplyContacts(List<Contact> newContacts)
|
||||
{
|
||||
lblRequestNotif.Visible =
|
||||
newContacts.Any(e =>
|
||||
e.UserId == _apiService.CurrentUser!.Id &&
|
||||
e.UserStatus == Contact.ContactStatus.AwaitingApprovalFromSelf);
|
||||
|
||||
Contacts.Clear();
|
||||
Contacts.AddRange(newContacts.DistinctBy(c => c.Id));
|
||||
|
||||
flpContacts.SuspendLayout();
|
||||
flpContacts.Controls.Clear();
|
||||
|
||||
var contactsSnap = Contacts.ToList();
|
||||
|
||||
foreach (var contact in contactsSnap)
|
||||
{
|
||||
var ctrl = await BuildContactControl(contact);
|
||||
if (ctrl != null)
|
||||
flpContacts.Controls.Add(ctrl);
|
||||
}
|
||||
|
||||
flpContacts.ResumeLayout(true);
|
||||
}
|
||||
|
||||
private async Task<ContactEntryControl?> BuildContactControl(Contact contact)
|
||||
{
|
||||
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);
|
||||
|
||||
var ctrl = new ContactEntryControl();
|
||||
|
||||
if (user.Data != null)
|
||||
{
|
||||
switch (user.Data.Status)
|
||||
await Invoke(async delegate ()
|
||||
{
|
||||
case 0:
|
||||
ctrl.StatusColor = Color.Gray;
|
||||
break;
|
||||
case 1:
|
||||
ctrl.StatusColor = Color.LightGreen;
|
||||
break;
|
||||
case 2:
|
||||
ctrl.StatusColor = Color.Gold;
|
||||
break;
|
||||
case 3:
|
||||
ctrl.StatusColor = Color.Red;
|
||||
break;
|
||||
}
|
||||
|
||||
if (contact.OwnerId == _apiService.CurrentUser!.Id)
|
||||
{
|
||||
switch (contact.OwnerStatus)
|
||||
Contacts.Clear();
|
||||
flpContacts.Controls.Clear();
|
||||
lblRequestNotif.Visible = false;
|
||||
var contactsRes = await _apiService.GetCurrentUserContacts();
|
||||
if (contactsRes.Success && contactsRes.Data != null)
|
||||
{
|
||||
case Contact.ContactStatus.AwaitingApprovalFromOther:
|
||||
ctrl.Username = $"{user.Data.Username} [Request Sent]";
|
||||
await AddProfilePicToList(user.Data.Id);
|
||||
ctrl.Avatar = ilProfilePics.Images[user.Data.Id] ?? ilProfilePics.Images[0];
|
||||
break;
|
||||
case Contact.ContactStatus.Accepted:
|
||||
ctrl.Username = user.Data.Username;
|
||||
await AddProfilePicToList(user.Data.Id);
|
||||
ctrl.Avatar = ilProfilePics.Images[user.Data.Id] ?? ilProfilePics.Images[0];
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (contact.UserId == _apiService.CurrentUser!.Id)
|
||||
{
|
||||
switch (contact.UserStatus)
|
||||
{
|
||||
case Contact.ContactStatus.AwaitingApprovalFromSelf:
|
||||
ctrl.Username = $"{user.Data.Username} [Contact Request]";
|
||||
await AddProfilePicToList(user.Data.Id);
|
||||
ctrl.Avatar = ilProfilePics.Images[user.Data.Id] ?? ilProfilePics.Images[0];
|
||||
AudioService.PlaySoundEffect("sndContactRequest");
|
||||
break;
|
||||
case Contact.ContactStatus.Accepted:
|
||||
ctrl.Username = user.Data.Username;
|
||||
await AddProfilePicToList(user.Data.Id);
|
||||
ctrl.Avatar = ilProfilePics.Images[user.Data.Id] ?? ilProfilePics.Images[0];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (contactsRes.Data.Where(e => e.UserId == _apiService.CurrentUser!.Id && e.UserStatus == Contact.ContactStatus.AwaitingApprovalFromSelf).Count() >= 1)
|
||||
lblRequestNotif.Visible = true;
|
||||
else
|
||||
lblRequestNotif.Visible = false;
|
||||
|
||||
// add the control to the flow panel
|
||||
ctrl.Margin = new Padding(0, 4, 0, 4);
|
||||
ctrl.Width = flpContacts.ClientSize.Width - flpContacts.Padding.Horizontal;
|
||||
ctrl.ContactDoubleClicked += Ctrl_ContactDoubleClicked;
|
||||
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);
|
||||
|
||||
// return the control
|
||||
return ctrl;
|
||||
var ctrl = new ContactEntryControl();
|
||||
|
||||
if (user.Data != null)
|
||||
{
|
||||
Contacts.Add(contact);
|
||||
|
||||
switch(user.Data.Status)
|
||||
{
|
||||
case 0:
|
||||
ctrl.StatusColor = Color.Gray;
|
||||
break;
|
||||
case 1:
|
||||
ctrl.StatusColor = Color.LightGreen;
|
||||
break;
|
||||
case 2:
|
||||
ctrl.StatusColor = Color.Gold;
|
||||
break;
|
||||
case 3:
|
||||
ctrl.StatusColor = Color.Red;
|
||||
break;
|
||||
}
|
||||
|
||||
if (contact.OwnerId == _apiService.CurrentUser!.Id)
|
||||
{
|
||||
switch (contact.OwnerStatus)
|
||||
{
|
||||
case Contact.ContactStatus.AwaitingApprovalFromOther:
|
||||
ctrl.Username = $"{user.Data.Username} [Request Sent]";
|
||||
await AddProfilePicToList(user.Data.Id);
|
||||
ctrl.Avatar = ilProfilePics.Images[user.Data.Id] ?? ilProfilePics.Images[0];
|
||||
break;
|
||||
case Contact.ContactStatus.Accepted:
|
||||
ctrl.Username = user.Data.Username;
|
||||
await AddProfilePicToList(user.Data.Id);
|
||||
ctrl.Avatar = ilProfilePics.Images[user.Data.Id] ?? ilProfilePics.Images[0];
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (contact.UserId == _apiService.CurrentUser!.Id)
|
||||
{
|
||||
switch (contact.UserStatus)
|
||||
{
|
||||
case Contact.ContactStatus.AwaitingApprovalFromSelf:
|
||||
ctrl.Username = $"{user.Data.Username} [Contact Request]";
|
||||
await AddProfilePicToList(user.Data.Id);
|
||||
ctrl.Avatar = ilProfilePics.Images[user.Data.Id] ?? ilProfilePics.Images[0];
|
||||
AudioService.PlaySoundEffect("sndContactRequest");
|
||||
break;
|
||||
case Contact.ContactStatus.Accepted:
|
||||
ctrl.Username = user.Data.Username;
|
||||
await AddProfilePicToList(user.Data.Id);
|
||||
ctrl.Avatar = ilProfilePics.Images[user.Data.Id] ?? ilProfilePics.Images[0];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// add the control to the flow panel
|
||||
ctrl.Margin = new Padding(0, 4, 0, 4);
|
||||
ctrl.Width = flpContacts.ClientSize.Width - flpContacts.Padding.Horizontal;
|
||||
ctrl.ContactDoubleClicked += Ctrl_ContactDoubleClicked;
|
||||
flpContacts.Controls.Add(ctrl);
|
||||
}
|
||||
}
|
||||
|
||||
if (System.Diagnostics.Debugger.IsAttached || _config.EnableDebugLogs)
|
||||
LoggingService.LogModel(contactsRes.Data);
|
||||
}
|
||||
});
|
||||
}
|
||||
else return default;
|
||||
}
|
||||
|
||||
private async void Ctrl_ContactDoubleClicked(object? sender, EventArgs e)
|
||||
|
||||
@ -81,7 +81,7 @@ namespace qtc_net_client_2.Properties {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to 6.5.6.
|
||||
/// Looks up a localized string similar to 6.5.5.
|
||||
/// </summary>
|
||||
internal static string AssemblyVersion {
|
||||
get {
|
||||
|
||||
@ -173,7 +173,7 @@
|
||||
<value>..\Icons\MessageIcon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="AssemblyVersion" xml:space="preserve">
|
||||
<value>6.5.6</value>
|
||||
<value>6.5.5</value>
|
||||
</data>
|
||||
<data name="cobalt_sittingatputer" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\cobalt_sittingatputer.jpg;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
|
||||
@ -19,24 +19,15 @@ namespace qtc_net_client_2.Services
|
||||
if (Debugger.IsAttached) return;
|
||||
|
||||
// get client update info
|
||||
HttpClient client = new()
|
||||
{
|
||||
BaseAddress = new Uri("https://qtcclient.alanmoon.net")
|
||||
};
|
||||
|
||||
HttpClient client = new();
|
||||
client.BaseAddress = new Uri("https://qtcclient.alanmoon.net");
|
||||
|
||||
try
|
||||
{
|
||||
ClientUpdateInfo? updateInfo = await client.GetFromJsonAsync<ClientUpdateInfo>("clientinfo.json");
|
||||
if (updateInfo != null)
|
||||
{
|
||||
var serverVersion = Version.Parse(updateInfo.Version);
|
||||
var clientVersion = Version.Parse(Resources.AssemblyVersion);
|
||||
|
||||
int relativeComparison = clientVersion.CompareTo(serverVersion);
|
||||
|
||||
if (relativeComparison > 0) return; // probably a version being developed or tested without a debugger, so don't do anything
|
||||
|
||||
if (relativeComparison < 0)
|
||||
if (updateInfo.Version != Resources.AssemblyVersion)
|
||||
{
|
||||
// inform the user an update is available
|
||||
if (!updateInfo.IsUpdateMandatory)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user