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); } } } } }