Пример #1
0
        private static async Task UpdatePrimaryTileNotificationsBlocking(AccountDataItem account, AccountDataStore data)
        {
            try
            {
                Debug.WriteLine("Updating Primary Tile");

                TileUpdater tileUpdater = TileUpdateManager.CreateTileUpdaterForApplication();


                if (account == null || account.MainTileSettings.IsDisabled())
                {
                    ClearScheduledNotifications(tileUpdater);
                    tileUpdater.Clear();
                    return;
                }

                DateTime todayInLocal = DateTime.Today;

                var allUpcoming = await getAllUpcomingBlocking(account, data, DateTime.SpecifyKind(todayInLocal, DateTimeKind.Utc), account.MainTileSettings);

                UpdateUpcomingTile(tileUpdater, allUpcoming, todayInLocal, UpcomingTileType.PrimaryTile, account.MainTileSettings);
            }

            catch (Exception ex)
            {
                if (!UWPExceptionHelper.TrackIfNotificationsIssue(ex, "Tiles"))
                {
                    throw ex;
                }
            }
        }
Пример #2
0
        private static async Task UpdateTileAsync(SecondaryTile tile, AccountDataItem account, AccountDataStore data, Guid classId)
        {
            try
            {
                DateTime todayInLocal = DateTime.Today;

                // Get the class tile settings
                ClassTileSettings settings = await account.GetClassTileSettings(classId);

                ClassData classData = await LoadDataAsync(data, classId, DateTime.SpecifyKind(todayInLocal, DateTimeKind.Utc), settings);

                // If classData was null, that means the class wasn't found, so we should delete the tile
                if (classData == null)
                {
                    await tile.RequestDeleteAsync();
                    return;
                }

                bool changed = false;

                string desiredName = GetTrimmedClassName(classData.Class.Name);

                Color desiredColor;

                if (settings.CustomColor != null)
                    desiredColor = ColorTools.GetColor(settings.CustomColor);
                else
                    desiredColor = ColorTools.GetColor(classData.Class.Color);

                if (!tile.DisplayName.Equals(desiredName))
                {
                    changed = true;
                    tile.DisplayName = desiredName;
                }

                if (!tile.VisualElements.BackgroundColor.Equals(desiredColor))
                {
                    changed = true;
                    tile.VisualElements.BackgroundColor = desiredColor;
                }

                if (changed)
                    await tile.UpdateAsync();


                var updater = TileUpdateManager.CreateTileUpdaterForSecondaryTile(tile.TileId);

                UpdateUpcomingTile(updater, classData.AllUpcoming, todayInLocal, UpcomingTileType.ClassTile, settings);
            }

            catch (Exception ex)
            {
                if (!UWPExceptionHelper.TrackIfNotificationsIssue(ex, "Tiles"))
                {
                    throw ex;
                }
            }
        }
        private static async Task UpdateScheduleTile(string tileId, AccountDataItem account, AccountDataStore data)
        {
            try
            {
                if (!SecondaryTile.Exists(tileId))
                {
                    return;
                }

                Debug.WriteLine("Updating Secondary Schedule Tile");

                TileUpdater updater;

                try
                {
                    updater = TileUpdateManager.CreateTileUpdaterForSecondaryTile(tileId);
                }

                catch
                {
                    return;
                }

                TileHelper.ClearScheduledNotifications(updater);

                bool sentNotification = false;

                var notifications = await GenerateTileNotificationContentsAsync(account);

                foreach (var n in notifications)
                {
                    Schedule(updater, n.Content, n.DeliveryTime ?? DateTime.Now, n.ExpirationTime);
                    sentNotification = true;
                }

                if (!sentNotification)
                {
                    updater.Clear();
                }
            }

            catch (Exception ex)
            {
                if (!UWPExceptionHelper.TrackIfNotificationsIssue(ex, "Tiles") && !UWPExceptionHelper.TrackIfElementNotFound(ex, "Tiles"))
                {
                    throw ex;
                }
            }
        }
Пример #4
0
        /// <summary>
        /// Invoked when application execution is being suspended.  Application state is saved
        /// without knowing whether the application will be terminated or resumed with the contents
        /// of memory still intact.
        /// </summary>
        /// <param name="sender">The source of the suspend request.</param>
        /// <param name="e">Details about the suspend request.</param>
        private void OnSuspending(object sender, SuspendingEventArgs e)
        {
            var deferral = e.SuspendingOperation.GetDeferral();

            //NotificationsExtensions.Toasts.ToastContent c = new NotificationsExtensions.Toasts.ToastContent()
            //{
            //    Visual = new NotificationsExtensions.Toasts.ToastVisual()
            //    {
            //        TitleText = new NotificationsExtensions.Toasts.ToastText()
            //        {
            //            Text = "Suspended"
            //        }
            //    }
            //};

            //Windows.UI.Notifications.ToastNotificationManager.CreateToastNotifier().Show(new Windows.UI.Notifications.ToastNotification(c.GetXml()));

            //TODO: Save application state and stop any background activity

            // TODO: Cancel any current syncs

            // Register the tasks
            try
            {
                // Make sure none are registered (they should have already been unregistered)
                UnregisterAllBackgroundTasks();

                RegisterInfrequentBackgroundTask();
                RegisterRawPushBackgroundTask();
            }

            catch (Exception ex)
            {
                if (UWPExceptionHelper.TrackIfRpcServerUnavailable(ex, "RegisterBgTasks"))
                {
                }
                else if (UWPExceptionHelper.TrackIfPathInvalid(ex, "RegisterBgTasks"))
                {
                }
                else
                {
                    TelemetryExtension.Current?.TrackException(ex);
                }
            }

            deferral.Complete();
        }
        protected override Task ActuallyClearReminders(Guid localAccountId)
        {
            try
            {
                ClearReminders(localAccountId, CancellationToken.None);
            }
            catch (Exception ex)
            {
                if (UWPExceptionHelper.TrackIfNotificationsIssue(ex, nameof(ActuallyClearReminders)))
                {
                }
                else
                {
                    TelemetryExtension.Current?.TrackException(ex);
                    Debug.WriteLine("ClearReminders failed - " + ex.ToString());
                }
            }

            return(Task.FromResult(true));
        }
Пример #6
0
        private static void RegisterRawPushBackgroundTask()
        {
            try
            {
                var builder = CreateBackgroundTaskBuilder("RawPushBackgroundTask");

                // Trigger on raw push received
                builder.SetTrigger(new PushNotificationTrigger());

                // Make sure internet available when triggered
                builder.AddCondition(new SystemCondition(SystemConditionType.InternetAvailable));

                builder.Register();
            }
            catch (Exception ex)
            {
                if (!UWPExceptionHelper.TrackIfNotificationsIssue(ex, nameof(RegisterRawPushBackgroundTask)))
                {
                    TelemetryExtension.Current?.TrackException(ex);
                }
            }
        }
        /// <summary>
        /// Runs on a new thread
        /// </summary>
        /// <param name="account"></param>
        /// <param name="data"></param>
        protected override async Task ActuallyResetReminders(AccountDataItem account, AccountDataStore data)
        {
            try
            {
                await System.Threading.Tasks.Task.Run(async delegate
                {
                    await ResetReminders(account, CancellationToken.None);
                });
            }

            catch (OperationCanceledException) { }

            catch (Exception ex)
            {
                if (UWPExceptionHelper.TrackIfNotificationsIssue(ex, "ResetReminders"))
                {
                }
                else
                {
                    TelemetryExtension.Current?.TrackException(ex);
                    Debug.WriteLine("ResetReminders failed - " + ex.ToString());
                }
            }
        }
Пример #8
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;
                }
            }
        }
Пример #9
0
        protected override async System.Threading.Tasks.Task OnLaunchedOrActivated(IActivatedEventArgs e)
        {
            try
            {
#if DEBUG
                //if (System.Diagnostics.Debugger.IsAttached)
                //{
                //    this.DebugSettings.EnableFrameRateCounter = true;
                //}
#endif

                // Register background tasks
                if (!_registeredBackgroundTasks)
                {
                    try
                    {
                        // Make sure none are registered (they should have already been unregistered)
                        UnregisterAllBackgroundTasks();

                        RegisterInfrequentBackgroundTask();
                        RegisterRawPushBackgroundTask();
                        RegisterToastBackgroundTask();
                    }

                    catch (Exception ex)
                    {
                        if (UWPExceptionHelper.TrackIfRpcServerUnavailable(ex, "RegisterBgTasks"))
                        {
                        }
                        else if (UWPExceptionHelper.TrackIfPathInvalid(ex, "RegisterBgTasks"))
                        {
                        }
                        else
                        {
                            TelemetryExtension.Current?.TrackException(ex);
                        }
                    }

                    _registeredBackgroundTasks = true;
                }

                // Wait for initialization to complete, to ensure we don't accidently add multiple windows
                // Although right now we don't even do any async tasks, so this will be useless
                await PowerPlannerApp.InitializeTask;

                MainAppWindow mainAppWindow;

                // If no windows, need to register window
                mainAppWindow = PowerPlannerApp.Current.Windows.OfType <MainAppWindow>().FirstOrDefault();
                if (mainAppWindow == null)
                {
                    // This configures the view models, does NOT call Activate yet
                    var nativeWindow = new NativeUwpAppWindow();
                    mainAppWindow = new MainAppWindow();
                    await PowerPlannerApp.Current.RegisterWindowAsync(mainAppWindow, nativeWindow);

                    if (PowerPlannerApp.Current.Windows.Count > 1)
                    {
                        throw new Exception("There are more than 1 windows registered");
                    }
                }

                if (e is LaunchActivatedEventArgs)
                {
                    var launchEventArgs = e as LaunchActivatedEventArgs;
                    var launchContext   = !object.Equals(launchEventArgs.TileId, "App") ? LaunchSurface.SecondaryTile : LaunchSurface.Normal;
                    if (launchContext == LaunchSurface.Normal)
                    {
                        // Track whether was launched from primary tile
                        if (ApiInformation.IsPropertyPresent(typeof(LaunchActivatedEventArgs).FullName, nameof(LaunchActivatedEventArgs.TileActivatedInfo)))
                        {
                            if (launchEventArgs.TileActivatedInfo != null)
                            {
                                launchContext = LaunchSurface.PrimaryTile;
                            }
                        }
                    }

                    await HandleArguments(mainAppWindow, launchEventArgs.Arguments, launchContext);
                }

                else if (e is ToastNotificationActivatedEventArgs)
                {
                    var args = e as ToastNotificationActivatedEventArgs;

                    await HandleArguments(mainAppWindow, args.Argument, LaunchSurface.Toast);
                }

                else if (e is ProtocolActivatedEventArgs)
                {
                    var protocolEventArgs = e as ProtocolActivatedEventArgs;

                    if (!string.IsNullOrWhiteSpace(protocolEventArgs.Uri.PathAndQuery) && protocolEventArgs.Uri.PathAndQuery.StartsWith("?"))
                    {
                        await HandleArguments(mainAppWindow, protocolEventArgs.Uri.PathAndQuery.Substring(1), LaunchSurface.Uri);
                    }
                }

                else if (e is AppointmentsProviderShowAppointmentDetailsActivatedEventArgs)
                {
                    // Note that this code is essentially deprecated and doesn't get hit... Uri launch happens instead
                    var showDetailsArgs = e as AppointmentsProviderShowAppointmentDetailsActivatedEventArgs;

                    try
                    {
                        AppointmentsHelper.RoamingIdData data = AppointmentsHelper.RoamingIdData.FromString(showDetailsArgs.RoamingId);

                        string finalArgs = null;

                        switch (data.ItemType)
                        {
                        case ItemType.Schedule:
                            finalArgs = new ViewScheduleArguments()
                            {
                                LocalAccountId = data.LocalAccountId
                            }.SerializeToString();
                            break;

                        case ItemType.MegaItem:
                            finalArgs = new ViewTaskArguments()
                            {
                                LocalAccountId = data.LocalAccountId,
                                ItemId         = data.Identifier
                            }.SerializeToString();
                            break;
                        }

                        if (finalArgs != null)
                        {
                            await HandleArguments(mainAppWindow, finalArgs, LaunchSurface.Calendar);
                        }
                    }

                    catch (Exception ex)
                    {
                        TelemetryExtension.Current?.TrackException(ex);
                    }
                }

                if (mainAppWindow.GetViewModel().Content == null)
                {
                    await mainAppWindow.GetViewModel().HandleNormalLaunchActivation();
                }

                Window.Current.Activate();

                // Listen to window activation changes
                Window.Current.Activated += Current_Activated;

                // Set up the default window properties
                ConfigureWindowProperties();

                // Set up the sharing support
                ConfigureDataTransferManager();

                // Display updates
                HandleVersionChange();
            }

            catch (Exception ex)
            {
                TelemetryExtension.Current?.TrackException(ex);
            }
        }