/**
* Copyright 2019 The Knights Of Unity, created by Piotr Stoch
*
* 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 UnityEngine.UI;
using UnityEngine;
using Nakama;
using System;
using DemoGame.Scripts.Session;
namespace DemoGame.Scripts.Friends
{
///
/// Panel for showing friends data in UI
///
public class FriendPanel : MonoBehaviour
{
#region public events
///
/// event fired when this friend button is selected
///
public event Action OnSelected = delegate { };
///
/// event fired after successful request
///
public event Action OnDataChanged = delegate { };
///
/// id, username
///
public event Action OnChatStartButtonClicked = delegate { };
#endregion
#region private serialized fields
[Header("UI elements")]
[Header("Buttons")]
[SerializeField] private Button _friendButton = null;
[SerializeField] private Button _removeFriendButton = null;
[SerializeField] private Button _blockFriendButton = null;
[SerializeField] private Button _startChatButton = null;
[SerializeField] private Button _acceptInviteButton = null;
[Header("Buttons texts and Icons")]
[SerializeField] private Text _nicknameText = null;
[SerializeField] private Text _blockFriendButtonText = null;
[SerializeField] private Text _removeFriendButtonText = null;
[Header("Animations")]
[SerializeField] private Animator _animator = null;
[SerializeField] private RectTransform _bottomPanel = null;
#endregion
#region private fields
//References addded in Init method
private IApiFriend _friend;
///
/// True if friend panel is selected and opened
///
private bool _panelOpened = false;
///
/// True if player is blocked
///
private bool _blocked;
#endregion
#region public methods
///
/// Initializes panel
///
///
///
public void Init(IApiFriend friend)
{
//Setting variables
_friend = friend;
_nicknameText.text = friend.User.Username;
//connecting methods to buttons clicks
_friendButton.onClick.AddListener(TogglePanel);
_friendButton.onClick.AddListener(OnSelected_Handler);
_removeFriendButton.onClick.AddListener(RemoveThisFriend);
_blockFriendButton.onClick.AddListener(BlockOrUnblockThisFriend);
_acceptInviteButton.onClick.AddListener(AcceptInviteFromThisFriend);
_startChatButton.onClick.AddListener(StartChatWithThisFriend);
//setting current panel state based on friend state
ActualizeFriendState();
}
///
/// Deselecting panel, closing it
///
public void Deselect(bool closeImmediately = false)
{
if (_panelOpened)
{
if (closeImmediately)
{
ClosePanelImmediately();
}
ClosePanel();
}
}
#endregion
#region private methods
///
/// Sets actual friend panel state basing on friend state in database
///
private void ActualizeFriendState()
{
switch (_friend.State)
{
// Users are friends with each other.
case 0: break;
// This user has sent an invitation and pending acceptance from other user.
case 1: SetInvitedState(); break;
// This user has received an invitation but has not accepted yet.
case 2: SetInvitingState(); break;
// This user has banned other user.
case 3: SetBlockedState(); break;
}
}
///
/// Handler useful for connecting button click without params with OnSelected event which requires friend panel parameter
///
private void OnSelected_Handler()
{
if (OnSelected != null)
{
OnSelected(this);
}
}
#region button methods
private async void AcceptInviteFromThisFriend()
{
bool success = await FriendsManager.AddFriendAsync(_friend, NakamaSessionManager.Instance.Client, NakamaSessionManager.Instance.Session);
if (success)
{
OnDataChanged();
}
}
private async void RemoveThisFriend()
{
bool success = await FriendsManager.RemoveFriendAsync(_friend, NakamaSessionManager.Instance.Client, NakamaSessionManager.Instance.Session);
if (success)
{
OnDataChanged();
}
}
private async void BlockOrUnblockThisFriend()
{
//Checking if player status is banned.
if (!_blocked)
{
//if is not banned, then block this friend
bool success = await FriendsManager.BlockFriendAsync(_friend, NakamaSessionManager.Instance.Client, NakamaSessionManager.Instance.Session);
if (success)
{
OnDataChanged();
}
}
else
{
//if is already banned, then unblock
bool success = await FriendsManager.RemoveFriendAsync(_friend, NakamaSessionManager.Instance.Client, NakamaSessionManager.Instance.Session);
if (success)
{
OnDataChanged();
}
}
}
private void StartChatWithThisFriend()
{
OnChatStartButtonClicked(_friend.User.Id, _friend.User.Username);
}
#endregion
#region Set states
private void SetBlockedState()
{
_removeFriendButton.gameObject.SetActive(true);
_removeFriendButtonText.text = "unblock";
_blockFriendButtonText.text = "Unblock Friend";
_blocked = true;
}
private void SetInvitedState()
{
_removeFriendButton.gameObject.SetActive(true);
_removeFriendButtonText.text = "remove";
}
private void SetInvitingState()
{
_removeFriendButton.gameObject.SetActive(true);
_removeFriendButtonText.text = "reject";
_acceptInviteButton.gameObject.SetActive(true);
}
#endregion
#region opening/closing panel
///
/// Toggle if panel is opened or closed
///
private void TogglePanel()
{
if (_panelOpened)
{
ClosePanel();
}
else
{
OpenPanel();
}
}
///
/// Plays animation for opening panel
///
private void OpenPanel()
{
_animator.SetTrigger("Open");
_panelOpened = true;
}
///
/// Plays animation for closing
///
private void ClosePanel()
{
_animator.SetTrigger("Close");
_panelOpened = false;
}
///
/// Close without animation
///
public void ClosePanelImmediately()
{
_bottomPanel.sizeDelta = new Vector2(_bottomPanel.sizeDelta.x, 0);
_panelOpened = false;
}
#endregion
#endregion
}
}