public static async Task <XmlDocument> GetCurrentTileNotificationContentAsync(AccountDataItem forAccount, Guid classId) { try { ClassTileSettings settings = await forAccount.GetClassTileSettings(classId); if (settings.IsDisabled()) { return(null); } DateTime todayInLocal = DateTime.Today; ClassData data = await LoadDataAsync(await AccountDataStore.Get(forAccount.LocalAccountId), classId, DateTime.SpecifyKind(todayInLocal, DateTimeKind.Utc), settings); // That means the class was deleted, but we'll just return null here if (data == null) { return(null); } List <ItemsOnDay> groupedByDay = GroupByDay(data.AllUpcoming); return(GenerateUpcomingTileNotificationContent(groupedByDay, DateTime.SpecifyKind(todayInLocal, DateTimeKind.Utc), true, UpcomingTileType.ClassTile)); } catch (Exception ex) { TelemetryExtension.Current?.TrackException(ex); return(null); } }
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; } } }
public async System.Threading.Tasks.Task SaveClassTileSettings(Guid classId, ClassTileSettings settings) { // Get the actual destination folder IFolder destination = await FileHelper.GetOrCreateClassTilesSettingsFolder(LocalAccountId); // Create a temp file to write to IFile temp = await destination.CreateFileAsync("Temp" + classId + ".dat", CreationCollisionOption.ReplaceExisting); // Write the data to the temp file using (Stream s = await temp.OpenAsync(FileAccess.ReadAndWrite)) { GetClassTileSettingsSerializer().WriteObject(s, settings); } // Move the temp file to the actual file await temp.MoveAsync(destination.Path + "/" + classId.ToString() + ".dat", NameCollisionOption.ReplaceExisting); }
/// <summary> /// Always guaranteed to return an initialized object (if class doesn't have settings, returns default with the SkipItems inherited from primary) /// </summary> /// <param name="classId"></param> /// <returns></returns> public async Task <ClassTileSettings> GetClassTileSettings(Guid classId) { try { IFile file = await FileSystem.Current.LocalStorage.GetFileByPathAsync(FileNames.ACCOUNT_CLASS_TILES_SETTINGS_PATH(LocalAccountId), classId.ToString() + ".dat"); if (file != null) { using (Stream s = await file.OpenAsync(FileAccess.Read)) { ClassTileSettings answer = (ClassTileSettings)GetClassTileSettingsSerializer().ReadObject(s); return(answer); } } } catch { } // Otherwise, return default object, which inherits the SkipItems option from primary tile return(new ClassTileSettings() { SkipItemsOlderThan = MainTileSettings.SkipItemsOlderThan }); }
private static async Task <ClassData> LoadDataBlocking(AccountDataStore data, Guid classId, DateTime todayAsUtc, ClassTileSettings settings) { DateTime dateToStartDisplayingFrom = DateTime.SpecifyKind(settings.GetDateToStartDisplayingOn(todayAsUtc), DateTimeKind.Local); Guid semesterId = Guid.Empty; // We lock the outside, since we are allowing trackChanges on the view items groups (so we have a chance of loading a cached one)... and since we're on a background thread, the lists inside the // view items groups could change while we're enumerating, hence throwing an exception. So we lock it to ensure this won't happen, and then we return a copy of the items that we need. using (await Locks.LockDataForReadAsync()) { // First we need to obtain the semester id var c = data.TableClasses.FirstOrDefault(i => i.Identifier == classId); if (c == null) { return(null); } semesterId = c.UpperIdentifier; } // We need all classes loaded, to know what time the end of day is var scheduleViewItemsGroup = await ScheduleViewItemsGroup.LoadAsync(data.LocalAccountId, semesterId, trackChanges : true, includeWeightCategories : false); var classViewItemsGroup = await ClassViewItemsGroup.LoadAsync( localAccountId : data.LocalAccountId, classId : classId, today : DateTime.SpecifyKind(todayAsUtc, DateTimeKind.Local), viewItemSemester : scheduleViewItemsGroup.Semester, includeWeights : false); classViewItemsGroup.LoadTasksAndEvents(); await classViewItemsGroup.LoadTasksAndEventsTask; List <ViewItemTaskOrEvent> copied; using (await classViewItemsGroup.DataChangeLock.LockForReadAsync()) { // Class view group sorts the items, so no need to sort copied = classViewItemsGroup.Class.TasksAndEvents.Where(i => i.Date.Date >= dateToStartDisplayingFrom).ToList(); } return(new ClassData() { Class = classViewItemsGroup.Class, AllUpcoming = copied }); }
private static Task <ClassData> LoadDataAsync(AccountDataStore data, Guid classId, DateTime todayAsUtc, ClassTileSettings settings) { try { return(Task.Run(delegate { return LoadDataBlocking(data, classId, todayAsUtc, settings); })); } catch (SemesterNotFoundException) { return(Task.FromResult <ClassData>(null)); } }
protected override async Task LoadAsyncOverride() { await base.LoadAsyncOverride(); Settings = await Account.GetClassTileSettings(Class.Identifier); }