/**
* Copyright 2019 The Knights Of Unity, created by Pawel Stolarczyk
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using DemoGame.Scripts.Clans;
using DemoGame.Scripts.DataStorage;
using DemoGame.Scripts.Friends;
using DemoGame.Scripts.Gameplay.Cards;
using DemoGame.Scripts.Gameplay.Decks;
using DemoGame.Scripts.Session;
using Nakama;
using UnityEngine;
using UnityEngine.UI;
namespace DemoGame.Scripts.Profile
{
///
/// Panel displaying user's stats.
///
public class ProfilePanel : MonoBehaviour
{
#region Fields
#region UI
///
/// Button sending friend request to currently shown user.
///
[SerializeField] private Button _befriendButton = null;
///
/// Textbox containing displayed user's username.
///
[SerializeField] private Text _usernameText = null;
///
/// Textbox containing displayed user's clan name.
///
[SerializeField] private Text _clanNameText = null;
///
/// List of card slots dipslaying user's deck.
///
[SerializeField] private List _cardSlots = null;
///
/// Textbox containing displayed user's stats gathered using .
///
[SerializeField] private Text _statsText = null;
///
/// Image showing displayed user's avatar.
///
[SerializeField] private Image _avatarImage = null;
///
/// Shows .
///
[SerializeField] private Button _profileUpdateButton = null;
#endregion
///
/// Used to store and retrieve used to populate this panel.
///
[SerializeField] private PlayerDataStorage _playerDataStorage = null;
///
/// Used to store and retrieve used to populste this panel.
///
[SerializeField] private DeckStorage _deckStorage = null;
#endregion
#region Mono
///
/// Adds a listener to and hides this panel.
///
private void Awake()
{
_profileUpdateButton.onClick.AddListener(() => ProfileUpdatePanel.Instance.ShowUpdatePanel(OnAccoutUpdated, true));
}
#endregion
#region Methods
///
/// Searches for a user with given . If a user was found, populates this panel
/// with retrieved user's stats. Makes this panel visible to the viewer.
///
/// Id of searched user.
public async Task ShowAsync(Client client, ISession session, string userId)
{
try
{
IApiUsers results = await client.GetUsersAsync(session, new string[] { userId });
if (results.Users.Count() != 0)
{
return await ShowAsync(results.Users.ElementAt(0));
}
else
{
Debug.LogWarning("Couldn't find user with id: " + userId);
return false;
}
}
catch (System.Exception e)
{
Debug.LogWarning("An error has occured while retrieving user info: " + e);
return false;
}
}
///
/// Populates fields of this panel using gathered from .
/// Makes this panel visible to the user.
///
/// User to be displayed in this panel.
public async Task ShowAsync(IApiUser user)
{
bool populated = await PopulateDataAsync(user);
if (populated == true)
{
// If asPopup is true, show raycast blocking background and close button.
// Otherwise, caller of this method should take care of closing this panel.
await SetUIAccessAsync(user);
return true;
}
else
{
return false;
}
}
///
/// Enables and disables UI.
///
///
/// Disables if displayed user is not the local user.
/// If displayed user is already a friend of local user (or is the local user),
/// is disabled.
/// If asPopup is true, show raycast blocking background and close button, otherwise,
/// caller of this method should take care of closing this panel.
///
private async Task SetUIAccessAsync(IApiUser user)
{
IApiUser localUser = NakamaSessionManager.Instance.Account.User;
bool isFriend = await CanBeFriendAsync(user);
_avatarImage.sprite = AvatarManager.Instance.LoadAvatar(user.AvatarUrl);
_profileUpdateButton.gameObject.SetActive(user.Id == localUser.Id);
_befriendButton.gameObject.SetActive(isFriend);
}
///
/// Returns true if
///
///
///
private async Task CanBeFriendAsync(IApiUser user)
{
Client client = NakamaSessionManager.Instance.Client;
ISession session = NakamaSessionManager.Instance.Session;
if (user.Id == session.UserId)
{
return false;
}
IApiFriends friends = await FriendsManager.LoadFriendsAsync(client, session);
if (friends == null)
{
Debug.Log("Couldn't retrieve friends list");
return false;
}
foreach (IApiFriend friend in friends.Friends)
{
if (friend.User.Id == user.Id)
{
return false;
}
}
return true;
}
///
/// Updates and .
/// Invoked after user successfully updates their account using .
///
private void OnAccoutUpdated()
{
IApiUser user = NakamaSessionManager.Instance.Account.User;
_usernameText.text = user.Username;
_avatarImage.sprite = AvatarManager.Instance.LoadAvatar(user.AvatarUrl);
}
///
/// Sets fields of this panel to show gathered from .
///
/// User to be displayed in this panel.
private async Task PopulateDataAsync(IApiUser user)
{
Client client = NakamaSessionManager.Instance.Client;
ISession session = NakamaSessionManager.Instance.Session;
PlayerData data = await _playerDataStorage.LoadDataAsync(user.Id, "player_data");
IUserGroupListUserGroup clan = await ClanManager.GetUserClanAsync(client, session, user.Id);
Deck deck = await _deckStorage.LoadDataAsync(user.Id, "deck");
if (data != null && deck != null)
{
_usernameText.text = user.Username;
_statsText.text = GenerateStats(data).TrimEnd();
if (clan != null)
{
_clanNameText.text = clan.Group.Name;
}
else
{
_clanNameText.text = "[Not a clan member yet]";
}
for (int i = 0; i < deck.usedCards.Count; i++)
{
Card card = deck.usedCards[i];
_cardSlots[i].SetCard(card);
}
return true;
}
else
{
return false;
}
}
///
/// Returns a formated string containing stats from .
///
private string GenerateStats(PlayerData data)
{
return
"Level: \t" + data.level + System.Environment.NewLine +
"Wins: \t" + data.wins + System.Environment.NewLine +
"Games:\t " + data.gamesPlayed + System.Environment.NewLine;
}
#endregion
}
}