Reimplement Status Indicator and Cosmetics

This commit is contained in:
Alan Moon 2025-12-10 14:25:45 -08:00
parent 9b350d4373
commit a0e83ad4df
9 changed files with 152 additions and 29 deletions

View File

@ -0,0 +1,90 @@
using QtCNETAPI.Models;
using QtCNETAPI.Services.ApiService;
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing.Drawing2D;
using Microsoft.Extensions.FileProviders;
using qtcnet_client.Properties;
namespace qtcnet_client.Factories
{
public class ImageFactory
{
private readonly IApiService _apiService;
public ImageFactory(IApiService apiService)
{
_apiService = apiService;
}
public async Task<Bitmap> GetAndCreateProfileImage(string userId, int status, int cosmeticStoreId = 0)
{
Bitmap combined = new(139, 138);
Image img1 = Resources.DefaultPfp;
Bitmap? img2 = null;
Bitmap img3 = Resources.OfflineIcon;
// get user profile image
var _pfpRes = await _apiService.GetUserProfilePic(userId);
if (_pfpRes.Success && _pfpRes.Data != null)
{
using var ms = new MemoryStream(_pfpRes.Data);
img1 = Image.FromStream(ms);
}
// get cosmetic image
if(cosmeticStoreId >= 0)
{
var _storeRes = await _apiService.GetStoreItem(cosmeticStoreId);
if(_storeRes.Success && _storeRes.Data != null)
{
using var _http = new HttpClient();
using var _httpRes = await _http.GetAsync(_storeRes.Data.AssetUrl);
if (_httpRes.IsSuccessStatusCode)
{
var _imgByes = await _httpRes.Content.ReadAsByteArrayAsync();
using var ms = new MemoryStream(_imgByes);
img2 = (Bitmap?)Image.FromStream(ms);
}
}
}
// set status image
switch(status)
{
case 0:
img3 = Resources.OfflineIcon;
break;
case 1:
img3 = Resources.OnlineIcon;
break;
case 2:
img3 = Resources.AwayIcon;
break;
case 3:
img3 = Resources.DNDIcon;
break;
}
// finally, combine the images
Graphics g = Graphics.FromImage(combined);
g.Clear(Color.Transparent);
g.CompositingMode = CompositingMode.SourceOver;
g.DrawImage(img1, 4, 6, 128, 128);
if (img2 != null)
{
img2.MakeTransparent();
g.DrawImage(img2, 0, 0, 139, 138);
}
img3.MakeTransparent();
g.DrawImage(img3, 104, 0, 35, 35);
return combined;
}
}
}

View File

@ -2,6 +2,7 @@ using Krypton.Toolkit;
using Microsoft.AspNetCore.Mvc.Routing;
using Microsoft.VisualBasic.ApplicationServices;
using qtcnet_client.Controls;
using qtcnet_client.Factories;
using qtcnet_client.Forms;
using qtcnet_client.Model;
using qtcnet_client.Properties;
@ -37,14 +38,16 @@ namespace qtcnet_client
private readonly LoggingService _loggingService;
private readonly CredentialService _credentialService;
private readonly ClientConfig _config;
private readonly ImageFactory _imgFactory;
public MainForm(IApiService apiService, IGatewayService gatewayService, LoggingService loggingService, CredentialService credentialService, ClientConfig config)
public MainForm(IApiService apiService, IGatewayService gatewayService, LoggingService loggingService, CredentialService credentialService, ClientConfig config, ImageFactory imageFactory)
{
_apiService = apiService;
_gatewayService = gatewayService;
_loggingService = loggingService;
_credentialService = credentialService;
_config = config;
_imgFactory = imageFactory;
// sub to currentuser updates
_apiService.OnCurrentUserUpdate += _apiService_OnCurrentUserUpdate;
@ -314,13 +317,7 @@ namespace qtcnet_client
_profile.ContactStatus = Contact.ContactStatus.NoRelation;
// get profile image
var _pfpBytes = await _apiService.GetUserProfilePic(_contactCtrl.UserId);
if (_pfpBytes.Success && _pfpBytes.Data != null)
{
using var ms = new MemoryStream(_pfpBytes.Data);
Image img = Image.FromStream(ms);
_profile.ProfileImage = img;
}
_profile.ProfileImage = await _imgFactory.GetAndCreateProfileImage(_user.Data.Id, _user.Data.Status, _user.Data.ProfileCosmeticId);
_profile.OnClose += ProfileForm_OnClose;
@ -365,13 +362,7 @@ namespace qtcnet_client
_profile.ContactStatus = Contact.ContactStatus.NoRelation;
// get profile image
var _pfpBytes = await _apiService.GetUserProfilePic(_tagString);
if(_pfpBytes.Success && _pfpBytes.Data != null)
{
using var ms = new MemoryStream(_pfpBytes.Data);
Image img = Image.FromStream(ms);
_profile.ProfileImage = img;
}
_profile.ProfileImage = await _imgFactory.GetAndCreateProfileImage(_user.Data.Id, _user.Data.Status, _user.Data.ProfileCosmeticId);
_profile.OnClose += ProfileForm_OnClose;
@ -900,13 +891,7 @@ namespace qtcnet_client
}
// get profile image
var _pfpRes = await _apiService.GetUserProfilePic(contact.UserId);
if(_pfpRes.Success && _pfpRes.Data != null)
{
using var ms = new MemoryStream(_pfpRes.Data);
Image img = Image.FromStream(ms);
ctrl.ProfilePic = img;
}
ctrl.ProfilePic = await _imgFactory.GetAndCreateProfileImage(user.Data.Id, user.Data.Status, user.Data.ProfileCosmeticId);
}
else if (contact.UserId == _apiService.CurrentUser.Id)
{
@ -922,13 +907,7 @@ namespace qtcnet_client
}
// get profile image
var _pfpRes = await _apiService.GetUserProfilePic(contact.OwnerId);
if (_pfpRes.Success && _pfpRes.Data != null)
{
using var ms = new MemoryStream(_pfpRes.Data);
Image img = Image.FromStream(ms);
ctrl.ProfilePic = img;
}
ctrl.ProfilePic = await _imgFactory.GetAndCreateProfileImage(user.Data.Id, user.Data.Status, user.Data.ProfileCosmeticId);
}
// return the control

View File

@ -1,6 +1,7 @@
using Krypton.Toolkit;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using qtcnet_client.Factories;
using qtcnet_client.Model;
using QtCNETAPI.Services;
using QtCNETAPI.Services.ApiService;
@ -37,6 +38,7 @@ namespace qtcnet_client
service.AddTransient<MainForm>();
service.AddSingleton<LoggingService>();
service.AddSingleton<CredentialService>();
service.AddSingleton<ImageFactory>();
service.AddSingleton(provider => GetOrCreateClientConfig());
service.AddSingleton<IApiService>(provider => new ApiService(provider.GetService<ClientConfig>()!.ServerBaseUri + "/api", provider.GetService<LoggingService>()!, provider.GetService<CredentialService>()!));
service.AddSingleton<IGatewayService>(provider => new GatewayService(provider.GetService<ClientConfig>()!.ServerBaseUri + "/chat", provider.GetService<IApiService>()!, provider.GetService<LoggingService>()!));

View File

@ -80,6 +80,16 @@ namespace qtcnet_client.Properties {
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap AwayIcon {
get {
object obj = ResourceManager.GetObject("AwayIcon", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
@ -120,6 +130,16 @@ namespace qtcnet_client.Properties {
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap DNDIcon {
get {
object obj = ResourceManager.GetObject("DNDIcon", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
@ -130,6 +150,26 @@ namespace qtcnet_client.Properties {
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap OfflineIcon {
get {
object obj = ResourceManager.GetObject("OfflineIcon", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap OnlineIcon {
get {
object obj = ResourceManager.GetObject("OnlineIcon", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>

View File

@ -154,4 +154,16 @@
<data name="DeclineContactIcon" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\DeclineContactIcon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="OfflineIcon" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\OfflineIcon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="OnlineIcon" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\OnlineIcon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="AwayIcon" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\AwayIcon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="DNDIcon" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\DNDIcon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
</root>

Binary file not shown.

After

Width:  |  Height:  |  Size: 587 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 602 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 670 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 603 B