Commit 9fa6f827 authored by Yousef Sameh's avatar Yousef Sameh

better auth error messages & leaderboard always include current player

parent cbf5e7b9
...@@ -11,16 +11,18 @@ public class LeaderboardService ...@@ -11,16 +11,18 @@ public class LeaderboardService
private Client supabase => SupabaseManager.Instance.Supabase(); private Client supabase => SupabaseManager.Instance.Supabase();
public async UniTask<OneOf<List<LeaderboardPlayerModel>, string>> LoadTop100Players() public async UniTask<OneOf<List<LeaderboardPlayerModel>, string>> LoadTop100PlayersAndCurrentPlayer()
{ {
var currentUserId = UserService.Instance.CurrentUser?.Id;
if (string.IsNullOrEmpty(currentUserId))
return new List<LeaderboardPlayerModel>();
try try
{ {
// Queries the 'leaderboard' view directly
var response = await supabase var response = await supabase
.From<LeaderboardPlayerModel>() .Rpc<List<LeaderboardPlayerModel>>("get_leaderboard_with_user", new { target_user_id = currentUserId });
.Get();
return response.Models; return response;
} }
catch (Exception e) catch (Exception e)
{ {
......
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading; // Required for CancellationTokenSource using System.Threading;
using Cysharp.Threading.Tasks; using Cysharp.Threading.Tasks;
using UnityEngine; using UnityEngine;
using UnityEngine.UIElements; using UnityEngine.UIElements;
...@@ -12,17 +12,16 @@ public class LeaderboardController : MonoBehaviour, IDisposable ...@@ -12,17 +12,16 @@ public class LeaderboardController : MonoBehaviour, IDisposable
private VisualElement allPlayersContainer; private VisualElement allPlayersContainer;
private VisualElement root; private VisualElement root;
// Stores the active cancellation token
private CancellationTokenSource _loadCts; private CancellationTokenSource _loadCts;
public int CurrentPlayerSlotIndex { get; private set; } = -1;
void Start() void Start()
{ {
root = leaderboardDocument.rootVisualElement; root = leaderboardDocument.rootVisualElement;
allPlayersContainer = root.Q<VisualElement>("AllPlayerContainer"); allPlayersContainer = root.Q<VisualElement>("AllPlayerContainer");
// Fixed Event Subscription: Use a named method to avoid memory leaks!
UserService.Instance.OnUserChanged += OnUserChanged; UserService.Instance.OnUserChanged += OnUserChanged;
LoadLeaderboard().Forget(); LoadLeaderboard().Forget();
} }
...@@ -52,31 +51,34 @@ public class LeaderboardController : MonoBehaviour, IDisposable ...@@ -52,31 +51,34 @@ public class LeaderboardController : MonoBehaviour, IDisposable
try try
{ {
// Note: If you can edit LeaderboardService, update LoadTop100Players() var result = await LeaderboardService.Instance.LoadTop100PlayersAndCurrentPlayer();
// to accept this CancellationToken to cancel the actual web request!
// Example: await LeaderboardService.Instance.LoadTop100Players(token);
var result = await LeaderboardService.Instance.LoadTop100Players();
// 3. Check if a newer request cancelled this one while we were waiting
if (token.IsCancellationRequested) if (token.IsCancellationRequested)
return; return;
result.Switch( result.Switch(
(List<LeaderboardPlayerModel> players) => (List<LeaderboardPlayerModel> players) =>
{ {
CurrentPlayerSlotIndex = -1;
for (int i = 0; i < players.Count; i++) for (int i = 0; i < players.Count; i++)
{ {
if (i < 3) if (i < 3)
ApplyTopThree(i, players[i]); ApplyTopThree(i, players[i]);
var player = players[i]; var player = players[i];
var isOwner = player.Id == UserService.Instance.CurrentUser?.Id;
if (isOwner)
CurrentPlayerSlotIndex = i;
var entry = new CustomLeaderboardSlot var entry = new CustomLeaderboardSlot
{ {
PlayerName = player.UserName, PlayerName = player.UserName,
Rank = player.Rank, Rank = player.Rank,
XP = player.Points.ToString(), XP = player.Points.ToString(),
Index = player.Position.ToString(), Index = player.Position.ToString(),
IsOwner = player.Id == UserService.Instance.CurrentUser?.Id IsOwner = isOwner
}; };
allPlayersContainer.Add(entry); allPlayersContainer.Add(entry);
...@@ -124,13 +126,11 @@ public class LeaderboardController : MonoBehaviour, IDisposable ...@@ -124,13 +126,11 @@ public class LeaderboardController : MonoBehaviour, IDisposable
public void Dispose() public void Dispose()
{ {
// Now safely removes the event listener
if (UserService.Instance != null) if (UserService.Instance != null)
{ {
UserService.Instance.OnUserChanged -= OnUserChanged; UserService.Instance.OnUserChanged -= OnUserChanged;
} }
// Cancel any pending load when this object is destroyed/disposed
if (_loadCts != null) if (_loadCts != null)
{ {
_loadCts.Cancel(); _loadCts.Cancel();
...@@ -139,7 +139,6 @@ public class LeaderboardController : MonoBehaviour, IDisposable ...@@ -139,7 +139,6 @@ public class LeaderboardController : MonoBehaviour, IDisposable
} }
} }
// Good practice in Unity to ensure Dispose runs if the GameObject is destroyed
private void OnDestroy() private void OnDestroy()
{ {
Dispose(); Dispose();
......
...@@ -3,13 +3,7 @@ using System; ...@@ -3,13 +3,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;
using UnityEngine.UIElements; using UnityEngine.UIElements;
[Serializable]
public class SupabaseError
{
public int code;
public string error_code;
public string msg;
}
public class LoginPageAnimation : MonoBehaviour public class LoginPageAnimation : MonoBehaviour
{ {
[SerializeField] UIDocument loginPage; [SerializeField] UIDocument loginPage;
...@@ -24,6 +18,8 @@ public class LoginPageAnimation : MonoBehaviour ...@@ -24,6 +18,8 @@ public class LoginPageAnimation : MonoBehaviour
PlayerPrefs.SetInt("IsGuest", 0); PlayerPrefs.SetInt("IsGuest", 0);
SupabaseAuthentication.Instance.UseArabicErrors = true;
if (Application.internetReachability == NetworkReachability.NotReachable) if (Application.internetReachability == NetworkReachability.NotReachable)
{ {
ShowUIMessage.Instance.ShowMessage("يرجي الأتصال بالإنترنت وأعد المحاولة", true); ShowUIMessage.Instance.ShowMessage("يرجي الأتصال بالإنترنت وأعد المحاولة", true);
...@@ -162,7 +158,7 @@ public class LoginPageAnimation : MonoBehaviour ...@@ -162,7 +158,7 @@ public class LoginPageAnimation : MonoBehaviour
}, },
error => error =>
{ {
ShowUIMessage.Instance.ShowMessage("فشل تسجيل الدخول، يرجى التحقق من البريد الإلكتروني وكلمة المرور"); ShowUIMessage.Instance.ShowMessage(error);
loginButton.SetEnabled(true); loginButton.SetEnabled(true);
loginButton.text = "تسجيل الدخول"; loginButton.text = "تسجيل الدخول";
} }
...@@ -281,10 +277,8 @@ public class LoginPageAnimation : MonoBehaviour ...@@ -281,10 +277,8 @@ public class LoginPageAnimation : MonoBehaviour
}, },
error => error =>
{ {
// debug error code and message
Debug.LogError($"ConvertGuestToEmail error: {error}"); Debug.LogError($"ConvertGuestToEmail error: {error}");
ShowUIMessage.Instance.ShowMessage(error);
ShowUIMessage.Instance.ShowMessage("فشل إنشاء الحساب، يرجى المحاولة مرة أخرى");
registerButton.SetEnabled(true); registerButton.SetEnabled(true);
registerButton.text = "تسجيل"; registerButton.text = "تسجيل";
} }
...@@ -313,19 +307,7 @@ public class LoginPageAnimation : MonoBehaviour ...@@ -313,19 +307,7 @@ public class LoginPageAnimation : MonoBehaviour
}, },
error => error =>
{ {
var json = error.ToString(); ShowUIMessage.Instance.ShowMessage(error);
var parsed = JsonUtility.FromJson<SupabaseError>(json);
if (parsed.code == 422)
{
ShowUIMessage.Instance.ShowMessage("الحساب مسجل بالفعل، يرجى تسجيل الدخول");
}
else
{
ShowUIMessage.Instance.ShowMessage("فشل إنشاء الحساب، يرجى المحاولة مرة أخرى");
}
registerButton.SetEnabled(true); registerButton.SetEnabled(true);
registerButton.text = "تسجيل"; registerButton.text = "تسجيل";
} }
...@@ -397,7 +379,7 @@ public class LoginPageAnimation : MonoBehaviour ...@@ -397,7 +379,7 @@ public class LoginPageAnimation : MonoBehaviour
error => error =>
{ {
Debug.LogError("Registration error: " + error); Debug.LogError("Registration error: " + error);
ShowUIMessage.Instance.ShowMessage("فشل إنشاء الحساب، يرجى المحاولة مرة أخرى"); ShowUIMessage.Instance.ShowMessage(error);
registerButton.SetEnabled(true); registerButton.SetEnabled(true);
registerButton.text = "تسجيل"; registerButton.text = "تسجيل";
} }
...@@ -466,15 +448,17 @@ public class LoginPageAnimation : MonoBehaviour ...@@ -466,15 +448,17 @@ public class LoginPageAnimation : MonoBehaviour
sendEmail.SetEnabled(false); sendEmail.SetEnabled(false);
closeForgetPasswordPanel.SetEnabled(false); closeForgetPasswordPanel.SetEnabled(false);
try var result = await SupabaseAuthentication.Instance.ResetPasswordRequest(forgetPasswordEmailField.text);
result.Switch(
success =>
{ {
await SupabaseAuthentication.Instance.ResetPasswordRequest(forgetPasswordEmailField.text);
ShowUIMessage.Instance.ShowMessage("تم إرسال بريد إعادة تعيين كلمة المرور، يرجى التحقق من بريدك الإلكتروني"); ShowUIMessage.Instance.ShowMessage("تم إرسال بريد إعادة تعيين كلمة المرور، يرجى التحقق من بريدك الإلكتروني");
} },
catch (Exception ex) error =>
{ {
Debug.LogException(ex); ShowUIMessage.Instance.ShowMessage(error);
} }
);
sendEmail.SetEnabled(true); sendEmail.SetEnabled(true);
closeForgetPasswordPanel.SetEnabled(true); closeForgetPasswordPanel.SetEnabled(true);
...@@ -523,15 +507,17 @@ public class LoginPageAnimation : MonoBehaviour ...@@ -523,15 +507,17 @@ public class LoginPageAnimation : MonoBehaviour
updatePassword.SetEnabled(false); updatePassword.SetEnabled(false);
try var result = await SupabaseAuthentication.Instance.UpdatePassword(newPasswordField.text);
result.Switch(
success =>
{ {
await SupabaseAuthentication.Instance.UpdatePassword(newPasswordField.text);
ShowUIMessage.Instance.ShowMessage("تم تحديث كلمة المرور بنجاح، يرجى تسجيل الدخول مرة أخرى"); ShowUIMessage.Instance.ShowMessage("تم تحديث كلمة المرور بنجاح، يرجى تسجيل الدخول مرة أخرى");
} },
catch (Exception ex) error =>
{ {
Debug.LogException(ex); ShowUIMessage.Instance.ShowMessage(error);
} }
);
updatePassword.SetEnabled(true); updatePassword.SetEnabled(true);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment