/// <summary> /// Downloads a plan /// </summary> /// <param name="textToShowAtInfoCenter">Text to show, before downloading</param> private void DownloadTimeTables(string textToShowAtInfoCenter) { SplitViewContentScrollViewer.Visibility = Visibility.Collapsed; InfoCenterStackPanel.Visibility = Visibility.Visible; InfoCenterButton.Visibility = Visibility.Visible; if (HtmlServices.UserHasInternetConnection()) { InfoCenterText.Text = textToShowAtInfoCenter; _isLoaded = false; } else InfoCenterText.Text = "Aby odświeżyć plan zajęc, musisz mieć połączenie z internetem! Naciśnij przycisk poniżej aby spróbować ponownie"; if (_isButtonClickEventSubscribed) return; _isButtonClickEventSubscribed = true; InfoCenterButton.Click += async (s, es) => { //if user downloaded plan succesfully, but there was problem //with save and then clicked a button if (InfoCenterText.Text.Contains("NIE POWIODŁO SIĘ")) { HtmlServices.InvokeAllTimeTableDownloaded(); return; } //check again if user has an internet connection //if not, call this function again to change text if (!HtmlServices.UserHasInternetConnection()) { DownloadTimeTables(textToShowAtInfoCenter); return; } //if user wants to download a plan if (InfoCenterText.Text == textToShowAtInfoCenter || !InfoCenterText.Text.Contains("zakończone")) { InfoCenterButton.Visibility = Visibility.Collapsed; InfoCenterProgressRing.Visibility = Visibility.Collapsed; InfoCenterText.Text = "Trwa synchronizowanie planu..."; TimeTable.TimetableOfTeachers = new ObservableCollection<Timetable>(); TimeTable.TimetablesOfClasses = new ObservableCollection<Timetable>(); //we want to avoid the situations where OnTimeTableDownloaded event //will be subscribed two times if (!_isTimeTableDownloadedEventSubscribed) { _isTimeTableDownloadedEventSubscribed = true; //called on each timetable downloaded to show progress HtmlServices.OnTimeTableDownloaded += (timeTable, lenght) => { var numOfTimeTable = TimeTable.TimetablesOfClasses.Count + TimeTable.TimetableOfTeachers.Count(); if (timeTable.type == 0) TimeTable.TimetablesOfClasses.Add(timeTable); else TimeTable.TimetableOfTeachers.Add(timeTable); var percentOfDownloadedTimeTables = (int)(0.5f + (++numOfTimeTable * 100.0) / lenght); InfoCenterText.Text = "[" + percentOfDownloadedTimeTables.ToString() + "%] Trwa dodawanie: " + timeTable.name; }; } if (!_isAllTimeTablesDownloadedSubscribed) { _isAllTimeTablesDownloadedSubscribed = true; HtmlServices.OnAllTimeTablesDownloaded += async () => { InfoCenterText.Text = "Trwa zapisywanie planu zajęć..."; TimeTable.IdOfLastOpenedTimeTable = -1; bool isPlanSerializedSuccesfullly = await DataServices.Serialize(TimeTable); InfoCenterText.Text = !isPlanSerializedSuccesfullly ? "Zapisywanie planu zajęć NIE POWIODŁO SIĘ. Spróbować ponownie?" : "Synchronizowanie i zapisywanie planu zajęć zakończone."; InfoCenterButton.Visibility = Visibility.Visible; InfoCenterProgressRing.Visibility = Visibility.Collapsed; }; } //if user wants to download a plan but //for he timetable is shown if (_isLoaded) { InfoCenterStackPanel.Visibility = Visibility.Collapsed; InfoCenterButton.Visibility = Visibility.Collapsed; await ShowTimeTableAsync(Timetable.GetLatestOpenedTimeTable(TimeTable) ?? TimeTable.TimetablesOfClasses[0], false, true); } TimeTable = new SchoolTimetable(); await HtmlServices.GetData(); } else { //if plan was downloaded&saved succesfully and user clicked OK button _isLoaded = true; InfoCenterStackPanel.Visibility = Visibility.Collapsed; MenuListViewOfSections.ItemsSource = TimeTableOfSections; MenuListViewOfTeachers.ItemsSource = TimeTableOfTeachers; MenuSplitView.IsPaneOpen = true; } }; }
/// <summary> /// Shows a timetable for user /// </summary> /// <param name="t">Timetable to show</param> /// <param name="quietChangedOfTimeTable">Changed timetable without showing it</param> /// <returns>Task for await</returns> private async Task ShowTimeTableAsync(Timetable t, bool quietChangedOfTimeTable = false, bool addPage = true) { if (InfoCenterStackPanel.Visibility == Visibility.Visible) InfoCenterStackPanel.Visibility = Visibility.Collapsed; // if we want to show timetable, without checking if eg settings page is opened if (!quietChangedOfTimeTable && SplitViewContentScrollViewer.Visibility == Visibility.Collapsed) { SplitViewContentScrollViewer.Visibility = Visibility.Visible; SplitViewContentFrame.Visibility = Visibility.Collapsed; } var splitViewContentGrid = MenuSplitViewContentGrid; //absolute id of timetable var idOfTimeTable = Timetable.GetIdOfTimetable(t, TimeTable); //t.type == Lesson.LessonType.Class ? TimeTable.TimetablesOfClasses.IndexOf(t) : //TimeTable.TimetablesOfClasses.Count + TimeTable.TimetableOfTeachers.IndexOf(t); //if table which we want to show is actually opened var headerGrid = splitViewContentGrid.Parent as Grid; if (addPage) PagesManager.AddPage(t, PagesManager.ePagesType.Timetable); if ((!quietChangedOfTimeTable && idOfTimeTable == TimeTable.IdOfLastOpenedTimeTable && splitViewContentGrid.Children.Any()) || headerGrid == null) { if (!TitleText.Text.Contains("Plan lekcji")) TitleText.Text = "Plan lekcji - " + t.name; return; } var timeNow = DateTime.Now.TimeOfDay; var actualHour = timeNow.Hours; var actualMinute = timeNow.Minutes; //checks checking actual hour and minute which lesson actually is var actualLesson = actualHour == 7 ? 1 : (actualHour == 8 && actualMinute < 55) ? 2 : ((actualHour == 8 && actualMinute >= 55) || actualHour == 9 && actualMinute < 45) ? 3 : ((actualHour == 9 && actualMinute >= 45) || actualHour == 10 && actualMinute < 45) ? 4 : ((actualHour == 10 && actualMinute >= 45) || actualHour == 11 && actualMinute < 35) ? 5 : ((actualHour == 11 && actualMinute >= 35) || actualHour == 12 && actualMinute < 30) ? 6 : ((actualHour == 12 && actualMinute >= 30) || actualHour == 13 && actualMinute < 20) ? 7 : ((actualHour == 13 && actualMinute >= 20) || actualHour == 14 && actualMinute < 10) ? 8 : ((actualHour == 14 && actualMinute >= 10)) ? 9 : ((actualHour == 15 && actualMinute >= 0) || actualHour == 15 && actualMinute < 50) ? 10 : ((actualHour == 15 && actualMinute >= 50) || actualHour >= 16) ? 11 : 0; if (!quietChangedOfTimeTable) TitleText.Text = "Plan lekcji - " + t.name; var actualTheme = Application.Current.RequestedTheme; //checks if we dont have title TextBlock created if (headerGrid.Children.FirstOrDefault(p => p is TextBlock && p != InfoCenterText) == null) { headerGrid.Children.Add(new TextBlock() { Text = t.name, HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Top, Margin = new Thickness(10.0), Padding = new Thickness(10.0), FontSize = 36 }); } else ((TextBlock)headerGrid.Children.First(p => p is TextBlock && p != InfoCenterText)).Text = t.name; //if we didnt created before a struct of grids //if we, then we have to delete it, lefts first row with //dayNames (poniedzialek,etc) if (!splitViewContentGrid.Children.Any()) { for (var i = 0; i < 7; i++) { splitViewContentGrid.ColumnDefinitions.Add(new ColumnDefinition() { Width = GridLength.Auto }); var tx = new TextBlock() { Text = _dayNames[i], HorizontalAlignment = HorizontalAlignment.Center, Padding = new Thickness(5.0) }; var grid = new Grid(); grid.Children.Add(tx); Grid.SetColumn(grid, i); grid.BorderBrush = new SolidColorBrush(actualTheme == ApplicationTheme.Light ? Colors.Black : Colors.White); grid.BorderThickness = new Thickness(1.0); grid.Background = new SolidColorBrush(actualTheme == ApplicationTheme.Light ? Colors.LightCyan : Color.FromArgb(127, 0, 150, 0)); splitViewContentGrid.Children.Add(grid); } } else { splitViewContentGrid.RowDefinitions.Clear(); var listOfObjects = splitViewContentGrid.Children.Select(p => (((Grid)p).Children[0] as TextBlock)).ToList(); foreach (TextBlock tb in listOfObjects) { if (!string.IsNullOrEmpty(_dayNames.FirstOrDefault(p => p.Contains(tb.Text)))) continue; splitViewContentGrid.Children.Remove((tb.Parent as Grid)); } } var numOfLessonsOnThisTimetable = t.days.Max(day => day.LessonsNum); //scans by rows for (var i = 0; i < numOfLessonsOnThisTimetable + 1; i++) { splitViewContentGrid.RowDefinitions.Add(new RowDefinition() { Height = GridLength.Auto }); // i=0 is a dayName eg Nr,Godz,Poniedzialek etc..., //we dont want to show there lessons if (i == 0) continue; //scans on every column for (var j = 0; j < 7; j++) { var tx = new TextBlock(); var grid = new Grid { IsTapEnabled = true }; //infoTextBlock provides a info about position lesson in a table //for flyout lesson instance looking var text = string.Empty; //j=0 is a number of lesson //j=1 is a hours of this lessons //j>1 is a lesson if (j == 0 || j == 1) { tx.HorizontalAlignment = HorizontalAlignment.Center; tx.VerticalAlignment = VerticalAlignment.Center; } switch (j) { case 0: text = i.ToString(); // number of lesson grid.Background = new SolidColorBrush(actualTheme == ApplicationTheme.Light ? Colors.LightCyan : Color.FromArgb(127, 0, 150, 0)); break; case 1: text = _lessonTimes[i - 1]; // hour of lessons grid.Background = new SolidColorBrush(actualTheme == ApplicationTheme.Light ? Colors.LightGreen : Color.FromArgb(127, 204, 0, 0)); break; default: var infoTextBlock = new TextBlock { Visibility = Visibility.Collapsed, Text = $"[] {j} {i} {Timetable.GetIdOfTimetable(t, TimeTable)}" }; grid.Children.Add(infoTextBlock); //j is column, i is a row //j - 2 because we have 2 added columns (Nr, Godz) //i - 1 because i=0 is a row with dayNames (Nr,Godz,Poniedzialek)etc.. var lesson = t.days[j - 2].Lessons[i - 1]; if (t.type == Lesson.LessonType.Teacher && !string.IsNullOrEmpty(lesson.lesson2Name)) { tx.Inlines.Add(new Run() { Text = $"{lesson.lesson2Name} ", FontWeight = FontWeights.Light }); } tx.Inlines.Add(new Run() { Text = lesson.lesson1Name ?? "", FontWeight = FontWeights.Bold }); //if lesson1Tag (is a Teachertag) is not available, then //skip it, else show full format if (string.IsNullOrEmpty(lesson.lesson1Tag)) { tx.Inlines.Add(new Run() { Text = $" {lesson.lesson1Place}", Foreground = new SolidColorBrush(Colors.Red) }); } else { tx.Inlines.Add(new Run { Text = $" {lesson.lesson1Tag}", Foreground = new SolidColorBrush(actualTheme == ApplicationTheme.Light ? Colors.Purple : Colors.LightCyan) }); tx.Inlines.Add(new Run { Text = $" {lesson.lesson1Place}", Foreground = new SolidColorBrush(Colors.Red) }); } //if this is a class timetable and //at one time, we have two lessons then show //seccond one at bottom in grid if (!string.IsNullOrEmpty(lesson.lesson2Name) && t.type == Lesson.LessonType.Class) { tx.Inlines.Add(new Run { Text = $"{Environment.NewLine}{lesson.lesson2Name}", FontWeight = FontWeights.Bold }); tx.Inlines.Add(new Run { Text = $" {lesson.lesson2Tag}" ?? " ", Foreground = new SolidColorBrush(actualTheme == ApplicationTheme.Light ? Colors.Purple : Colors.LightCyan) }); tx.Inlines.Add(new Run { Text = $" {lesson.lesson2Place}" ?? " ", Foreground = new SolidColorBrush(Colors.Red) }); } break; } tx.Padding = new Thickness(10.0); //if actually operated record //was a lesson (then text was not added, and is empty) if (text != "") tx.Text = text; if (tx.Text.Trim() != "" && j > 1) { grid.Tapped += (s, e) => { var lesson = Lesson.GetLessonFromLessonGrid(s as Grid, TimeTable); FlyoutHelper.SetTimetable(TimeTable); //if lesson has two lesson, show flyout with choose which lesson if (!string.IsNullOrEmpty(lesson.lesson2Tag)) FlyoutHelper.ShowFlyOutMenuForTwoLessons(grid, lesson); else //clicked lesson has only one lesson FlyoutHelper.ShowFlyOutMenuForLesson(grid); }; } grid.Children.Add(tx); Grid.SetColumn(grid, j); Grid.SetRow(grid, i); grid.BorderBrush = new SolidColorBrush(actualTheme == ApplicationTheme.Light ? Colors.Black : Colors.White); grid.BorderThickness = new Thickness(1.0); if (SettingsPage.IsShowActiveLessonsToogleSwitchOn() && i == actualLesson) { grid.BorderThickness = new Thickness(2); grid.BorderBrush = new SolidColorBrush(actualTheme == ApplicationTheme.Light ? Colors.Red : Colors.Yellow); } splitViewContentGrid.Children.Add(grid); } } /* Saving lastOpenedTimeTable */ if (await DataServices.SaveLastOpenedTimeTableToFile(idOfTimeTable, TimeTable) == false) { //If Plan is not saved ResetView(); InfoCenterStackPanel.Visibility = Visibility.Visible; InfoCenterText.Visibility = Visibility.Visible; InfoCenterButton.Visibility = Visibility.Collapsed; InfoCenterText.Text = "Wystąpił błąd podczas zapisu danych. Prawdopodobnie masz za mało pamięci na telefonie," + " bądź inny błąd uniemożliwia zapis. Spróbuj uruchomić aplikację ponownie!"; _isLoaded = false; } }
/// <summary> /// Loads plan /// </summary> private async void MainPage_Loaded(object sender, RoutedEventArgs e) { // load schooltimetable if (DataServices.IsFileExists()) { InfoCenterStackPanel.Visibility = Visibility.Visible; InfoCenterProgressRing.Visibility = Visibility.Visible; InfoCenterButton.Visibility = Visibility.Collapsed; InfoCenterText.Text = "Trwa wczytywanie planu zajęć..."; try { TimeTable = await DataServices.Deserialize(); } catch { TimeTable = null; } if (TimeTable == null || !TimeTable.TimetableOfTeachers.Any() || !TimeTable.TimetablesOfClasses.Any()) { //removes settings InfoCenterProgressRing.Visibility = Visibility.Collapsed; TimeTable = new SchoolTimetable(); DownloadTimeTables("Wystąpił problem podczas wczytywania planu lekcji, muisz pobrać go od nowa. Chcesz to zrobić teraz?"); return; } MenuListViewOfSections.ItemsSource = TimeTableOfSections; MenuListViewOfTeachers.ItemsSource = TimeTableOfTeachers; InfoCenterProgressRing.Visibility = Visibility.Collapsed; //show last opened timetable, first check settings config var numOfClassesTimeTables = TimeTable.IdOfLastOpenedTimeTable; if (LocalSettingsServices.ShowTimetableAtStartup.ContainsKey()) { if ((int.Parse(LocalSettingsServices.ShowTimetableAtStartup.GetKeyValue()) == 0)) numOfClassesTimeTables = -1; else numOfClassesTimeTables = 1; } //if user dont want to show last timetable or no one are sets var lastTimetable = Timetable.GetLatestOpenedTimeTable(TimeTable); if (numOfClassesTimeTables == -1 || lastTimetable == null) { InfoCenterText.Text = "Naciśnij przycisk menu u góry i wybierz interesujący Cię plan zajęć."; InfoCenterButton.Visibility = Visibility.Collapsed; _isLoaded = true; return; } InfoCenterStackPanel.Visibility = Visibility.Collapsed; if (lastTimetable.type == Lesson.LessonType.Class) { MenuListViewOfSections.SelectionChanged += (s, f) => MenuListViewOfSections.ScrollIntoView((s as ListView).SelectedItem, ScrollIntoViewAlignment.Leading); MenuListViewOfSections.SelectedItem = lastTimetable; } else { MenuListViewOfTeachers.SelectionChanged += (s, f) => MenuListViewOfTeachers.ScrollIntoView((s as ListView).SelectedItem, ScrollIntoViewAlignment.Leading); MenuListViewOfTeachers.SelectedItem = lastTimetable; } await ShowTimeTableAsync(lastTimetable, false, true); _isLoaded = true; return; } // if file doesnt exits DownloadTimeTables("By przeglądać plan zajęć, musiz go zsynchronizować, chcesz to zrobić teraz?"); }