コード例 #1
0
        private async Task LoadBlocking()
        {
            var dataStore = await GetDataStore();

            DataItemMegaItem[] dataItems;

            using (await Locks.LockDataForReadAsync("SemesterItemsViewGroup.LoadBlocking"))
            {
                Guid   semesterIdentifier = Semester.Identifier;
                Guid[] classIdentifiers   = Semester.Classes.Select(i => i.Identifier).ToArray();

                dataItems = dataStore.TableMegaItems.Where(ShouldIncludeItemFunction(semesterIdentifier, classIdentifiers)).ToArray();
            }

            await Dispatcher.RunAsync(delegate
            {
                foreach (var i in dataItems)
                {
                    Add(i);
                }

                if (dataItems.Length > 0)
                {
                    OnItemsChanged?.Invoke(this, new EventArgs());
                }
            });
        }
コード例 #2
0
        private async void TryAskingForRatingIfNeeded()
        {
            try
            {
                // If we haven't asked for rating yet
                if (!ApplicationData.Current.RoamingSettings.Values.ContainsKey("HasAskedForRating"))
                {
                    if (ViewModel.CurrentAccount != null)
                    {
                        var dataStore = await AccountDataStore.Get(ViewModel.CurrentLocalAccountId);

                        // If they actually have a decent amount of tasks/events
                        if (await System.Threading.Tasks.Task.Run(async delegate
                        {
                            using (await Locks.LockDataForReadAsync())
                            {
                                return(dataStore.TableMegaItems.Count() > 15);
                            }
                        }))
                        {
                            CustomMessageBox mb = new CustomMessageBox("Thanks for using Power Planner! If you love the app, please leave a rating in the Store! If you have any suggestions or issues, please email me!", "★ Review App ★", "Review", "Email Dev", "Close");
                            mb.Response += mbAskForReview_Response;
                            mb.Show();

                            ApplicationData.Current.RoamingSettings.Values["HasAskedForRating"] = true;
                        }
                    }
                }
            }

            catch { }
        }
コード例 #3
0
        private async Task LoadBlocking()
        {
            var dataStore = await GetDataStore();

            DataItemYear[]           dataYears;
            DataItemSemester[]       dataSemesters;
            DataItemClass[]          dataClasses;
            DataItemWeightCategory[] dataWeightCategories;
            DataItemMegaItem[]       dataMegaItems;
            DataItemGrade[]          dataGrades;

            // Need to lock the whole thing so that if something is added while we're constructing, it'll be added after we've constructed
            using (await Locks.LockDataForReadAsync("YearsViewItemsGroup.LoadBlocking"))
            {
                dataYears            = dataStore.TableYears.ToArray();
                dataSemesters        = dataStore.TableSemesters.ToArray();
                dataClasses          = dataStore.TableClasses.ToArray();
                dataWeightCategories = dataStore.TableWeightCategories.ToArray();
                dataGrades           = dataStore.TableGrades.ToArray();
                dataMegaItems        = dataStore.TableMegaItems.Where(i =>
                                                                      (i.MegaItemType == PowerPlannerSending.MegaItemType.Homework || i.MegaItemType == PowerPlannerSending.MegaItemType.Exam) &&
                                                                      i.WeightCategoryIdentifier != PowerPlannerSending.BaseHomeworkExam.WEIGHT_CATEGORY_EXCLUDED).ToArray();

                var school = new ViewItemSchool(CreateYear);

                school.FilterAndAddChildren(dataYears);

                foreach (var year in school.Years)
                {
                    year.FilterAndAddChildren(dataSemesters);

                    foreach (var semester in year.Semesters)
                    {
                        semester.FilterAndAddChildren(dataClasses);

                        foreach (var classItem in semester.Classes)
                        {
                            classItem.FilterAndAddChildren(dataWeightCategories);

                            foreach (var weight in classItem.WeightCategories)
                            {
                                weight.FilterAndAddChildren <BaseDataItemHomeworkExamGrade>(dataGrades);
                                weight.FilterAndAddChildren <BaseDataItemHomeworkExamGrade>(dataMegaItems);
                            }
                        }
                    }
                }

                // Sort the years here, since when initially inserting they can't be sorted, since they
                // sort based on their start dates, but their start dates are calculated based on their
                // semesters, and their semesters hadn't been added when the years are inserted
                school.Years.Sort();

                this.School = school;
            }

            School.CalculateEverything();
        }
コード例 #4
0
        private static async Task <bool> CheckThatSemesterIsValidBlocking(Guid localAccountId, Guid semesterId)
        {
            var dataStore = await AccountDataStore.Get(localAccountId);

            using (await Locks.LockDataForReadAsync())
            {
                return(dataStore.TableSemesters.Count(i => i.Identifier == semesterId) > 0);
            }
        }
コード例 #5
0
        private async Task LoadBlocking()
        {
            var dataStore = await GetDataStore();

            DataItemClass[]          dataClasses;
            DataItemSchedule[]       dataSchedules;
            DataItemWeightCategory[] dataWeights = null; // Weights are now needed for adding tasks/events
            DataItemSemester         dataSemester;

            using (await Locks.LockDataForReadAsync("ScheduleViewItemsGroup.LoadBlocking"))
            {
                var timeTracker = TimeTracker.Start();
                dataSemester = dataStore.TableSemesters.FirstOrDefault(i => i.Identifier == SemesterId);

                if (dataSemester == null)
                {
                    throw new SemesterNotFoundException();
                }

                dataClasses = dataStore.TableClasses.Where(i => i.UpperIdentifier == SemesterId).ToArray();

                Guid[] classIdentifiers = dataClasses.Select(i => i.Identifier).ToArray();

                dataSchedules = dataStore.TableSchedules.Where(i => classIdentifiers.Contains(i.UpperIdentifier)).ToArray();

                if (_includeWeightCategories)
                {
                    dataWeights = dataStore.TableWeightCategories.Where(i => classIdentifiers.Contains(i.UpperIdentifier)).ToArray();
                }
                timeTracker.End(3, "ScheduleViewItemsGroup.LoadBlocking loading items from database");

                timeTracker = TimeTracker.Start();
                var semester = new ViewItemSemester(dataSemester, CreateClass);

                semester.FilterAndAddChildren(dataClasses);

                foreach (var c in semester.Classes)
                {
                    c.FilterAndAddChildren(dataSchedules);

                    if (_includeWeightCategories)
                    {
                        c.FilterAndAddChildren(dataWeights);
                    }
                }

                this.Semester = semester;
                timeTracker.End(3, "ScheduleViewItemsGroup.LoadBlocking constructing view items");
            }
        }
コード例 #6
0
        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
            });
        }
コード例 #7
0
            public override async Task <bool> ShouldShowAsync(AccountDataItem account)
            {
                // Don't show for offline accounts or for devices that aren't Desktop
                if (account == null || !account.IsOnlineAccount || InterfacesUWP.DeviceInfo.DeviceFamily != InterfacesUWP.DeviceFamily.Desktop)
                {
                    return(false);
                }

                if (ApplicationData.Current.RoamingSettings.Values.ContainsKey(SETTING_HAS_PROMOTED_ANDROID_AND_IOS))
                {
                    return(false);
                }

                var dataStore = await AccountDataStore.Get(account.LocalAccountId);

                // If they actually have some classes
                bool hasContent;

                using (await Locks.LockDataForReadAsync())
                {
                    hasContent = dataStore.TableClasses.Count() > 1;
                }

                if (hasContent)
                {
                    // Try downloading and then show
                    ShouldSuggestOtherPlatformsResponse response = await account.PostAuthenticatedAsync <ShouldSuggestOtherPlatformsRequest, ShouldSuggestOtherPlatformsResponse>(
                        Website.URL + "shouldsuggestotherplatforms",
                        new ShouldSuggestOtherPlatformsRequest()
                    {
                        CurrentPlatform = "Windows 10"
                    });

                    if (response.ShouldSuggest)
                    {
                        return(true);
                    }

                    // No need to suggest in the future nor show now
                    MarkShown(account);
                    return(false);
                }
                else
                {
                    // Not enough content to show right now
                    return(false);
                }
            }
コード例 #8
0
            public override async Task <bool> ShouldShowAsync(AccountDataItem account)
            {
                if (account == null)
                {
                    return(false);
                }

                // If we've already shown
                if (Helpers.Settings.HasShownPromoContribute)
                {
                    return(false);
                }

                var dataStore = await AccountDataStore.Get(account.LocalAccountId);

                // If they actually have lots of tasks
                using (await Locks.LockDataForReadAsync())
                {
                    return(dataStore.ActualTableMegaItems.Count() > 60);
                }
            }
コード例 #9
0
        private async Task LoadBlocking()
        {
            var dataStore = await GetDataStore();

            Guid     semesterId = Semester.Identifier;
            DateTime startAsUtc = DateTime.SpecifyKind(StartDate, DateTimeKind.Utc);
            DateTime endAsUtc   = DateTime.SpecifyKind(EndDate, DateTimeKind.Utc);

            DataItemMegaItem[] dataItemHolidays;

            using (await Locks.LockDataForReadAsync("HolidayViewItemsGroup.LoadBlocking"))
            {
                dataItemHolidays = dataStore.TableMegaItems.Where(i =>
                                                                  i.MegaItemType == PowerPlannerSending.MegaItemType.Holiday &&
                                                                  i.UpperIdentifier == semesterId &&
                                                                  ((i.Date <= startAsUtc && i.EndTime >= startAsUtc) ||
                                                                   (i.Date >= startAsUtc && i.Date <= endAsUtc))).ToArray();
            }

            Holidays = new MyObservableList <ViewItemHoliday>(dataItemHolidays.Select(i => new ViewItemHoliday(i)));
        }
コード例 #10
0
        private async Task LoadBlocking()
        {
            var dataStore = await GetDataStore();

            DataItemMegaItem[] dataItems;

            using (await Locks.LockDataForReadAsync("AgendaViewItemsGroup.LoadBlocking"))
            {
                Guid[] classIdentifiers = _semester.Classes.Select(i => i.Identifier).ToArray();

                DateTime todayAsUtc = DateTime.SpecifyKind(Today, DateTimeKind.Utc);

                dataItems = dataStore.TableMegaItems.Where(ShouldIncludeItemFunction(classIdentifiers, todayAsUtc)).ToArray();

                this.Items = new MyObservableList <ViewItemTaskOrEvent>();

                foreach (var i in dataItems)
                {
                    Add(i);
                }
            }
        }
コード例 #11
0
        private async void TryAskingForRatingIfNeeded()
        {
            try
            {
                // If we haven't asked for rating yet
                if (!PowerPlannerAppDataLibrary.Helpers.Settings.HasAskedForRating)
                {
                    if (ViewModel.CurrentAccount != null)
                    {
                        var dataStore = await AccountDataStore.Get(ViewModel.CurrentLocalAccountId);

                        // If they actually have a decent amount of homework
                        if (await System.Threading.Tasks.Task.Run(async delegate
                        {
                            using (await Locks.LockDataForReadAsync())
                            {
                                return(dataStore.TableMegaItems.Count() > 30 && dataStore.TableMegaItems.Any(i => i.DateCreated < DateTime.Today.AddDays(-60)));
                            }
                        }))
                        {
                            var builder = new Android.App.AlertDialog.Builder(Context);

                            builder
                            .SetTitle("★ Review App ★")
                            .SetMessage("Thanks for using Power Planner! If you love the app, please leave a rating in the Store! If you have any suggestions or issues, please email me!")
                            .SetNeutralButton("Review", delegate { OpenReview(); })     // Neutral is displayed more prominently
                            .SetPositiveButton("Email Dev", delegate { AboutView.EmailDeveloper(Context, base.ViewModel); })
                            .SetNegativeButton("Close", delegate { });

                            builder.Create().Show();

                            PowerPlannerAppDataLibrary.Helpers.Settings.HasAskedForRating = true;
                        }
                    }
                }
            }

            catch { }
        }
コード例 #12
0
        private async void LoadPastCompletedHomeworkAndExams()
        {
            if (_hasLoadedPastCompletedHomeworkAndExams)
            {
                return;
            }

            _hasLoadedPastCompletedHomeworkAndExams = true;

            try
            {
                var dataStore = await GetDataStore();

                DataItemMegaItem[] additionalHomeworkAndExams;

                using (await Locks.LockDataForReadAsync())
                {
                    // Get the data items that we haven't loaded yet
                    additionalHomeworkAndExams = dataStore.TableMegaItems.Where(IsPastCompletedHomeworkOrExamFunction(_classId, TodayAsUtc)).ToArray();

                    // Exclude any that are already loaded (due to the events being complicated to calculate whether they're incomplete, we end up double loading items that are on today)
                    additionalHomeworkAndExams = additionalHomeworkAndExams.Where(a => !this.Class.HomeworkAndExams.Any(i => i.Identifier == a.Identifier)).ToArray();

                    // And then update the child function so that we include all homework for the class, and inject the new items
                    this.Class.UpdateIsChildMethod <DataItemMegaItem, BaseViewItemHomeworkExam>(i => i.UpperIdentifier == _classId && i.MegaItemType == PowerPlannerSending.MegaItemType.Homework || i.MegaItemType == PowerPlannerSending.MegaItemType.Exam, additionalHomeworkAndExams);
                }

                // Include the opposite of the other function
                PastCompletedHomework = new PastCompletedHomeworkList(this.Class.HomeworkAndExams.OfTypeObservable <ViewItemHomework>(), TodayAsUtc);
                PastCompletedExams    = new PastCompletedExamsList(this.Class.HomeworkAndExams.OfTypeObservable <ViewItemExam>(), TodayAsUtc);
            }

            catch (Exception ex)
            {
                TelemetryExtension.Current?.TrackException(ex);
            }
        }
コード例 #13
0
        public async Task HandleViewHolidayActivation(Guid localAccountId, Guid holidayId)
        {
            DataItemMegaItem holiday = await Task.Run(async delegate
            {
                using (await Locks.LockDataForReadAsync("HandleViewHolidayActivation"))
                {
                    var dataStore = await AccountDataStore.Get(localAccountId);
                    if (dataStore == null)
                    {
                        return(null);
                    }

                    return(dataStore.TableMegaItems.FirstOrDefault(i =>
                                                                   i.MegaItemType == PowerPlannerSending.MegaItemType.Holiday &&
                                                                   i.Identifier == holidayId));
                }
            });

            if (holiday != null)
            {
                var holidayDate         = DateTime.SpecifyKind(holiday.Date, DateTimeKind.Local);
                var desiredDisplayMonth = holidayDate;
                var mainScreen          = GetMainScreenViewModel();
                if (mainScreen != null && mainScreen.CurrentAccount != null && mainScreen.CurrentAccount.LocalAccountId == localAccountId && mainScreen.Content is CalendarViewModel)
                {
                    (mainScreen.Content as CalendarViewModel).DisplayMonth = desiredDisplayMonth;
                    (mainScreen.Content as CalendarViewModel).SelectedDate = holidayDate;
                }
                else
                {
                    NavigationManager.SetDisplayMonth(desiredDisplayMonth);
                    NavigationManager.SetSelectedDate(holidayDate);
                    await HandleSelectMenuItemActivation(localAccountId, NavigationManager.MainMenuSelections.Calendar);
                }
            }
        }
コード例 #14
0
        private async void TryAskingForRatingIfNeeded()
        {
            try
            {
                // If we haven't asked for rating yet
                if (!PowerPlannerAppDataLibrary.Helpers.Settings.HasAskedForRating)
                {
                    if (ViewModel.CurrentAccount != null)
                    {
                        var dataStore = await AccountDataStore.Get(ViewModel.CurrentLocalAccountId);

                        // If they actually have a decent amount of tasks
                        if (await System.Threading.Tasks.Task.Run(async delegate
                        {
                            using (await Locks.LockDataForReadAsync())
                            {
                                return(dataStore.TableMegaItems.Count() > 30 && dataStore.TableMegaItems.Any(i => i.DateCreated < DateTime.Today.AddDays(-60)));
                            }
                        }))
                        {
                            var alert = UIAlertController.Create(
                                title: "★ Review App ★",
                                message: "Thanks for using Power Planner! If you love the app, please leave a rating in the Store! If you have any suggestions or issues, please email me!",
                                preferredStyle: UIAlertControllerStyle.Alert);

                            alert.AddAction(UIAlertAction.Create("Review", UIAlertActionStyle.Default, delegate
                            {
                                PowerPlannerAppDataLibrary.Helpers.Settings.HasAskedForRating       = true;
                                PowerPlannerAppDataLibrary.Helpers.Settings.HasReviewedOrEmailedDev = true;
                                TelemetryExtension.Current?.TrackEvent("PromptReviewApp_ClickedReview");

                                OpenStoreReview();
                            }));

                            alert.AddAction(UIAlertAction.Create("Email dev", UIAlertActionStyle.Default, delegate
                            {
                                PowerPlannerAppDataLibrary.Helpers.Settings.HasAskedForRating       = true;
                                PowerPlannerAppDataLibrary.Helpers.Settings.HasReviewedOrEmailedDev = true;
                                TelemetryExtension.Current?.TrackEvent("PromptReviewApp_ClickedEmailDev");

                                Settings.AboutViewController.EmailDeveloper();
                            }));

                            alert.AddAction(UIAlertAction.Create("No thanks", UIAlertActionStyle.Cancel, delegate
                            {
                                PowerPlannerAppDataLibrary.Helpers.Settings.HasAskedForRating = true;
                                TelemetryExtension.Current?.TrackEvent("PromptReviewApp_ClickedNoThanks");
                            }));

                            PresentViewController(alert, true, null);
                        }
                    }
                }

                // If the user previously clicked No thanks, we'll try the new in-app review dialog
                else if (!PowerPlannerAppDataLibrary.Helpers.Settings.HasReviewedOrEmailedDev)
                {
                    if (UIDevice.CurrentDevice.CheckSystemVersion(10, 3))
                    {
                        // This will only sometimes show a dialog, at most 3 times a year
                        // It will still display if they already rated, meaning users who previously clicked
                        // No thanks on my own dialog will persistently get this dialog, but that should be ok
                        StoreKit.SKStoreReviewController.RequestReview();
                    }
                }
            }

            catch { }
        }
コード例 #15
0
        public async void LoadHomeworkAndExams()
        {
            try
            {
                if (_hasHomeworkAndExamsBeenRequested)
                {
                    return;
                }

                _hasHomeworkAndExamsBeenRequested = true;

                bool hasPastCompletedHomework = false;
                bool hasPastCompletedExams    = false;

                SemesterItemsViewGroup cached = null;
                if (this.Class.Semester != null)
                {
                    cached = SemesterItemsViewGroup.GetCached(this.Class.Semester.Identifier);
                }

                if (cached != null)
                {
                    await cached.LoadingTask;
                    DataItemMegaItem[] dataMegaItems = cached.Items
                                                       .OfType <BaseViewItemHomeworkExam>()
                                                       .Select(i => i.DataItem)
                                                       .OfType <DataItemMegaItem>()
                                                       .ToArray();

                    this.Class.AddHomeworkAndExamChildrenHelper(CreateHomeworkOrExam, ShouldIncludeHomeworkOrExamFunction(_classId, TodayAsUtc));
                    this.Class.FilterAndAddChildren(dataMegaItems);

                    hasPastCompletedHomework = dataMegaItems.Any(IsPastCompletedHomeworkFunction(_classId, TodayAsUtc));
                    hasPastCompletedExams    = dataMegaItems.Any(IsPastCompletedExamFunction(_classId, TodayAsUtc));
                }
                else
                {
                    await Task.Run(async delegate
                    {
                        var dataStore = await GetDataStore();

                        DataItemMegaItem[] dataHomeworks;

                        using (await Locks.LockDataForReadAsync())
                        {
                            dataHomeworks = dataStore.TableMegaItems.Where(ShouldIncludeHomeworkOrExamFunction(_classId, TodayAsUtc)).ToArray();

                            this.Class.AddHomeworkAndExamChildrenHelper(CreateHomeworkOrExam, ShouldIncludeHomeworkOrExamFunction(_classId, TodayAsUtc));
                            this.Class.FilterAndAddChildren(dataHomeworks);

                            hasPastCompletedHomework = dataStore.TableMegaItems.Any(IsPastCompletedHomeworkFunction(_classId, TodayAsUtc));
                            hasPastCompletedExams    = dataStore.TableMegaItems.Any(IsPastCompletedExamFunction(_classId, TodayAsUtc));
                        }
                    });
                }

                HasPastCompletedHomework = hasPastCompletedHomework;
                HasPastCompletedExams    = hasPastCompletedExams;
                Homework = this.Class.HomeworkAndExams.Sublist(ShouldIncludeInNormalHomeworkFunction(TodayAsUtc)).Cast <ViewItemHomework>();
                Exams    = new MyObservableList <ViewItemExam>();
                (Exams as MyObservableList <ViewItemExam>).InsertSorted(
                    this.Class.HomeworkAndExams.Sublist(ShouldIncludeInNormalExamsFunction()).Cast <ViewItemExam>());
                OnPropertyChanged(nameof(Homework));
                OnPropertyChanged(nameof(Exams));

                _loadHomeworkAndExamsCompletionSource.SetResult(true);
            }
            catch (Exception ex)
            {
                TelemetryExtension.Current?.TrackException(ex);
            }
        }
コード例 #16
0
        public async void LoadGrades()
        {
            try
            {
                if (_hasGradesBeenRequested)
                {
                    return;
                }

                _hasGradesBeenRequested = true;

                await Task.Run(async delegate
                {
                    try
                    {
                        var dataStore = await GetDataStore();

                        DataItemGrade[] dataGrades;
                        DataItemMegaItem[] dataItems;

                        using (await Locks.LockDataForReadAsync())
                        {
                            Guid[] weightIds = this.Class.WeightCategories.Select(i => i.Identifier).ToArray();

                            dataGrades = dataStore.TableGrades.Where(i => weightIds.Contains(i.UpperIdentifier)).ToArray();

                            dataItems = dataStore.TableMegaItems.Where(i =>
                                                                       (i.MegaItemType == PowerPlannerSending.MegaItemType.Exam || i.MegaItemType == PowerPlannerSending.MegaItemType.Homework) &&
                                                                       i.UpperIdentifier == _classId &&
                                                                       i.WeightCategoryIdentifier != PowerPlannerSending.BaseHomeworkExam.WEIGHT_CATEGORY_EXCLUDED)
                                        .ToArray();

                            var unassignedItems = new MyObservableList <BaseViewItemHomeworkExam>();
                            unassignedItems.InsertSorted(dataItems
                                                         .Where(i => IsUnassignedChild(i))
                                                         .Select(i =>
                                                                 i.MegaItemType == PowerPlannerSending.MegaItemType.Homework ?
                                                                 new ViewItemHomework(i)
                            {
                                Class = this.Class, WeightCategory = ViewItemWeightCategory.UNASSIGNED
                            } as BaseViewItemHomeworkExam
                                        : new ViewItemExam(i)
                            {
                                Class = this.Class, WeightCategory = ViewItemWeightCategory.UNASSIGNED
                            }));

                            PortableDispatcher.GetCurrentDispatcher().Run(delegate
                            {
                                try
                                {
                                    foreach (var weight in this.Class.WeightCategories)
                                    {
                                        weight.AddGradesHelper(ViewItemWeightCategory.CreateGradeHelper);

                                        weight.FilterAndAddChildren <BaseDataItemHomeworkExamGrade>(dataGrades);
                                        weight.FilterAndAddChildren <BaseDataItemHomeworkExamGrade>(dataItems);
                                    }

                                    Class.CalculateEverything();

                                    UnassignedItems    = unassignedItems;
                                    HasUnassignedItems = unassignedItems.Count > 0;

                                    _loadGradesTaskSource.SetResult(true);
                                    IsGradesLoaded = true;
                                }
                                catch (Exception ex)
                                {
                                    TelemetryExtension.Current?.TrackException(ex);
                                }
                            });
                        }
                    }
                    catch (Exception ex)
                    {
                        TelemetryExtension.Current?.TrackException(ex);
                    }
                });
            }
            catch (Exception ex)
            {
                TelemetryExtension.Current?.TrackException(ex);
            }
        }
コード例 #17
0
        private async Task LoadBlocking(ViewItemSemester viewItemSemester, bool includeWeights)
        {
            var dataStore = await GetDataStore();

            DataItemClass dataClass;

            DataItemClass[]          dataClasses;
            DataItemSchedule[]       dataSchedules;
            DataItemWeightCategory[] dataWeights;

            using (await Locks.LockDataForReadAsync("ClassViewItemsGroup.LoadBlocking"))
            {
                dataClasses = viewItemSemester.Classes.Select(i => i.DataItem).OfType <DataItemClass>().ToArray();

                var viewClassRef = viewItemSemester.Classes.FirstOrDefault(i => i.Identifier == _classId);
                dataClass = viewClassRef?.DataItem as DataItemClass;

                if (dataClass == null)
                {
                    throw new ClassNotFoundExcetion();
                }

                dataSchedules = viewClassRef.Schedules.Select(i => i.DataItem).OfType <DataItemSchedule>().ToArray();

                if (includeWeights)
                {
                    // Get weights for ALL classes, since we need them for editing purposes when editing item to different class
                    dataWeights = viewItemSemester.Classes.SelectMany(i => i.WeightCategories).Select(i => i.DataItem).OfType <DataItemWeightCategory>().ToArray();
                }
                else
                {
                    dataWeights = null;
                }

                Func <DataItemWeightCategory, ViewItemWeightCategory> createWeight = null;
                if (includeWeights)
                {
                    createWeight = CreateWeight;
                }

                var classItem = new ViewItemClass(
                    dataClass,
                    createScheduleMethod: CreateSchedule,
                    createWeightMethod: createWeight);

                classItem.FilterAndAddChildren(dataSchedules);

                if (includeWeights)
                {
                    classItem.FilterAndAddChildren(dataWeights);
                }

                this.Class = classItem;

                _semester = new ViewItemSemester(dataClass.UpperIdentifier, createClassMethod: CreateClass);

                dataClasses = dataStore.TableClasses.Where(i => i.UpperIdentifier == _semester.Identifier).ToArray();

                _semester.FilterAndAddChildren(dataClasses);

                // Add the weights for the other classes
                if (includeWeights)
                {
                    foreach (var c in _semester.Classes.Where(i => i.Identifier != this.Class.Identifier))
                    {
                        c.FilterAndAddChildren(dataWeights);
                    }
                }
            }

            // If there were no weights in the class, we need to create and add a weight
            if (this.Class.WeightCategories != null && this.Class.WeightCategories.Count == 0)
            {
                TelemetryExtension.Current?.TrackEvent("Error_ClassMissingWeightCategoryAddingDefault");

                DataChanges changes = new DataLayer.DataChanges();
                changes.Add(AccountDataStore.CreateDefaultWeightCategory(this.Class.Identifier));

                await PowerPlannerApp.Current.SaveChanges(changes);
            }
        }
コード例 #18
0
        private async Task ApplyFilterBlocking(DateTime prevStart, DateTime prevEnd, DateRange filterRequest)
        {
            DateTime newStart = filterRequest.Start;
            DateTime newEnd   = filterRequest.End;

            DateTime notLoadedStart;
            DateTime notLoadedEnd;

            // We're only supporting where the date range shifts in one direction.
            // We're not supporting where the date range expands in both directions.

            if (newEnd > prevEnd)
            {
                notLoadedEnd = newEnd;

                if (newStart < prevEnd)
                {
                    notLoadedStart = prevEnd.AddTicks(1);
                }
                else
                {
                    notLoadedStart = newStart;
                }
            }

            else if (newStart < prevStart)
            {
                notLoadedStart = newStart;

                if (newEnd > prevStart)
                {
                    notLoadedEnd = prevStart.AddTicks(-1);
                }
                else
                {
                    notLoadedEnd = newEnd;
                }
            }

            else
            {
                return;
            }


            var dataStore = await GetDataStore();

            using (await Locks.LockDataForReadAsync())
            {
                // If the pending filter request has changed, do nothing
                if (_pendingFilterRequest != filterRequest)
                {
                    return;
                }

                Guid[] classIdentifiers = Semester.Classes.Select(i => i.Identifier).ToArray();

                DataItemMegaItem[] dataItems = dataStore.TableMegaItems.Where(ShouldIncludeItemFunction(classIdentifiers, notLoadedStart, notLoadedEnd)).ToArray();

                // We need to dispatch to UI thread to actually change the collection
                try
                {
                    Dispatcher.Run(delegate
                    {
                        // If the pending filter request has changed, do nothing
                        if (_pendingFilterRequest != filterRequest)
                        {
                            return;
                        }


                        // Remove all that are no longer in the date range (don't worry about class changing since data didn't change here)
                        Items.RemoveWhere(i => !ShouldIncludeItem(i, newStart, newEnd));

                        // Then add the new items
                        foreach (var h in dataItems)
                        {
                            Add(h);
                        }

                        Start = newStart;
                        End   = newEnd;
                    });
                }
                catch (Exception ex)
                {
                    TelemetryExtension.Current?.TrackException(ex);
                }
            }
        }
コード例 #19
0
        protected async Task LoadBlocking(Guid examId)
        {
            var dataStore = await GetDataStore();

            if (dataStore == null)
            {
                throw new NullReferenceException("Account doesn't exist");
            }

            DataItemMegaItem dataItem;

            // We need ALL classes loaded, including their schedules, and their weight categories.
            // Might as well just use ScheduleViewItemsGroup therefore.

            Guid semesterId;
            Guid classId = Guid.Empty;

            using (await Locks.LockDataForReadAsync("BaseSingleItemViewItemsGroup.LoadBlocking"))
            {
                dataItem = dataStore.TableMegaItems.FirstOrDefault(i => i.Identifier == examId);
                if (dataItem == null)
                {
                    TelemetryExtension.Current?.TrackEvent("Error_LoadSingleItem_CouldNotFind", new Dictionary <string, string>()
                    {
                        { "ItemId", examId.ToString() }
                    });

                    // Leave the Item set to null
                    return;
                }

                if (dataItem.MegaItemType == PowerPlannerSending.MegaItemType.Task || dataItem.MegaItemType == PowerPlannerSending.MegaItemType.Event)
                {
                    semesterId = dataItem.UpperIdentifier;
                    classId    = dataItem.UpperIdentifier;
                }
                else
                {
                    var dataClass = dataStore.TableClasses.FirstOrDefault(i => i.Identifier == dataItem.UpperIdentifier);
                    if (dataClass == null)
                    {
                        throw new NullReferenceException("Class not found. Item id " + examId);
                    }
                    semesterId = dataClass.UpperIdentifier;
                    classId    = dataClass.Identifier;
                }
            }

            _scheduleViewItemsGroup = await ScheduleViewItemsGroup.LoadAsync(LocalAccountId, semesterId : semesterId, trackChanges : trackChanges, includeWeightCategories : true);

            // Grab the class for the item
            ViewItemClass viewClass;

            if (dataItem.MegaItemType == PowerPlannerSending.MegaItemType.Task || dataItem.MegaItemType == PowerPlannerSending.MegaItemType.Event)
            {
                viewClass = _scheduleViewItemsGroup.Semester.NoClassClass;
            }
            else
            {
                viewClass = _scheduleViewItemsGroup.Semester.Classes.FirstOrDefault(i => i.Identifier == classId);
                if (viewClass == null)
                {
                    throw new NullReferenceException("ViewItemClass not found. Item id " + examId);
                }
            }

            // And create the item
            Item = CreateItem(dataItem, viewClass);
        }