Skip to content

Releases: thecattest/lyceum-reports-android

Синхронизация, Диаграммы, Многоязыковость, Редизайн, Иконка

20 Jun 16:28
Compare
Choose a tag to compare

Сервис

Создал сервис, который

  • автоматически получает новые данные с сервера
  • автоматически отправляет неотправленные из-за ошибки или отсутствия соединения изменения

Можно выключить в настройках

Диаграммы

Сделал активность статистики с bottom navigation и navigation architecture component.
Табличку за день переписал на фрагмент и переместил туда, а также добавил фрагмент с диаграммой за класс.

Кстати, если дата во фрагменте таблички не выбрана, там будет вот такая картиночка

Поменял иконку на главной

Многоязыковость

Добавил поддержку следующих языков:

  • английский
  • украинский
  • белорусский
  • казахский
    Переключается автоматически взависимости от системных настроек. Дефолтный - русский

Редизайн

Перенастроил цвета и шрифты, вынес все размеры в dimensions, переписал на Constraint layout все разметки

У приложения наконец-то появилась иконка!!!

И она офигенная

Room - Новая Архитектура

21 May 19:37
Compare
Choose a tag to compare

Room

image

Почти полностью переписал архитектуру приложения, теперь всё работает по схемке на картинке.

Новые data классы, новое api, переписано взаимодействие с данными и перекидывание их в разные места системы.

Всё по красоте, а количество багов я старательно пытался сместить поближе к нулю. Дополнительно есть кучка разных элементов для improving user expirience, snackbar'ы всякие, диалоги например.

Аккаунты для тестов

  • админ thecattest / superpass
  • редактор editor / editor
  • наблюдатель viewer / viewer

Новый внешний вид страницы авторизации

16 May 10:12
Compare
Choose a tag to compare

Обновил внешний вид страницы авторизации

Всё из прошлого релиза, естественно, осталось на месте. Я не буду дублировать описания оттуда, так что для начала советую ознакомиться с возможностями предыдущей версии приложения, а потом возвращаться сюда.

Помимо обновления layout, я организовал передачу куков авторизации в запросах не через методы data services, а через interceptor, причем для инициализации retrofit сделал отдельный класс.

Новая авторизация

Старая авторизация

Таблица за день

14 May 13:47
Compare
Choose a tag to compare

В этом релизе я добавил таблицу отстутствующих за день по всем классам, а также вагон и маленькую тележку оптимизаций кода

Всё из прошлого релиза, естественно, осталось на месте. Я не буду дублировать описания оттуда, так что для начала советую ознакомиться с возможностями предыдущей версии приложения, а потом возвращаться сюда.


Итак, теперь в верхней панели на главной странице появилась новая кнопка - таблица отстутствующих за день. Она отображается только если у пользователя есть разрешение просматривать таблицу, разрешение приходит вместе с данными с сервера.

Карточки

Обновил внешний вид карточек на главной странице: скругления, border. Для этого пришлось создать в drawable фигуры и ставить их как background карточке и заголовку карточки отдельно, тк ему также нужен и фон.

DefaultCallback

Создал ранее и уже несколько раз переработал этот абстрактный класс. По сути, это базовый класс для создания callback для call.enque, который я использую вместо retrofit2.Callback.

  • В нем реализуются методы его родителя - onResponse и onFailure, причём в onResponse используется switch по кодам ответа. 200, 401, 403, 500 и default.
  • В 403 вызывается loginmanager.handleNotAuthorized и пользователя сразу кидает на авторизацию.
  • В default показывается snackbar с соответствующим сообщением.
  • В остальных для обработки вызываются методы типа onResponse200, onResponse401 и тд.
  • Также в нём есть метод onPostExecute, который вызовется в конце выполнения запроса при любом исходе, тоже иногда нужен, например, чтобы разблокировать кнопки, заблокированные на время выполнения запроса.
  • Кроме того, обработчики обернуты в try/catch.

Класс спасает от дублирования кода и в некоторой степени упрощает и делает более прозрачным процесс обработки запроса.

StatusManager

В приложении я создал layout'ы загрузки и ошибки на сервере для улучшения UX. Так как везде они одинаковые, я задумался о том, чтобы создать класс-хелпер, благодаря которому мне будет проще менять статусы, а также не придется дублировать код. Так появился StatusManager.

  • Я инициализирую его в onCreate активности, передавая на вход параметры
  • Activity, через который потом будут искаться loading и server error layout'ы,
  • View главного layout'а приложения, так как его нужно будет скрывать, меняя статусы,
  • и, если я хочу использовать serverErrorLayout, передаю onClickListener для кнопки "попробовать снова".
  • В коренной layout активности я добавляю две строчки
<include layout="@layout/fragment_loading"/>
<include layout="@layout/fragment_server_error"/>

И всё, теперь я могу использовать методы setMainLayout, setLoadingLayout, setServerErrorLayout в любом месте и радоваться жизни.

Более того, класс реализует методы saveToBundle и loadFromBundle, которые я могу вызывать в соответствующих обработчиках ивентов активности, и тогда статус будет ещё и сохраняться и загружаться.

DatePickerManager

Когда я создавал активность таблицы отсутствующих за день, я понял, что для создания и использования datePicker пишу практически один и тот же код, причём довольно громоздкий. Я решил создать класс-хелпер и здесь тоже.

  • Я инициализирую его в onCreate активности, передавая на вход параметры
  • Context, который нужен для доступа к String Resources, так как там находится дефолтный текст кнопки-триггера и формат даты для сервера
  • View кнопки-триггера, которая будет запускать date picker
  • fragment manager
  • callback, который будет вызван при нажатии ок во время выбора даты

Теперь я могу использовать getDate для получения выбранной даты уже в формате для отправки на сервер

При помощи isEmpty проверять, выбрана ли какая-то дата, тк это нужно, например, для включения/выключения SwipeRefreshLayout

Сохранять и грузить date picker в/из bundle, используя методы, реализованные в классе

Bundles

Благодаря реализации в классах менеджеров и data models методов для работы с bundle, код обработчиков соответствующих ивентов в активностях стал очень чистым

    @Override
    protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);

        if(statusManager.loadFromBundle(savedInstanceState)) {
            summaryWithPermissions.loadFromBundle(savedInstanceState);
            updateSummaryView();
        }
    }

    @Override
    protected void onSaveInstanceState(@NonNull Bundle outState) {
        summaryWithPermissions.saveToBundle(outState);
        statusManager.saveToBundle(outState);
    }

Отмена отправки запросов на сервер

При отправке запроса я кладу call в глобальную переменную класса, так что при нажатии кнопки назад, например, могу отменить запрос. Такая ситуация отдельно обрабатывается в DefaultCallback и всё ок

String Resources

Почистил strings.xml: всерьёз взялся за нейминг строк и вынес туда вообще все строковые ресурсы, использующиеся в программе, так что теперь его даже читать приятно и всё по правилам.
Фрагмент

<string name="app_name">Lyceum Reports</string>

    <!-- Page titles -->
    <string name="title_main">Отсутствующие</string>
    <string name="title_summary_day">Отсутствующие: день</string>
    <string name="title_authorization">Авторизация</string>
    <string name="title_day">День</string>

    <!-- Snackbars titles -->
    <string name="snackbar_no_info">За этот день данных нет</string>
    <string name="snackbar_no_absent">Все в классе</string>
    <string name="snackbar_request_cancelled">Отмена</string>
    <string name="snackbar_server_error">Ошибка, попробуйте ещё раз позднее</string>
    <string name="snackbar_server_error_code">Ошибка при выполнении запроса :( код </string>
    <string name="snackbar_server_error_code_500">Сервер выдал ошибку 500, попробуйте позднее</string>
    <string name="snackbar_server_ok">Сработало :)</string>

    <!-- Buttons -->
    <string name="button_edit">редактировать</string>
    <string name="button_submit_day_default">отправить</string>
    <string name="button_date_picker_trigger">выбрать дату</string>
    <string name="button_logout">Выйти</string>

    <!-- Summary -->
    <string name="summary_card_yesterday">Вчера</string>
    <string name="summary_card_today">Сегодня</string>
    <string name="summary_status_no_info">Нет данных</string>

Рефакторинг кода в DataModels, Activities, Managers

Структурировал всё ещё больше, повысил читаемость, а в DataModels добавил методы saveToBundle и loadFromBundle

Главная с кнопкой и без. Карточки новые

Активность с табличкой, пустая при открытии и уже прогруженная. Иконка загрузки и окно ошибки тут тоже показывается.

Пользователи, авторизация, права, а также тема!

08 May 08:29
Compare
Choose a tag to compare

В этом релизе я добавил авторизацию и права пользователей.

Всё из прошлого релиза, естественно, осталось на месте. Я не буду дублировать описания оттуда, так что для начала советую ознакомиться с возможностями предыдущей версии приложения, а потом возвращаться сюда.


Итак, я перешёл на новую версию API, которая требует авторизации и регулирует права пользователей. Теперь без входа в аккаунт делать будет нельзя ничего. Я реализовал активность формы авторизации и LoginManager, предоставляющий функции для работы с авторизацией.

LoginManager

По сути, нужно просто получить куки после отправки логина и пароля и дальше добавлять их во все запросы, а в случае ошибки 403 - запускать LoginActivity. LoginManager используется для сохранения и загрузки куков в/из SharedPreferences, а также может перенаправить пользователя на авторизацию или выйти из аккаунта, то бишь стереть куки.

Роли

Описаны вот тут.
В приложении пользователям соответственно ролям скрываются или показываются отдельные элементы интерфейса: кнопки редактирования или карточки классов. Таблички будут реализованы в будущих версиях приложения, так что о них речи пока не идёт.

Тема

Подобрал цвета для светлой и темной темы приложения, так что теперь всё выглядит приятнее и больше соответствует веб-версии сервиса

Можно потрогать!

вот тестовые аккаунты

  • Админ thecattest/superpass
  • Редактор editor/editor
  • Руководитель viewer/viewer

Итак, а теперь десяток скринов для наглядного представления

(14 actually)

Авторизация

Главная и кнопочка logout вверху

Страница отсутствующих и пара информационных сообщений

Окна ошибок в случае, если сервер недоступен. Кстати, фрагменты

Темная тема тоже выглядит хорошо

Руководитель

может только смотреть, кнопок редактирования нет

Редактор

видит только один класс и может его редактировать

Главная страница и редактирование отсутствующих

05 May 13:42
Compare
Choose a tag to compare

Реализованы две активности: главная страница с карточками классов и страница класса, на которой можно просматривать и редактировать информацию об отсутствующих в классе за тот или иной день.
Короткая демка приложения:
https://user-images.githubusercontent.com/57992909/117150358-bfe95c80-adc0-11eb-858f-fa9b6eca4b3f.mp4
Длинная демка, в которой показан почти весь функционал:
https://photos.app.goo.gl/VSWNoqotKFqkXnbu5

Данные сохраняются в бандлы, так что, например, при перевороте экрана ничего не потеряются.

Появляются всплывающие уведомления с поясняющими сообщениями
Ошибка при загрузке выглядит так