/**
* 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;
using DemoGame.Scripts.DataStorage;
using DemoGame.Scripts.Menus;
using DemoGame.Scripts.Session;
using Facebook.Unity;
using Nakama;
using UnityEngine;
using UnityEngine.UI;
namespace DemoGame.Scripts.Profile
{
///
/// Panel used to change username and avatar of a user account.
///
public class ProfileUpdatePanel : SingletonMenu
{
#region Fields
#region FacebookRestoreUI
///
/// Begins account migration process by invoking
/// .
///
[SerializeField] private Button _facebookConflictConfirmButton = null;
///
/// Panel with UI representing succesfull Facebook account linking.
///
[SerializeField] private Menu _facebookSuccessPanel = null;
///
/// Panel with UI representing failed Facebook account linking.
///
[SerializeField] private Menu _facebookErrorPanel = null;
///
/// Panel allowing user to chose whether to migrate current device to
/// an already existing accoun linked to supplied Facebook account
///
[SerializeField] private Menu _facebookConflictPanel = null;
#endregion
[Space]
///
/// Sends account update request to Nakama server and closes the panel.
///
[SerializeField] private Button _doneButton = null;
///
/// Textbox containing account's username.
///
[SerializeField] private InputField _usernameText = null;
///
/// Restores account using Facebook.
///
[SerializeField] private Button _linkFacebookButton = null;
///
/// Image displying user's avatar.
///
[SerializeField] private Image _avatarImage = null;
///
/// Button used for changing avatars.
///
[SerializeField] private Button _avatarButton = null;
///
/// The path to currently displayed avatar in Resources folder.
///
private string _avatarPath;
#endregion
#region Mono
///
/// Sets button listeners.
///
private void Start()
{
_avatarButton.onClick.AddListener(ChangeAvatar);
_linkFacebookButton.onClick.AddListener(LinkFacebook);
_facebookConflictConfirmButton.onClick.AddListener(MigrateAccount);
_facebookConflictPanel.SetBackButtonHandler(_facebookConflictPanel.Hide);
_facebookErrorPanel.SetBackButtonHandler(_facebookErrorPanel.Hide);
_facebookSuccessPanel.SetBackButtonHandler(_facebookSuccessPanel.Hide);
_facebookConflictPanel.Hide();
_facebookErrorPanel.Hide();
_facebookSuccessPanel.Hide();
base.SetBackButtonHandler(MenuManager.Instance.HideTopMenu);
}
#endregion
#region Methods
///
/// Makes this panel visible to the viewer.
/// Fills fields with local user data.
///
///
/// If false, user can't exit this panel before updating their account.
///
public void ShowUpdatePanel(Action onDone, bool canTerminate)
{
// Update done button listeners
_doneButton.onClick.RemoveAllListeners();
_doneButton.onClick.AddListener(() => Done(onDone));
IApiUser user = NakamaSessionManager.Instance.Account.User;
_usernameText.text = user.Username;
_avatarPath = user.AvatarUrl;
_avatarImage.sprite = AvatarManager.Instance.LoadAvatar(_avatarPath);
MenuManager.Instance.ShowMenu(this, false);
if (canTerminate == true)
{
_backButton.gameObject.SetActive(true);
}
else
{
_backButton.gameObject.SetActive(false);
}
}
///
/// Changes displayed avatar to next available.
///
private void ChangeAvatar()
{
_avatarPath = AvatarManager.Instance.NextAvatar(_avatarPath);
_avatarImage.sprite = AvatarManager.Instance.LoadAvatar(_avatarPath);
}
///
/// Links a Facebook account with Nakama user account.
/// If given facebook account is already linked to other Nakama account, links a dummy device
/// to current account, unlinks local device and migrates it to the Facebook linked account.
///
private void LinkFacebook()
{
NakamaSessionManager.Instance.ConnectFacebook(OnFacebookResponded);
}
///
/// Invoked by after successfull or unsuccessfull facebook linking.
///
private void OnFacebookResponded(FacebookResponse response)
{
if (response == FacebookResponse.Conflict)
{
_facebookConflictPanel.Show();
}
else if (response == FacebookResponse.Error || response == FacebookResponse.NotInitialized)
{
_facebookErrorPanel.Show();
}
else if (response == FacebookResponse.Linked)
{
_facebookSuccessPanel.Show();
}
}
///
/// Migrates current device to supplied Facebook account.
///
private async void MigrateAccount()
{
_facebookConflictPanel.Hide();
string token = AccessToken.CurrentAccessToken.TokenString;
bool good = await NakamaSessionManager.Instance.MigrateDeviceIdAsync(token);
if (good == false)
{
_facebookErrorPanel.Show();
}
else
{
_facebookSuccessPanel.Show();
}
}
///
/// Sends account update request to server with new Username and AvatarUrl.
///
private async void Done(Action onDone)
{
AuthenticationResponse response = await NakamaSessionManager.Instance.UpdateUserInfoAsync(_usernameText.text, _avatarPath);
if (response != AuthenticationResponse.Error)
{
onDone?.Invoke();
MenuManager.Instance.HideTopMenu();
}
}
#endregion
}
}