diff --git a/Manager.App/Components/Dialogs/AccountDialog.razor b/Manager.App/Components/Dialogs/AccountDialog.razor
index 2a3d75f..e33353c 100644
--- a/Manager.App/Components/Dialogs/AccountDialog.razor
+++ b/Manager.App/Components/Dialogs/AccountDialog.razor
@@ -1,3 +1,5 @@
+@inject ISnackbar SnackbarService
+
@@ -14,11 +16,11 @@
Apply
}
-
-
+
+
-
+
Account id: |
@@ -28,6 +30,10 @@
Account name: |
@Client.AccountName |
+
+ Account handle: |
+ @Client.AccountHandle |
+
User agent: |
@Client.UserAgent |
@@ -51,6 +57,10 @@
+ @if (!string.IsNullOrWhiteSpace(Client.AccountImage))
+ {
+
+ }
@@ -84,14 +94,6 @@
-
-
-
-
-
-
-
-
diff --git a/Manager.App/Components/Dialogs/AccountDialog.razor.cs b/Manager.App/Components/Dialogs/AccountDialog.razor.cs
index 16c6f64..738eed3 100644
--- a/Manager.App/Components/Dialogs/AccountDialog.razor.cs
+++ b/Manager.App/Components/Dialogs/AccountDialog.razor.cs
@@ -29,17 +29,6 @@ namespace Manager.App.Components.Dialogs
Client.CookieContainer.Add(new Cookie { Name = "SET_NAME", Domain = ".youtube.com" });
}
- private async Task RemoveCookie(Cookie? cookie)
- {
- if (cookie == null)
- {
- return;
- }
-
- cookie.Expired = true;
- await InvokeAsync(StateHasChanged);
- }
-
private void ToggleCookieTextImport()
{
_showCookieTextImport =! _showCookieTextImport;
@@ -97,13 +86,27 @@ namespace Manager.App.Components.Dialogs
private bool CanSave()
{
- return Client.ClientState is { LoggedIn: true };
+ if (Client.ClientState == null)
+ {
+ return false;
+ }
+
+ if (string.IsNullOrWhiteSpace(Client.Id))
+ {
+ return false;
+ }
+
+ return Client.SapisidCookie != null && Client.ClientState.LoggedIn;
}
private async Task ValidateAccount()
{
_isLoading = true;
- await Client.BuildClientAsync();
+ var result = await Client.BuildClientAsync();
+ if (!result.IsSuccess)
+ {
+ SnackbarService.Add(result.Error?.Description ?? "Error validating account.", Severity.Error);
+ }
_isLoading = false;
}
diff --git a/Manager.YouTube/Models/AccountMenuInfo.cs b/Manager.YouTube/Models/AccountMenuInfo.cs
index 2e1306b..e0c474a 100644
--- a/Manager.YouTube/Models/AccountMenuInfo.cs
+++ b/Manager.YouTube/Models/AccountMenuInfo.cs
@@ -5,4 +5,6 @@ public class AccountMenuInfo
public string? AccountId { get; set; }
public string? AccountHandle { get; set; }
public string? ImageUrl { get; set; }
+ public int ImageWidth { get; set; }
+ public int ImageHeight { get; set; }
}
\ No newline at end of file
diff --git a/Manager.YouTube/NetworkService.cs b/Manager.YouTube/NetworkService.cs
index b3f4606..36a9ee9 100644
--- a/Manager.YouTube/NetworkService.cs
+++ b/Manager.YouTube/NetworkService.cs
@@ -128,16 +128,52 @@ public static class NetworkService
return ResultError.Fail("Unable to get http client!");
}
- var response = await http.SendAsync(httpRequest);
- if (!response.IsSuccessStatusCode)
+ try
{
- var responseResult = await response.Content.ReadAsStringAsync();
- return ResultError.Fail(responseResult);
+ var response = await http.SendAsync(httpRequest);
+ if (!response.IsSuccessStatusCode)
+ {
+ var responseResult = await response.Content.ReadAsStringAsync();
+ return ResultError.Fail(responseResult);
+ }
+
+ var json = await response.Content.ReadAsStringAsync();
+ var jsonDocument = JsonDocument.Parse(json);
+ var activeAccountHeader = jsonDocument.RootElement
+ .GetProperty("actions")[0]
+ .GetProperty("openPopupAction")
+ .GetProperty("popup")
+ .GetProperty("multiPageMenuRenderer")
+ .GetProperty("header")
+ .GetProperty("activeAccountHeaderRenderer");
+
+ var matRuns = activeAccountHeader
+ .GetProperty("manageAccountTitle")
+ .GetProperty("runs");
+
+ var accountPhotos = activeAccountHeader
+ .GetProperty("accountPhoto")
+ .GetProperty("thumbnails");
+
+ var accInfo = new AccountMenuInfo();
+
+ var highestImage = accountPhotos.EnumerateArray().OrderBy(x => x.GetProperty("width").Deserialize())
+ .FirstOrDefault();
+ accInfo.ImageUrl = highestImage.GetProperty("url").Deserialize();
+ accInfo.ImageWidth = highestImage.GetProperty("width").Deserialize();
+ accInfo.ImageHeight = highestImage.GetProperty("height").Deserialize();
+
+ foreach (var run in matRuns.EnumerateArray())
+ {
+ var browseEndpoint = run.GetProperty("navigationEndpoint").GetProperty("browseEndpoint");
+ accInfo.AccountId = browseEndpoint.GetProperty("browseId").GetString();
+ accInfo.AccountHandle = browseEndpoint.GetProperty("canonicalBaseUrl").GetString()?.Replace("/", "");
+ }
+ return accInfo;
+ }
+ catch (Exception e)
+ {
+ return ResultError.Error(e);
}
-
- var json = await response.Content.ReadAsStringAsync();
- var jsonObject = JsonNode.Parse(json);
-
- return ResultError.Fail("Not implemented");
}
}
\ No newline at end of file
diff --git a/Manager.YouTube/YouTubeClient.cs b/Manager.YouTube/YouTubeClient.cs
index a6e489a..c26e304 100644
--- a/Manager.YouTube/YouTubeClient.cs
+++ b/Manager.YouTube/YouTubeClient.cs
@@ -1,4 +1,5 @@
using System.Net;
+using DotBased.Monads;
using Manager.YouTube.Models.Innertube;
namespace Manager.YouTube;
@@ -7,8 +8,10 @@ public sealed class YouTubeClient : IDisposable
{
public string Id { get; private set; } = "";
public string AccountName => ClientState?.UserAccountName ?? "";
+ public string? AccountHandle { get; set; }
+ public string? AccountImage { get; set; }
public string? UserAgent { get; set; }
- public CookieContainer CookieContainer { get; } = new() { Capacity = 100, PerDomainCapacity = 50 };
+ public CookieContainer CookieContainer { get; } = new() { PerDomainCapacity = 50 };
public ClientState? ClientState { get; private set; }
public List DatasyncIds { get; set; } = [];
public Cookie? SapisidCookie => CookieContainer.GetAllCookies()["SAPISID"];
@@ -35,14 +38,14 @@ public sealed class YouTubeClient : IDisposable
_httpClient.DefaultRequestHeaders.Clear();
}
- public async Task BuildClientAsync()
+ public async Task BuildClientAsync()
{
if (ClientState == null || !ClientState.LoggedIn)
{
var state = await NetworkService.GetClientStateAsync(this);
if (!state.IsSuccess)
{
- return;
+ return state;
}
ClientState = state.Value;
}
@@ -52,7 +55,7 @@ public sealed class YouTubeClient : IDisposable
var datasyncResult = await NetworkService.GetDatasyncIds(this);
if (!datasyncResult.IsSuccess)
{
- return;
+ return datasyncResult;
}
foreach (var id in datasyncResult.Value)
@@ -63,7 +66,17 @@ public sealed class YouTubeClient : IDisposable
}
}
- var accountInfo = await NetworkService.GetCurrentAccountInfoAsync(this);
+ var accountInfoResult = await NetworkService.GetCurrentAccountInfoAsync(this);
+ if (!accountInfoResult.IsSuccess)
+ {
+ return accountInfoResult;
+ }
+
+ Id = accountInfoResult.Value.AccountId ?? "";
+ AccountHandle = accountInfoResult.Value.AccountHandle;
+ AccountImage = accountInfoResult.Value.ImageUrl;
+
+ return Result.Success();
}
public void Dispose()