using System;
using System.Collections;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
namespace NotificationSamples.Demo
{
///
/// Manages the console on screen that displays information about notifications,
/// and allows you to schedule more.
///
public class NotificationConsole : MonoBehaviour
{
// On iOS, this represents the notification's Category Identifier, and is optional
// On Android, this represents the notification's channel, and is required (at least one).
// Channels defined as global constants so can be referred to from GameController.cs script when setting/sending notification
public const string ChannelId = "game_channel0";
public const string ReminderChannelId = "reminder_channel1";
public const string NewsChannelId = "news_channel2";
[SerializeField]
protected Button sendButton;
[SerializeField]
protected Button clearEventButton;
[SerializeField]
protected TMP_InputField titleField;
[SerializeField]
protected TMP_InputField bodyField;
[SerializeField]
protected TMP_InputField timeField;
[SerializeField]
protected TMP_InputField badgeField;
[SerializeField]
protected GameNotificationsManager manager;
[SerializeField]
protected Transform pendingNotificationsListParent;
[SerializeField]
protected PendingNotificationItem pendingNotificationPrefab;
[SerializeField]
protected Transform pendingEventParent;
[SerializeField]
protected NotificationEventItem eventPrefab;
// Update pending notifications in the next update.
private bool updatePendingNotifications;
private void Awake()
{
if (sendButton != null)
{
sendButton.onClick.AddListener(SendNotificationFromUi);
}
if (clearEventButton != null)
{
clearEventButton.onClick.AddListener(ClearEvents);
}
}
private IEnumerator Start()
{
// Set up channels (mostly for Android)
// You need to have at least one of these
var c1 = new GameNotificationChannel(ChannelId, "Default Game Channel", "Generic notifications");
var c2 = new GameNotificationChannel(NewsChannelId, "News Channel", "News feed notifications");
var c3 = new GameNotificationChannel(ReminderChannelId, "Reminder Channel", "Reminder notifications");
return manager.Initialize(c1, c2, c3);
}
private void OnDestroy()
{
if (sendButton != null)
{
sendButton.onClick.RemoveListener(SendNotificationFromUi);
}
if (clearEventButton != null)
{
clearEventButton.onClick.RemoveListener(ClearEvents);
}
}
private void OnEnable()
{
if (manager != null)
{
manager.LocalNotificationDelivered += OnDelivered;
manager.LocalNotificationExpired += OnExpired;
}
}
private void OnDisable()
{
if (manager != null)
{
manager.LocalNotificationDelivered -= OnDelivered;
manager.LocalNotificationExpired -= OnExpired;
}
}
///
/// Queue a notification with the given parameters.
///
/// The title for the notification.
/// The body text for the notification.
/// The time to deliver the notification.
/// The optional badge number to display on the application icon.
///
/// Whether to reschedule the notification if foregrounding and the notification hasn't yet been shown.
///
/// Channel ID to use. If this is null/empty then it will use the default ID. For Android
/// the channel must be registered in .
/// Notification small icon.
/// Notification large icon.
public void SendNotification(string title, string body, DateTime deliveryTime, int? badgeNumber = null,
bool reschedule = false, string channelId = null,
string smallIcon = null, string largeIcon = null)
{
IGameNotification notification = manager.CreateNotification();
if (notification == null)
{
return;
}
notification.Title = title;
notification.Body = body;
notification.Group = !string.IsNullOrEmpty(channelId) ? channelId : ChannelId;
notification.DeliveryTime = deliveryTime;
notification.SmallIcon = smallIcon;
notification.LargeIcon = largeIcon;
if (badgeNumber != null)
{
notification.BadgeNumber = badgeNumber;
}
PendingNotification notificationToDisplay = manager.ScheduleNotification(notification);
notificationToDisplay.Reschedule = reschedule;
updatePendingNotifications = true;
QueueEvent($"Queued event with ID \"{notification.Id}\" at time {deliveryTime:HH:mm}");
}
///
/// Cancel a given pending notification
///
public void CancelPendingNotificationItem(PendingNotification itemToCancel)
{
manager.CancelNotification(itemToCancel.Notification.Id.Value);
updatePendingNotifications = true;
QueueEvent($"Cancelled notification with ID \"{itemToCancel.Notification.Id}\"");
}
private void OnApplicationFocus(bool hasFocus)
{
if (hasFocus)
{
StartCoroutine(UpdatePendingNotificationsNextFrame());
}
}
private void SendNotificationFromUi()
{
int? badgeNumber = int.TryParse(badgeField.text, out int parsedBadgeNumber)
? parsedBadgeNumber
: (int?)null;
DateTime deliveryTime;
if (float.TryParse(timeField.text, out float minutes))
{
deliveryTime = DateTime.Now.ToLocalTime() + TimeSpan.FromMinutes(minutes);
}
else
{
deliveryTime = DateTime.Now.ToLocalTime() + TimeSpan.FromMinutes(1);
}
SendNotification(titleField.text, bodyField.text, deliveryTime, badgeNumber);
}
private void OnDelivered(PendingNotification deliveredNotification)
{
// Schedule this to run on the next frame (can't create UI elements from a Java callback)
StartCoroutine(ShowDeliveryNotificationCoroutine(deliveredNotification.Notification));
}
private void OnExpired(PendingNotification obj)
{
QueueEvent($"Notification with title \"{obj.Notification.Title}\" expired and was not displayed.");
}
private IEnumerator ShowDeliveryNotificationCoroutine(IGameNotification deliveredNotification)
{
yield return null;
QueueEvent($"Notification with ID \"{deliveredNotification.Id}\" shown in foreground.");
updatePendingNotifications = true;
}
private IEnumerator UpdatePendingNotificationsNextFrame()
{
yield return null;
updatePendingNotifications = true;
}
private void Update()
{
if (updatePendingNotifications)
{
UpdatePendingNotifications();
}
}
private void UpdatePendingNotifications()
{
Debug.Log("Updating pending list.");
updatePendingNotifications = false;
// Clear all existing ones
foreach (object child in pendingNotificationsListParent.transform)
{
if (child is Transform childTransform)
{
Destroy(childTransform.gameObject);
}
}
if (manager?.PendingNotifications == null)
return;
// Recreate based on currently pending list
// Note: Using ToArray because the list can change during the loop.
foreach (PendingNotification scheduledNotification in manager.PendingNotifications.ToArray())
{
PendingNotificationItem newItem =
Instantiate(pendingNotificationPrefab, pendingNotificationsListParent);
newItem.Show(scheduledNotification, this);
}
}
private void QueueEvent(string eventText)
{
Debug.Log($"Queueing event with text \"{eventText}\"");
NotificationEventItem newItem = Instantiate(eventPrefab, pendingEventParent);
newItem.Show(eventText);
}
private void ClearEvents()
{
foreach (object child in pendingEventParent.transform)
{
if (child is Transform childTransform)
{
Destroy(childTransform.gameObject);
}
}
}
}
}