Example #1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="groupedByDay">This list will be modified, removing items that are past the date to start displaying on, which is beneficial to the next time this is called since those removed items would have never been applicable anyways.</param>
        /// <param name="todayAsUtc"></param>
        /// <param name="useFriendlyDates"></param>
        /// <param name="type"></param>
        /// <param name="tileSettings"></param>
        /// <returns></returns>
        internal static XmlDocument GenerateUpcomingTileNotificationContent(List <ItemsOnDay> groupedByDay, DateTime todayAsUtc, bool useFriendlyDates, UpcomingTileType type)
        {
            // If there aren't any
            if (groupedByDay.Count == 0)
            {
                return(null);
            }

            var mediumAndWideContent = GenerateTileBindingContent(
                groupedItems: groupedByDay,
                todayAsUtc: todayAsUtc,
                useFriendlyDates: useFriendlyDates,
                useLargerHeader: false,
                maxLinesOfText: 10);

            var largeContent = GenerateTileBindingContent(
                groupedItems: groupedByDay,
                todayAsUtc: todayAsUtc,
                useFriendlyDates: useFriendlyDates,
                useLargerHeader: true,
                maxLinesOfText: 13);


            TileContent content = new TileContent()
            {
                Visual = new TileVisual()
                {
                    Branding = type == UpcomingTileType.PrimaryTile ? TileBranding.NameAndLogo : TileBranding.Auto,

                    TileMedium = new TileBinding()
                    {
                        DisplayName = type == UpcomingTileType.PrimaryTile ? "Planner" : null,
                        Content     = mediumAndWideContent
                    },

                    TileWide = new TileBinding()
                    {
                        Content = mediumAndWideContent
                    },

                    TileLarge = new TileBinding()
                    {
                        Content = largeContent
                    },

                    LockDetailedStatus1 = GenerateUpcomingDateText(groupedByDay.First().DateInUtc, todayAsUtc, useFriendlyDates)
                }
            };

            var firstGroup = groupedByDay.First();

            if (firstGroup.Items.Count > 1)
            {
                content.Visual.LockDetailedStatus1 += " - " + firstGroup.Items.Count + " Items";
            }

            content.Visual.LockDetailedStatus2 = trim(firstGroup.Items[0].Name, 255);

            if (firstGroup.Items.Count >= 2)
            {
                content.Visual.LockDetailedStatus3 = trim(firstGroup.Items[1].Name, 255);
            }

            //XmlDocument doc = new XmlDocument();
            //string stringContent = content.GetContent();
            //doc.LoadXml(stringContent);
            //return doc;
            return(content.GetXml());
        }
Example #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="updater"></param>
        /// <param name="allUpcoming">This list will be manipulated. Should already be sorted.</param>
        /// <param name="todayInLocal"></param>
        /// <param name="type"></param>
        internal static void UpdateUpcomingTile(TileUpdater updater, List <BaseViewItemHomeworkExam> allUpcoming, DateTime todayInLocal, UpcomingTileType type, BaseUpcomingTileSettings tileSettings)
        {
            try
            {
                // Clear all scheduled notifications
                ClearScheduledNotifications(updater);

                List <ItemsOnDay> groupedByDay = GroupByDay(allUpcoming);

                bool      veryFirst     = true;
                DateTime  today         = todayInLocal;
                const int daysInAdvance = 5;
                for (int i = 0; i < daysInAdvance; i++, today = today.AddDays(1))
                {
                    DateTime todayAsUtc = DateTime.SpecifyKind(today, DateTimeKind.Utc);

                    // Remove any exams that are past "today"
                    for (int x = 0; x < groupedByDay.Count; x++)
                    {
                        groupedByDay[x].Items.RemoveAll(item => item is ViewItemExam && item.Date < today);
                        if (groupedByDay[x].Items.Count == 0)
                        {
                            groupedByDay.RemoveAt(x);
                            x--;
                        }
                    }

                    DateTime dateToStartFrom = tileSettings.GetDateToStartDisplayingOn(todayAsUtc);

                    // Remove any day groups that are older than the user's chosen max date range to display
                    while (groupedByDay.Count > 0 && groupedByDay[0].DateInUtc < dateToStartFrom)
                    {
                        groupedByDay.RemoveAt(0);
                    }

                    // If there's a today group
                    Dictionary <Guid, DateTime> identifiersAndEndTimes = new Dictionary <Guid, DateTime>();
                    var todayGroup = groupedByDay.FirstOrDefault(g => g.DateInUtc == todayAsUtc);
                    if (todayGroup != null)
                    {
                        // That means we'll need to check if there's exams/events, and if so, we need to update the tile
                        // after the event is over, rather than waiting till the day is over

                        // First we need to create a mapping of the item end times and their indexes, because we need to make sure that we're removing
                        // in order of the earliest end times (right now items are sorted by their start times, so not necessarily correct order based on end times)
                        // We also need to be aware that an event could potentially span multiple days...
                        foreach (var item in todayGroup.Items)
                        {
                            // We ignore "all day" items which end at 11:59:59
                            DateTime endTime;
                            if (item is ViewItemExam && item.TryGetEndDateWithTime(out endTime) && endTime.TimeOfDay != new TimeSpan(23, 59, 59))
                            {
                                identifiersAndEndTimes[item.Identifier] = endTime;
                            }
                        }

                        // Remove any events that have already expired (so that the first update doesn't include them)
                        //if (veryFirst)
                        //{
                        //    while (true)
                        //    {
                        //        if (identifiersAndEndTimes.Count > 0)
                        //        {
                        //            DateTime minEndTime = identifiersAndEndTimes.Values.Min();

                        //            // If it's already expired, we remove it
                        //            if (minEndTime < DateTime.Now)
                        //            {
                        //                Guid[] identifiersToRemove = identifiersAndEndTimes.Where(p => p.Value == minEndTime).Select(p => p.Key).ToArray();
                        //                foreach (var id in identifiersToRemove)
                        //                {
                        //                    identifiersAndEndTimes.Remove(id);
                        //                }

                        //                // Remove those events
                        //                todayGroup.Items.RemoveAll(x => identifiersToRemove.Contains(x.Identifier));

                        //                // If we've removed all for that day
                        //                if (todayGroup.Items.Count == 0)
                        //                {
                        //                    // Remove the group
                        //                    groupedByDay.Remove(todayGroup);
                        //                }
                        //            }
                        //        }

                        //        break;
                        //    }
                        //}
                    }

                    DateTime deliveryTime = today;

                    do
                    {
                        if (deliveryTime.Date != today.Date)
                        {
                            // If an event ended up spanning multiple days causing delivery time to be past today, we just won't add it.
                            // In the future when we add support for multiple day events, we'll have to actually handle this... otherwise when the
                            // event expires, the tile won't update correctly on that future day.
                            break;
                        }

                        // On all items but the last, we use the friendly date
                        XmlDocument tile = GenerateUpcomingTileNotificationContent(
                            groupedByDay: groupedByDay,
                            todayAsUtc: todayAsUtc,
                            useFriendlyDates: i != daysInAdvance - 1,
                            type: type);

                        if (tile == null)
                        {
                            if (veryFirst)
                            {
                                updater.Clear();
                            }
                            return;
                        }

                        DateTime thisDeliveryTime = deliveryTime;

                        DateTime expirationTime = today.AddDays(1);

                        bool hasAdditionalOnThisDay = false;

                        // Pick off earliest ending time if there are any left
                        if (identifiersAndEndTimes.Count > 0)
                        {
                            DateTime minEndTime          = identifiersAndEndTimes.Values.Min();
                            Guid[]   identifiersToRemove = identifiersAndEndTimes.Where(p => p.Value == minEndTime).Select(p => p.Key).ToArray();
                            foreach (var id in identifiersToRemove)
                            {
                                identifiersAndEndTimes.Remove(id);
                            }

                            // Assign the expiration time and the next delivery time to be this end time
                            if (minEndTime > deliveryTime)
                            {
                                expirationTime = minEndTime;
                                deliveryTime   = minEndTime; // Setting this for the NEXT notification
                            }

                            // Remove those events
                            todayGroup.Items.RemoveAll(x => identifiersToRemove.Contains(x.Identifier));

                            // If we've removed all for that day
                            if (todayGroup.Items.Count == 0)
                            {
                                // Remove the group
                                groupedByDay.Remove(todayGroup);
                            }

                            // Otherwise
                            else
                            {
                                // We have more on this day that we'll have to repeat the loop for
                                hasAdditionalOnThisDay = true;
                            }
                        }

                        // If we don't have additional on this day, we can remove today since we're done with it,
                        // which will ensure we correctly set expiration time if there's nothing else left
                        if (!hasAdditionalOnThisDay && todayGroup != null)
                        {
                            groupedByDay.Remove(todayGroup);
                        }

                        if (veryFirst || thisDeliveryTime < DateTime.Now.AddSeconds(5))
                        {
                            TileNotification currNotif = new TileNotification(tile);

                            // Only assign expiration time if we have no items left
                            if (groupedByDay.Count == 0)
                            {
                                currNotif.ExpirationTime = expirationTime;
                            }

                            updater.Update(currNotif);

                            veryFirst = false;
                        }
                        else
                        {
                            ScheduledTileNotification s = new ScheduledTileNotification(tile, thisDeliveryTime);

                            // Only assign expiration time if we have no items left
                            if (groupedByDay.Count == 0)
                            {
                                s.ExpirationTime = expirationTime;
                            }

                            updater.AddToSchedule(s);
                        }

                        if (!hasAdditionalOnThisDay)
                        {
                            break;
                        }
                    } while (true);
                }
            }

            catch (Exception ex)
            {
                if (!UWPExceptionHelper.TrackIfNotificationsIssue(ex, "Tiles"))
                {
                    throw ex;
                }
            }
        }