From 16cc7bc301056263f5b4b63fb315e10a98ec5c54 Mon Sep 17 00:00:00 2001 From: Michael Gordeev Date: Wed, 5 Feb 2020 22:54:53 +0300 Subject: [PATCH] Added English localization, updated changelog Renamed menu layout file to match naming rules --- GUT.Schedule/GUT.Schedule.sln | 6 +- .../GUT.Schedule/Activities/AboutActivity.cs | 37 ++- .../GUT.Schedule/Activities/ExportActivity.cs | 14 +- .../GUT.Schedule/Activities/MainActivity.cs | 39 ++- .../GUT.Schedule/Activities/StartActivity.cs | 18 +- GUT.Schedule/GUT.Schedule/GUT.Schedule.csproj | 9 +- .../Properties/AndroidManifest.xml | 2 +- .../Resources/Resource.designer.cs | 256 ++++++++++++++++-- .../GUT.Schedule/Resources/layout/About.xml | 18 +- .../GUT.Schedule/Resources/layout/Export.xml | 2 +- .../GUT.Schedule/Resources/layout/Main.xml | 38 +-- .../Resources/layout/SplashScreen.xml | 4 +- .../{menu_main.xml => MainContextMenu.xml} | 6 +- .../Resources/values-ru/strings.xml | 102 +++++++ .../GUT.Schedule/Resources/values/strings.xml | 100 +++++++ changelog.md | 12 +- 16 files changed, 540 insertions(+), 123 deletions(-) rename GUT.Schedule/GUT.Schedule/Resources/menu/{menu_main.xml => MainContextMenu.xml} (71%) create mode 100644 GUT.Schedule/GUT.Schedule/Resources/values-ru/strings.xml create mode 100644 GUT.Schedule/GUT.Schedule/Resources/values/strings.xml diff --git a/GUT.Schedule/GUT.Schedule.sln b/GUT.Schedule/GUT.Schedule.sln index 4281a71..89fccf2 100644 --- a/GUT.Schedule/GUT.Schedule.sln +++ b/GUT.Schedule/GUT.Schedule.sln @@ -15,9 +15,9 @@ Global {A0471165-37F5-4309-8A92-42F1A6589EEE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {A0471165-37F5-4309-8A92-42F1A6589EEE}.Debug|Any CPU.Build.0 = Debug|Any CPU {A0471165-37F5-4309-8A92-42F1A6589EEE}.Debug|Any CPU.Deploy.0 = Debug|Any CPU - {A0471165-37F5-4309-8A92-42F1A6589EEE}.Release (APK)|Any CPU.ActiveCfg = Release|Any CPU - {A0471165-37F5-4309-8A92-42F1A6589EEE}.Release (APK)|Any CPU.Build.0 = Release|Any CPU - {A0471165-37F5-4309-8A92-42F1A6589EEE}.Release (APK)|Any CPU.Deploy.0 = Release|Any CPU + {A0471165-37F5-4309-8A92-42F1A6589EEE}.Release (APK)|Any CPU.ActiveCfg = Release (APK)|Any CPU + {A0471165-37F5-4309-8A92-42F1A6589EEE}.Release (APK)|Any CPU.Build.0 = Release (APK)|Any CPU + {A0471165-37F5-4309-8A92-42F1A6589EEE}.Release (APK)|Any CPU.Deploy.0 = Release (APK)|Any CPU {A0471165-37F5-4309-8A92-42F1A6589EEE}.Release|Any CPU.ActiveCfg = Release|Any CPU {A0471165-37F5-4309-8A92-42F1A6589EEE}.Release|Any CPU.Build.0 = Release|Any CPU {A0471165-37F5-4309-8A92-42F1A6589EEE}.Release|Any CPU.Deploy.0 = Release|Any CPU diff --git a/GUT.Schedule/GUT.Schedule/Activities/AboutActivity.cs b/GUT.Schedule/GUT.Schedule/Activities/AboutActivity.cs index b34c74c..f3a8f6f 100644 --- a/GUT.Schedule/GUT.Schedule/Activities/AboutActivity.cs +++ b/GUT.Schedule/GUT.Schedule/Activities/AboutActivity.cs @@ -10,32 +10,31 @@ using Newtonsoft.Json; using System.Collections.Generic; using System.Linq; using System.Net.Http; -using System.Net.Http.Headers; namespace GUT.Schedule.Activities { - [Activity(Label = "О приложениии")] + [Activity(Label = "@string/aboutTitle")] public class AboutActivity : AppCompatActivity { - private readonly (string name, string handle, string link)[] contacts = new (string, string, string)[] - { - ("Веб-сайт", "https://xfox111.net", "https://xfox111.net"), - ("Twitter", "@xfox111", "https://twitter.com/xfox111"), - ("ВКонтакте", "@xfox.mike", "https://vk.com/xfox.mike"), - ("LinkedIn", "@xfox", "https://linkedin.com/in/xfox"), - ("GitHub", "@xfox111", "https://github.com/xfox111"), - }; - private readonly (string name, string link)[] links = new (string, string)[] - { - ("Политика конфиденциальности", "https://xfox111.net/Projects/GUTSchedule/PrivacyPolicy.txt"), - ("General Public License v3", "https://www.gnu.org/licenses/gpl-3.0"), - ("Репозиторий GitHub", "https://github.com/xfox111/gutschedule"), - ("НОЦ \"ТИОС\"", "http://tios.spbgut.ru/index.php"), - ("СПбГУТ", "https://sut.ru"), - }; - protected override async void OnCreate(Bundle savedInstanceState) { + (string name, string handle, string link)[] contacts = new (string, string, string)[] + { + (Resources.GetText(Resource.String.websiteContact), "https://xfox111.net", "https://xfox111.net"), + (Resources.GetText(Resource.String.twitterContact), "@xfox111", "https://twitter.com/xfox111"), + (Resources.GetText(Resource.String.vkontakteContact), "@xfox.mike", "https://vk.com/xfox.mike"), + ("LinkedIn", "@xfox", "https://linkedin.com/in/xfox"), + ("GitHub", "@xfox111", "https://github.com/xfox111"), + }; + (string name, string link)[] links = new (string, string)[] + { + (Resources.GetText(Resource.String.privacyPolicyLink), "https://xfox111.net/Projects/GUTSchedule/PrivacyPolicy.txt"), + ("General Public License v3", "https://www.gnu.org/licenses/gpl-3.0"), + (Resources.GetText(Resource.String.repositoryLink), "https://github.com/xfox111/gutschedule"), + (Resources.GetText(Resource.String.notsLink), "http://tios.spbgut.ru/index.php"), + (Resources.GetText(Resource.String.sutLink), "https://sut.ru"), + }; + base.OnCreate(savedInstanceState); SetContentView(Resource.Layout.About); PackageInfo version = PackageManager.GetPackageInfo(PackageName, PackageInfoFlags.MatchAll); diff --git a/GUT.Schedule/GUT.Schedule/Activities/ExportActivity.cs b/GUT.Schedule/GUT.Schedule/Activities/ExportActivity.cs index af05815..907b047 100644 --- a/GUT.Schedule/GUT.Schedule/Activities/ExportActivity.cs +++ b/GUT.Schedule/GUT.Schedule/Activities/ExportActivity.cs @@ -32,9 +32,9 @@ namespace GUT.Schedule.Activities try { if(Data.DataSet.IsProfessor == true) - status.Text = "Загрузка расписания с картофельных серверов Бонча"; + status.Text = Resources.GetText(Resource.String.potatoLoadingStatus); // For some reason professors' schedule loads much slower else - status.Text = "Загрузка расписания"; + status.Text = Resources.GetText(Resource.String.loadingStatus); if (Data.DataSet.HttpClient != null) { @@ -49,7 +49,7 @@ namespace GUT.Schedule.Activities schedule = schedule.FindAll(i => i.StartTime.Date >= Data.StartDate && i.StartTime.Date <= Data.EndDate); // Filtering schedule according to export range - status.Text = "Экспортирование в календарь"; + status.Text = Resources.GetText(Resource.String.calendarExportStatus); Calendar.Export(schedule); } else @@ -58,20 +58,20 @@ namespace GUT.Schedule.Activities schedule = schedule.FindAll(i => i.StartTime.Date >= Data.StartDate && i.StartTime.Date <= Data.EndDate); // Filtering schedule according to export range - status.Text = "Экспортирование в календарь"; + status.Text = Resources.GetText(Resource.String.calendarExportStatus); Calendar.Export(schedule); } - status.Text = "Готово"; + status.Text = Resources.GetText(Resource.String.doneStatus); await Task.Delay(1000); } catch (HttpRequestException e) { Android.Support.V7.App.AlertDialog.Builder builder = new Android.Support.V7.App.AlertDialog.Builder(this); - builder.SetMessage("Невозможно загрузить расписание. Проверьте интернет-соединение или попробуйте позже") + builder.SetMessage(Resources.GetText(Resource.String.connectionFailMessage)) .SetTitle(e.Message) .SetPositiveButton("ОК", (s, e) => base.OnBackPressed()) - .SetNegativeButton("Повторить", (s, e) => Export()); + .SetNegativeButton(Resources.GetText(Resource.String.repeat), (s, e) => Export()); Android.Support.V7.App.AlertDialog dialog = builder.Create(); dialog.Show(); diff --git a/GUT.Schedule/GUT.Schedule/Activities/MainActivity.cs b/GUT.Schedule/GUT.Schedule/Activities/MainActivity.cs index c7f30ea..16adfbd 100644 --- a/GUT.Schedule/GUT.Schedule/Activities/MainActivity.cs +++ b/GUT.Schedule/GUT.Schedule/Activities/MainActivity.cs @@ -55,10 +55,10 @@ namespace GUT.Schedule.Activities // Settings spinners' dropdown lists content reminder.SetList(this, new[] { - "Нет", - "Во время начала", - "За 5 мин", - "За 10 мин" + Resources.GetText(Resource.String.noReminderOption), + Resources.GetText(Resource.String.inTimeReminderOption), + Resources.GetText(Resource.String.fiveMinuteReminderOption), + Resources.GetText(Resource.String.tenMinuteReminderOption) }); reminder.SetSelection(prefs.GetInt("Reminder", 0)); @@ -82,7 +82,7 @@ namespace GUT.Schedule.Activities if (Data.StartDate > Data.EndDate) { - error.Text = "Ошибка: Неправильный диапазон дат"; + error.Text = Resources.GetText(Resource.String.invalidDateRangeError); error.Visibility = ViewStates.Visible; return; } @@ -91,10 +91,10 @@ namespace GUT.Schedule.Activities bool? isProf = null; if(authorize.Checked) { - Toast.MakeText(ApplicationContext, "Авторизация...", ToastLength.Short).Show(); + Toast.MakeText(ApplicationContext, Resources.GetText(Resource.String.authorizationState), ToastLength.Short).Show(); if (string.IsNullOrWhiteSpace(email.Text) || string.IsNullOrWhiteSpace(password.Text)) { - error.Text = "Ошибка: Введите корректные учетные данные"; + error.Text = Resources.GetText(Resource.String.invalidAuthorizationError); error.Visibility = ViewStates.Visible; return; } @@ -115,14 +115,14 @@ namespace GUT.Schedule.Activities if (!response.IsSuccessStatusCode) { - error.Text = $"Ошибка авторизации: {response.StatusCode}: {responseContent}"; + error.Text = $"{Resources.GetText(Resource.String.authorizationError)}: {response.StatusCode}: {responseContent}"; error.Visibility = ViewStates.Visible; return; } if (!responseContent.StartsWith("1", StringComparison.OrdinalIgnoreCase)) { - error.Text = $"Ошибка авторизации: Неверный e-mail и/или пароль ({string.Join("; ", responseContent.Replace("error=", "", StringComparison.OrdinalIgnoreCase).Split('|'))})"; + error.Text = $"{Resources.GetText(Resource.String.invalidCredentialError)} ({string.Join("; ", responseContent.Replace("error=", "", StringComparison.OrdinalIgnoreCase).Split('|'))})"; error.Visibility = ViewStates.Visible; return; } @@ -152,7 +152,7 @@ namespace GUT.Schedule.Activities { if(Data.Groups.Count < 1) { - error.Text = "Ошибка: Не выбрана группа"; + error.Text = Resources.GetText(Resource.String.groupSelectionError); error.Visibility = ViewStates.Visible; return; } @@ -290,7 +290,7 @@ namespace GUT.Schedule.Activities #region Menu stuff public override bool OnCreateOptionsMenu(IMenu menu) { - MenuInflater.Inflate(Resource.Menu.menu_main, menu); + MenuInflater.Inflate(Resource.Menu.MainContextMenu, menu); return true; } @@ -298,9 +298,9 @@ namespace GUT.Schedule.Activities { try { - Toast.MakeText(ApplicationContext, "Очистка...", ToastLength.Short).Show(); + Toast.MakeText(ApplicationContext, Resources.GetText(Resource.String.clearingStatus), ToastLength.Short).Show(); Calendar.Clear(keepPrevious); - Toast.MakeText(ApplicationContext, "Готово!", ToastLength.Short).Show(); + Toast.MakeText(ApplicationContext, Resources.GetText(Resource.String.doneStatus), ToastLength.Short).Show(); } catch (Exception e) { @@ -329,14 +329,11 @@ namespace GUT.Schedule.Activities case Resource.Id.clear: builder = new Android.Support.V7.App.AlertDialog.Builder(this); - builder.SetMessage("Это действие удалит экспортированное расписание из всех доступных календарей.\n" + - "Данное действие затронет только расписание, экспортированное этим приложением\n" + - "'Все' - удалит все события расписания, включая прошедшие\n" + - "'Только новые' - удалит будущие события расписания") - .SetTitle("Очистка календарей") - .SetPositiveButton("Только новые", (s, e) => Clear()) - .SetNegativeButton("Все", (s, e) => Clear(false)) - .SetNeutralButton("Отмена", (IDialogInterfaceOnClickListener)null); + builder.SetMessage(Resources.GetText(Resource.String.clearScheduleMessage)) + .SetTitle(Resources.GetText(Resource.String.clearScheduleTitle)) + .SetPositiveButton(Resources.GetText(Resource.String.clearUpcomingOption), (s, e) => Clear()) + .SetNegativeButton(Resources.GetText(Resource.String.clearAllOption), (s, e) => Clear(false)) + .SetNeutralButton(Resources.GetText(Resource.String.cancelOption), (IDialogInterfaceOnClickListener)null); dialog = builder.Create(); dialog.Show(); diff --git a/GUT.Schedule/GUT.Schedule/Activities/StartActivity.cs b/GUT.Schedule/GUT.Schedule/Activities/StartActivity.cs index c84707b..c1f4902 100644 --- a/GUT.Schedule/GUT.Schedule/Activities/StartActivity.cs +++ b/GUT.Schedule/GUT.Schedule/Activities/StartActivity.cs @@ -31,12 +31,12 @@ namespace GUT.Schedule.Activities PackageInfo version = PackageManager.GetPackageInfo(PackageName, PackageInfoFlags.MatchAll); FindViewById(Resource.Id.version).Text = $"v{version.VersionName} (ci-id #{version.VersionCode})"; - status.Text = "Проверка наличия разрешений"; + status.Text = Resources.GetText(Resource.String.permissionsCheckStatus); if (ContextCompat.CheckSelfPermission(this, Manifest.Permission.WriteCalendar) != Permission.Granted) { if (ActivityCompat.ShouldShowRequestPermissionRationale(this, Manifest.Permission.WriteCalendar)) - ShowDialog("Доступ к календарю", "Разрешите приложению получать доступ к календарю. Без этого разрешения приложение не сможет добавлять расписание в ваш календарь", RequestPermissions); + ShowDialog(Resources.GetText(Resource.String.calendarAccessTitle), Resources.GetText(Resource.String.calendarAccessRationale), RequestPermissions); else RequestPermissions(); } @@ -48,24 +48,24 @@ namespace GUT.Schedule.Activities { try { - status.Text = "Загрузка списка календарей"; + status.Text = Resources.GetText(Resource.String.calendarLoadingStatus); Calendar.LoadCalendars(); if (Calendar.Calendars.Count == 0) { - ShowDialog("Создайте новый календарь", "На вашем устройстве нет календарей пригодных для записи расписания"); + ShowDialog(Resources.GetText(Resource.String.createCalendarTitle), Resources.GetText(Resource.String.createCalendarMessage)); return; } - status.Text = "Загрузка списка факультетов"; + status.Text = Resources.GetText(Resource.String.facultiesLoadingStatus); await Parser.LoadFaculties(); - status.Text = "Загрузка дат смещения"; + status.Text = Resources.GetText(Resource.String.offsetDatesLoadingStatus); using HttpClient client = new HttpClient(); Data.FirstWeekDay = int.Parse(await client.GetStringAsync("https://xfox111.net/schedule_offset.txt")); } catch(HttpRequestException e) { - ShowDialog(e.Message, "Невозможно загрузить расписание. Проверьте интернет-соединение или попробуйте позже", Proceed, FinishAndRemoveTask, "Повторить", "Выйти"); + ShowDialog(e.Message, Resources.GetText(Resource.String.connectionFailMessage), Proceed, FinishAndRemoveTask, Resources.GetText(Resource.String.repeat), Resources.GetText(Resource.String.quit)); return; } catch (Exception e) @@ -83,7 +83,7 @@ namespace GUT.Schedule.Activities if (grantResults.All(i => i == Permission.Granted)) Proceed(); else - ShowDialog("Доступ к календарю", "Разрешите приложению получать доступ к календарю. Без этого разрешения приложение не сможет добавлять расписание в ваш календарь", RequestPermissions); + ShowDialog(Resources.GetText(Resource.String.calendarAccessTitle), Resources.GetText(Resource.String.calendarAccessRationale), RequestPermissions); } private void RequestPermissions() => @@ -101,7 +101,7 @@ namespace GUT.Schedule.Activities .SetTitle(title).SetPositiveButton(posActionLabel ?? "OK", (s, e) => posAction?.Invoke()); if (negAction != null) - builder.SetNegativeButton(negActionLabel ?? "Close", (s, e) => negAction.Invoke()); + builder.SetNegativeButton(negActionLabel ?? Resources.GetText(Resource.String.close), (s, e) => negAction.Invoke()); Android.Support.V7.App.AlertDialog dialog = builder.Create(); dialog.Show(); diff --git a/GUT.Schedule/GUT.Schedule/GUT.Schedule.csproj b/GUT.Schedule/GUT.Schedule/GUT.Schedule.csproj index d5f9ebc..81b3ea4 100644 --- a/GUT.Schedule/GUT.Schedule/GUT.Schedule.csproj +++ b/GUT.Schedule/GUT.Schedule/GUT.Schedule.csproj @@ -77,6 +77,7 @@ false false armeabi-v7a;x86;x86_64;arm64-v8a + apk @@ -152,7 +153,7 @@ - + @@ -173,6 +174,12 @@ + + + + + + + Инициализация + Проверка наличия разрешений + Загрузка списка календарей + Загрузка списка факультативов + Загрузка дат смещения + + Доступ к календарю + Разрешите приложению получать доступ к календарю. Без этого разрешения приложение не сможет добавлять расписание в ваш календарь + + Создайте новый календарь + На вашем устройстве нет календарей пригодных для записи расписания + + Невозможно загрузить расписание. Проверьте интернет-соединение или попробуйте позже + Повторить + Выйти + Закрыть + + + Параметры расписания + Авторизоваться через Личный кабинет + Факультет + Курс + Группа + + Пароль + + Параметры экспорта + Диапазон экспорта + + На день + На неделю + На месяц + На семестр + + Напоминать за + (i) Внимание, при экспорте в облачный Google-календарь, Google автоматически ставит уведомление за пол часа, если его не поставил пользователь + Нет + Во время начала + За 5 минут + За 10 минут + + Добавить номер группы в заголовок + (i) Не касается преподавательского расписания + + Конечый календарь + + Добавить расписание + + ©2020 Михаил Гордеев, ИКСС, ИКТ-907 + + Очистить расписание + Сообщить об ошибке + + Ошибка: Неправильный диапазон дат + Авторизация... + Ошибка: Введите корректные учетные данные + Ошибка авторизации + Ошибка авторизации: Неверный e-mail и/или пароль + Ошибка: Не выбрана группа + + Очистка расписания + Это действие удалит экспортированное расписание из всех доступных календарей. \nДанное действие затронет только расписание, экспортированное этим приложением \n\'Все\' - удалит все события расписания, включая прошедшие \n\'Только новые\' - удалит будущие события расписания + + Все + Только новые + Отмена + Очистка... + + + Загрузка + Загрузка расписания с картофельных серверов Бонча + Загрузка расписания + Экспортирование в календарь + Готово + + + О приложении + Приложение для экспорта перподавательского и учебного расписаний Санкт-Петербургского Государственного Университета Телекоммуникаций им. проф. М.А. Бонч-Бруевича + Разработано Михаилом Гордеевым, ИКТ-907, ИКСС в Научно-образовательном центре \"Технологии информационных образовательных систем\" + Свой вклад в разработку внесли + + Особые благодарности + Виталий Мошков, Анастасия Годунова + + Контакты + Веб-сайт + Твиттер + ВКонтакте + + Полезные ссылки + Политика конфиденциальности + Репозиторий GitHub + НОЦ \"ТИОС\" + СПбГУТ + + Оставить отзыв + \ No newline at end of file diff --git a/GUT.Schedule/GUT.Schedule/Resources/values/strings.xml b/GUT.Schedule/GUT.Schedule/Resources/values/strings.xml new file mode 100644 index 0000000..9073002 --- /dev/null +++ b/GUT.Schedule/GUT.Schedule/Resources/values/strings.xml @@ -0,0 +1,100 @@ + + + GUT.Schedule + + Initialization + Checking permissions + Loading calendars list + Loading faculties list + Loading offset dates + + Calendar access + Grant permission to the app to access calendar. Without it the app will not be able to add schedule to your calendar + + Create new calendar + There\'s no calendars on your device we can write schedule to + + Unable to load schedule. Check your internet connection or try again later + Try again + Quit + Close + + + Schedule parameters + Authorize via Personal cabinet + Faculty + Course + Group + + Password + + Export parameters + Export range + + For day + For week + For month + For semester + + Set reminders for + (i) Attention, for cloud-based Google calendars Google automatically sets reminders for 30 minutes if there\'s no reminder set by user + None + At the start of event + 5 minutes + 10 minutes + + Add group number to event title + (i) This doesn\'t affect professors\' schedule + + Destination calendar + + Add schedule + + ©2020 Michael Gordeev, INS, IS-907 + + Clear schedule + Report error + + Error: Invalid date range + Authorization... + Error: Invalid credential + Authorization error + Authorization error: Invalid e-mail and/or password + Error: no group was selected + + Clear schedule + This action will purge exported schedule from all available calendars. \nIt will affect only events created by the app. \n\'All\' - will purge all timetable events including the past ones \n\'Upcoming\' - will affect only upcoming timetable events + All + Upcoming + Cancel + Clearing... + + + Loading + Loading schedule from SPbSUT potato servers + Loading schedule + Exporting to calendar + Done + + + About application + Application for SPbSUT professors\' and students\' schedule export + Developed by Michael Gordeev (IS-907, INS) in the \"Technologies of Informational and Educational Systems\" Research Facility + Contributors + + Special thanks + Vitaliy Moshkov, Anastasiya Godunova + + Contacts + Website + Twitter + Vkontakte + + Useful links + Privacy policy + GitHub Repository + \"TIES\" RF + SPbSUT + + Leave feedback + \ No newline at end of file diff --git a/changelog.md b/changelog.md index 4a25fc3..f794be8 100644 --- a/changelog.md +++ b/changelog.md @@ -1,8 +1,4 @@ -Version 1.0.8 -- Student now can authorize with SPbSUT Cabinet credential -- Introduced both work and study schedule export for PhD students -- Duplicating schedule entries (when group splits in two) are now mergeg into one -- Fixed cases when app crashes on the second launch after entered credentials -- Fixed export errors -- Professors' schedule is now marked with 📚 -- You can now add your group number to event title when using cabinet authorization \ No newline at end of file +- Added version number to loading screen and main page +- Updated "About" page +- Changed version numbering system +- Added English localization \ No newline at end of file