| | 1 | | using DCL; |
| | 2 | | using DCL.Interface; |
| | 3 | | using System; |
| | 4 | | using System.Collections.Generic; |
| | 5 | | using System.Globalization; |
| | 6 | | using UnityEngine; |
| | 7 | |
|
| | 8 | | /// <summary> |
| | 9 | | /// Utils related to the events management in ExploreV2. |
| | 10 | | /// </summary> |
| | 11 | | public static class ExploreEventsUtils |
| | 12 | | { |
| | 13 | | internal const string EVENT_CARD_MODAL_ID = "EventCard_Modal"; |
| | 14 | | internal const string LIVE_TAG_TEXT = "LIVE"; |
| | 15 | | internal const string EVENT_DETAIL_URL = "https://events.decentraland.org/event/?id={0}"; |
| | 16 | |
|
| | 17 | | /// <summary> |
| | 18 | | /// Instantiates (if does not already exists) a event card modal from the given prefab. |
| | 19 | | /// </summary> |
| | 20 | | /// <param name="eventCardModalPrefab">Prefab to instantiate.</param> |
| | 21 | | /// <returns>An instance of a event card modal.</returns> |
| | 22 | | public static EventCardComponentView ConfigureEventCardModal(EventCardComponentView eventCardModalPrefab) |
| | 23 | | { |
| 36 | 24 | | EventCardComponentView eventModal = null; |
| | 25 | |
|
| 36 | 26 | | GameObject existingModal = GameObject.Find(EVENT_CARD_MODAL_ID); |
| 36 | 27 | | if (existingModal != null) |
| 24 | 28 | | eventModal = existingModal.GetComponent<EventCardComponentView>(); |
| | 29 | | else |
| | 30 | | { |
| 12 | 31 | | eventModal = GameObject.Instantiate(eventCardModalPrefab); |
| 12 | 32 | | eventModal.name = EVENT_CARD_MODAL_ID; |
| | 33 | | } |
| | 34 | |
|
| 36 | 35 | | eventModal.Hide(true); |
| | 36 | |
|
| 36 | 37 | | return eventModal; |
| | 38 | | } |
| | 39 | |
|
| | 40 | | /// <summary> |
| | 41 | | /// Creates and configures a pool for event cards. |
| | 42 | | /// </summary> |
| | 43 | | /// <param name="pool">Pool to configure.</param> |
| | 44 | | /// <param name="poolName">Name of the pool.</param> |
| | 45 | | /// <param name="eventCardPrefab">Event card prefab to use by the pool.</param> |
| | 46 | | /// <param name="maxPrewarmCount">Max number of pre-created cards.</param> |
| | 47 | | public static void ConfigureEventCardsPool(out Pool pool, string poolName, EventCardComponentView eventCardPrefab, i |
| | 48 | | { |
| 115 | 49 | | pool = PoolManager.i.GetPool(poolName); |
| 115 | 50 | | if (pool == null) |
| | 51 | | { |
| 6 | 52 | | pool = PoolManager.i.AddPool( |
| | 53 | | poolName, |
| | 54 | | GameObject.Instantiate(eventCardPrefab).gameObject, |
| | 55 | | maxPrewarmCount: maxPrewarmCount, |
| | 56 | | isPersistent: true); |
| | 57 | |
|
| 6 | 58 | | pool.ForcePrewarm(); |
| | 59 | | } |
| 115 | 60 | | } |
| | 61 | |
|
| | 62 | | /// <summary> |
| | 63 | | /// Instantiates and configures a given list of events. |
| | 64 | | /// </summary> |
| | 65 | | /// <param name="events">List of events data.</param> |
| | 66 | | /// <param name="pool">Pool to use.</param> |
| | 67 | | /// <param name="OnEventInfoClicked">Action to inform when the Info button has been clicked.</param> |
| | 68 | | /// <param name="OnEventJumpInClicked">Action to inform when the JumpIn button has been clicked.</param> |
| | 69 | | /// <param name="OnEventSubscribeEventClicked">Action to inform when the Subscribe button has been clicked.</param> |
| | 70 | | /// <param name="OnEventUnsubscribeEventClicked">Action to inform when the Unsubscribe button has been clicked.</par |
| | 71 | | /// <returns>A list of instances of events.</returns> |
| | 72 | | public static List<BaseComponentView> InstantiateAndConfigureEventCards( |
| | 73 | | List<EventCardComponentModel> events, |
| | 74 | | Pool pool, |
| | 75 | | Action<EventCardComponentModel> OnEventInfoClicked, |
| | 76 | | Action<EventFromAPIModel> OnEventJumpInClicked, |
| | 77 | | Action<string> OnEventSubscribeEventClicked, |
| | 78 | | Action<string> OnEventUnsubscribeEventClicked) |
| | 79 | | { |
| 7 | 80 | | List<BaseComponentView> instantiatedPlaces = new List<BaseComponentView>(); |
| | 81 | |
|
| 42 | 82 | | foreach (EventCardComponentModel eventInfo in events) |
| | 83 | | { |
| 14 | 84 | | EventCardComponentView eventGO = pool.Get().gameObject.GetComponent<EventCardComponentView>(); |
| 14 | 85 | | ConfigureEventCard(eventGO, eventInfo, OnEventInfoClicked, OnEventJumpInClicked, OnEventSubscribeEventClicke |
| 14 | 86 | | instantiatedPlaces.Add(eventGO); |
| | 87 | | } |
| | 88 | |
|
| 7 | 89 | | return instantiatedPlaces; |
| | 90 | | } |
| | 91 | |
|
| | 92 | | /// <summary> |
| | 93 | | /// Configure a event card with the given model. |
| | 94 | | /// </summary> |
| | 95 | | /// <param name="eventCard">Event card to configure.</param> |
| | 96 | | /// <param name="eventInfo">Model to apply.</param> |
| | 97 | | /// <param name="OnEventInfoClicked">Action to inform when the Info button has been clicked.</param> |
| | 98 | | /// <param name="OnEventJumpInClicked">Action to inform when the JumpIn button has been clicked.</param> |
| | 99 | | /// <param name="OnEventSubscribeEventClicked">Action to inform when the Subscribe button has been clicked.</param> |
| | 100 | | /// <param name="OnEventUnsubscribeEventClicked">Action to inform when the Unsubscribe button has been clicked.</par |
| | 101 | | public static void ConfigureEventCard( |
| | 102 | | EventCardComponentView eventCard, |
| | 103 | | EventCardComponentModel eventInfo, |
| | 104 | | Action<EventCardComponentModel> OnEventInfoClicked, |
| | 105 | | Action<EventFromAPIModel> OnEventJumpInClicked, |
| | 106 | | Action<string> OnEventSubscribeEventClicked, |
| | 107 | | Action<string> OnEventUnsubscribeEventClicked) |
| | 108 | | { |
| 17 | 109 | | eventCard.Configure(eventInfo); |
| 17 | 110 | | eventCard.onInfoClick?.RemoveAllListeners(); |
| 17 | 111 | | eventCard.onInfoClick?.AddListener(() => OnEventInfoClicked?.Invoke(eventInfo)); |
| 17 | 112 | | eventCard.onJumpInClick?.RemoveAllListeners(); |
| 17 | 113 | | eventCard.onJumpInClick?.AddListener(() => OnEventJumpInClicked?.Invoke(eventInfo.eventFromAPIInfo)); |
| 17 | 114 | | eventCard.onSubscribeClick?.RemoveAllListeners(); |
| 17 | 115 | | eventCard.onSubscribeClick?.AddListener(() => OnEventSubscribeEventClicked?.Invoke(eventInfo.eventId)); |
| 17 | 116 | | eventCard.onUnsubscribeClick?.RemoveAllListeners(); |
| 17 | 117 | | eventCard.onUnsubscribeClick?.AddListener(() => OnEventUnsubscribeEventClicked?.Invoke(eventInfo.eventId)); |
| 17 | 118 | | } |
| | 119 | |
|
| | 120 | | /// <summary> |
| | 121 | | /// Returs a event card model from the given API data. |
| | 122 | | /// </summary> |
| | 123 | | /// <param name="eventFromAPI">Data received from the API.</param> |
| | 124 | | /// <returns>An event card model.</returns> |
| | 125 | | public static EventCardComponentModel CreateEventCardModelFromAPIEvent(EventFromAPIModel eventFromAPI) |
| | 126 | | { |
| 9 | 127 | | EventCardComponentModel eventCardModel = new EventCardComponentModel(); |
| 9 | 128 | | eventCardModel.eventId = eventFromAPI.id; |
| 9 | 129 | | eventCardModel.eventPictureUri = eventFromAPI.image; |
| 9 | 130 | | eventCardModel.isLive = eventFromAPI.live; |
| 9 | 131 | | eventCardModel.liveTagText = LIVE_TAG_TEXT; |
| 9 | 132 | | eventCardModel.eventDateText = FormatEventDate(eventFromAPI); |
| 9 | 133 | | eventCardModel.eventName = eventFromAPI.name; |
| 9 | 134 | | eventCardModel.eventDescription = eventFromAPI.description; |
| 9 | 135 | | eventCardModel.eventStartedIn = FormatEventStartDate(eventFromAPI); |
| 9 | 136 | | eventCardModel.eventStartsInFromTo = FormatEventStartDateFromTo(eventFromAPI); |
| 9 | 137 | | eventCardModel.eventOrganizer = FormatEventOrganized(eventFromAPI); |
| 9 | 138 | | eventCardModel.eventPlace = FormatEventPlace(eventFromAPI); |
| 9 | 139 | | eventCardModel.subscribedUsers = eventFromAPI.total_attendees; |
| 9 | 140 | | eventCardModel.isSubscribed = false; |
| 9 | 141 | | eventCardModel.coords = new Vector2Int(eventFromAPI.coordinates[0], eventFromAPI.coordinates[1]); |
| 9 | 142 | | eventCardModel.eventFromAPIInfo = eventFromAPI; |
| | 143 | |
|
| | 144 | | // Card events |
| 9 | 145 | | return eventCardModel; |
| | 146 | | } |
| | 147 | |
|
| | 148 | | internal static string FormatEventDate(EventFromAPIModel eventFromAPI) |
| | 149 | | { |
| 10 | 150 | | DateTime eventDateTime = Convert.ToDateTime(eventFromAPI.next_start_at).ToUniversalTime(); |
| 10 | 151 | | return eventDateTime.ToString("MMMM d", new CultureInfo("en-US")); |
| | 152 | | } |
| | 153 | |
|
| | 154 | | internal static string FormatEventStartDate(EventFromAPIModel eventFromAPI) |
| | 155 | | { |
| 10 | 156 | | DateTime eventDateTime = Convert.ToDateTime(eventFromAPI.next_start_at).ToUniversalTime(); |
| | 157 | | string formattedDate; |
| 10 | 158 | | if (eventFromAPI.live) |
| | 159 | | { |
| 10 | 160 | | int daysAgo = (int)Math.Ceiling((DateTime.Now - eventDateTime).TotalDays); |
| 10 | 161 | | int hoursAgo = (int)Math.Ceiling((DateTime.Now - eventDateTime).TotalHours); |
| | 162 | |
|
| 10 | 163 | | if (daysAgo > 0) |
| 10 | 164 | | formattedDate = $"{daysAgo} days ago"; |
| | 165 | | else |
| 0 | 166 | | formattedDate = $"{hoursAgo} hr ago"; |
| 0 | 167 | | } |
| | 168 | | else |
| | 169 | | { |
| 0 | 170 | | int daysToStart = (int)Math.Ceiling((eventDateTime - DateTime.Now).TotalDays); |
| 0 | 171 | | int hoursToStart = (int)Math.Ceiling((eventDateTime - DateTime.Now).TotalHours); |
| | 172 | |
|
| 0 | 173 | | if (daysToStart > 0) |
| 0 | 174 | | formattedDate = $"in {daysToStart} days"; |
| | 175 | | else |
| 0 | 176 | | formattedDate = $"in {hoursToStart} hours"; |
| | 177 | | } |
| | 178 | |
|
| 10 | 179 | | return formattedDate; |
| | 180 | | } |
| | 181 | |
|
| | 182 | | internal static string FormatEventStartDateFromTo(EventFromAPIModel eventFromAPI) |
| | 183 | | { |
| 10 | 184 | | CultureInfo cultureInfo = new CultureInfo("en-US"); |
| 10 | 185 | | DateTime eventStartDateTime = Convert.ToDateTime(eventFromAPI.next_start_at).ToUniversalTime(); |
| 10 | 186 | | DateTime eventEndDateTime = Convert.ToDateTime(eventFromAPI.finish_at).ToUniversalTime(); |
| 10 | 187 | | string formattedDate = $"From {eventStartDateTime.ToString("dddd", cultureInfo)}, {eventStartDateTime.Day} {even |
| | 188 | | $" to {eventEndDateTime.ToString("dddd", cultureInfo)}, {eventEndDateTime.Day} {eventEndD |
| | 189 | |
|
| 10 | 190 | | return formattedDate; |
| | 191 | | } |
| | 192 | |
|
| 10 | 193 | | internal static string FormatEventOrganized(EventFromAPIModel eventFromAPI) { return $"Public, Organized by {eventFr |
| | 194 | |
|
| 10 | 195 | | internal static string FormatEventPlace(EventFromAPIModel eventFromAPI) { return string.IsNullOrEmpty(eventFromAPI.s |
| | 196 | |
|
| | 197 | | /// <summary> |
| | 198 | | /// Makes a jump in to the event defined by the given place data from API. |
| | 199 | | /// </summary> |
| | 200 | | /// <param name="eventFromAPI">Event data from API.</param> |
| | 201 | | public static void JumpInToEvent(EventFromAPIModel eventFromAPI) |
| | 202 | | { |
| 2 | 203 | | Vector2Int coords = new Vector2Int(eventFromAPI.coordinates[0], eventFromAPI.coordinates[1]); |
| 2 | 204 | | string[] realmFromAPI = string.IsNullOrEmpty(eventFromAPI.realm) ? new string[] { "", "" } : eventFromAPI.realm. |
| 2 | 205 | | string serverName = realmFromAPI[0]; |
| 2 | 206 | | string layerName = realmFromAPI[1]; |
| | 207 | |
|
| 2 | 208 | | if (string.IsNullOrEmpty(serverName)) |
| 2 | 209 | | WebInterface.GoTo(coords.x, coords.y); |
| | 210 | | else |
| 0 | 211 | | WebInterface.JumpIn(coords.x, coords.y, serverName, layerName); |
| 0 | 212 | | } |
| | 213 | | } |